diff -ru Tremstats-NightlyBuild-Rev-58/ChangeLog Tremstats-Slux/ChangeLog
--- Tremstats-NightlyBuild-Rev-58/ChangeLog	2006-12-16 20:11:43.000000000 +0100
+++ Tremstats-Slux/ChangeLog	2007-09-12 16:17:18.000000000 +0200
@@ -1,3 +1,10 @@
+2007-09-27 Slux <slux83@gmail.com>
+	* Added unnamed name as parametar (for Lakitu7's patch)
+	* Added Qkey support (fixed the multi-nicks probem for the same TJW client)
+	* Added possibility to show all nicks used by a TJW client in the player page
+	* Extended the Database structure
+	* Adapted the search engine to multi-nicks
+  
 2006-12-16 DASPRiD <mail@dasprids.de>
 	* Overworked the HTML code
 	* Added spectators to server monitor
diff -ru Tremstats-NightlyBuild-Rev-58/parser/config.py Tremstats-Slux/parser/config.py
--- Tremstats-NightlyBuild-Rev-58/parser/config.py	2006-12-16 20:12:49.000000000 +0100
+++ Tremstats-Slux/parser/config.py	2007-09-12 14:42:40.000000000 +0200
@@ -25,3 +25,11 @@
 
 # Directory which contains the PK3 files. Must be absolute.
 CONFIG['PK3_DIR']        = '/root/.tremulous/base/'
+
+# Name/Partname of unnamed nick (case sensitive)
+# Lakitu7's patch have these cvars: 
+#       set g_newbieNumbering 1
+#       set g_newbieNamePrefix "UnnamedPlayer #" 
+#       eg: UnnamedPlayer #0 ~ UnnamedPlayer #1 ~ etc...
+# Don't change the default value if you don't have the Lakitu7's patch set
+CONFIG['UNNAMED_PLAYER']  = 'UnnamedPlayer'
diff -ru Tremstats-NightlyBuild-Rev-58/parser/internals/log_parse.py Tremstats-Slux/parser/internals/log_parse.py
--- Tremstats-NightlyBuild-Rev-58/parser/internals/log_parse.py	2006-12-17 19:49:51.000000000 +0100
+++ Tremstats-Slux/parser/internals/log_parse.py	2007-09-12 16:39:41.000000000 +0200
@@ -8,6 +8,9 @@
 # External libraries
 from externals.progressbar import ProgressBar, Percentage, Bar, ETA
 
+# Config
+from config import CONFIG
+
 """ Class: Parser """
 class Parser:
 	""" Init Parser """
@@ -17,10 +20,10 @@
 		self.RE_UNCOLOR_NAME  = re.compile("\\^[^\\^]")
 		self.RE_CORRECT_NAME  = re.compile("\\^[^\\^]$")
 		self.RE_MESSAGE_CHECK = re.compile("^[ ]*(\\^[^\\^])?!")
-
-		self.RE_CONNECT      = re.compile("^([0-9]+) \\[[0-9\.]+\\] \\(.*?\\) \"(.*?)\"$")
+		
+		self.RE_CONNECT      = re.compile("^([0-9]+) \\[[0-9\.]+\\] \\((.+)\\) \"(.*?)\"$")
 		self.RE_DISCONNECT   = re.compile("^([0-9]+)")
-		self.RE_RENAME       = re.compile("^([0-9]+) \\[[0-9\.]+\\] \\(.*?\\) \".*?\" -> \"(.*?)\"$")
+		self.RE_RENAME       = re.compile("^([0-9]+) \\[[0-9\.]+\\] \\((.+)\\) \".*?\" -> \"(.*?)\"$")
 		self.RE_TEAMCLASS    = re.compile("^([0-9]+) (alien|human) (.+)$")
 		self.RE_EXIT         = re.compile("^(Aliens|Humans) win\.$")
 
@@ -173,13 +176,14 @@
 		if sys.platform == 'win32':
 			if os.path.isfile(local_tmp_log):
 				logtmp = open(local_tmp_log, "r")
+		
 		while True:
 			# Get current line
 			if sys.platform == 'win32':
 				if os.path.isfile(local_tmp_log):
 					linetmp = logtmp.readline()
 			line = log.readline()
-
+			
 			# If linetmp is EOF, keep going
 			if (sys.platform == 'win32' and not linetmp) or (sys.platform != 'win32'):
 				# If line is EOF, break
@@ -191,7 +195,7 @@
 					sizedone += len(line)
 
 				line = line[:-1]
-
+				
 				# Parse the line
 				self.Log_parse_line(line)
 
@@ -371,23 +375,36 @@
 
 		result = match.groups()
 		player_id             = result[0]
-		player_name           = self.Correct_player_name(result[1])
-		player_name_uncolored = self.Remove_colors(result[1])
+		player_qkey           = result[1]
+		player_name           = self.Correct_player_name(result[2])
+		player_name_uncolored = self.Remove_colors(result[2])
 
-		# Check against MySQL
-		if player_name_uncolored == 'UnnamedPlayer':
-			self.players[player_id] = {'name': player_name, 'name_uncolored': player_name_uncolored, 'id': 0}
+
+		# Check against MySQL (non TJW and `unnamed player`)
+		if player_qkey == 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' and player_name_uncolored.find(CONFIG['UNNAMED_PLAYER']) != -1:
+			self.players[player_id] = {'name': player_name, 'name_uncolored': player_name_uncolored, 'id': 0, 'qkey': player_qkey}
 		else:
-			self.dbc.execute("SELECT `player_id` FROM `players` WHERE `player_name_uncolored` = %s", (player_name_uncolored, ))
-			result = self.dbc.fetchone()
-			if result == None:
-				# We have to insert this as new player
-				self.dbc.execute("INSERT INTO `players` (`player_name`, `player_name_uncolored`, `player_first_game_id`) VALUES (%s, %s, %s)", (player_name, player_name_uncolored, self.game_id))
-				self.dbc.execute("SELECT LAST_INSERT_ID()")
+			# Check against MySQL (TJW)
+			if player_qkey != 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX':
+				self.dbc.execute("SELECT `player_id` FROM `players` WHERE `player_qkey` = %s", (player_qkey))
 				result = self.dbc.fetchone()
-
+				if result == None:
+					# We have to insert this as new player (tjw client)
+					self.dbc.execute("INSERT INTO `players` (`player_name`, `player_qkey`, `player_name_uncolored`, `player_first_game_id`) VALUES (%s, %s, %s, %s)", (player_name, player_qkey, player_name_uncolored, self.game_id))
+					self.dbc.execute("SELECT LAST_INSERT_ID()")
+					result = self.dbc.fetchone()
+			else:
+				# vanilla client
+				self.dbc.execute("SELECT `player_id` FROM `players` WHERE `player_name_uncolored` = %s", (player_name_uncolored, ))
+				result = self.dbc.fetchone()
+				if result == None:
+					# We have to insert this as new player (vanilla client)
+					self.dbc.execute("INSERT INTO `players` (`player_name`, `player_name_uncolored`, `player_first_game_id`) VALUES (%s, %s, %s)", (player_name, player_name_uncolored, self.game_id))
+					self.dbc.execute("SELECT LAST_INSERT_ID()")
+					result = self.dbc.fetchone()
+			
 			# Add the player to internal list
-			self.players[player_id] = {'name': player_name, 'name_uncolored': player_name_uncolored, 'id': result[0]}
+			self.players[player_id] = {'name': player_name, 'name_uncolored': player_name_uncolored, 'id': result[0], 'qkey': player_qkey}
 
 		# If the player wasn't in the current game, we set his gamecount up by one
 		if not self.game_players.has_key(result[0]):
@@ -424,13 +441,22 @@
 
 		result = match.groups()
 		player_id   = result[0]
-		player_name = self.Correct_player_name(result[1])
-		player_name_uncolored = self.Remove_colors(result[1])
-
-		# Rename the player in the internal list
-		self.players[player_id]['name']           = player_name
-		self.players[player_id]['name_uncolored'] = player_name_uncolored
-
+		player_qkey = result[1]
+		player_name = self.Correct_player_name(result[2])
+		player_name_uncolored = self.Remove_colors(result[2])
+
+		# Add the new nick for this TJW player
+		if player_qkey != 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' and len(player_qkey) == 32:
+			self.dbc.execute("SELECT `player_qkey` FROM `nicks` WHERE `nick_name` = %s", (player_name))
+			result = self.dbc.fetchone()
+			if result == None:
+				# Add new nick
+				self.dbc.execute("INSERT INTO `nicks` (`player_qkey`, `nick_name_uncolored`, `nick_name`) VALUES (%s, %s, %s)", (player_qkey, player_name_uncolored, player_name))
+		else:
+			# Rename the player in the internal list
+			self.players[player_id]['name']           = player_name
+			self.players[player_id]['name_uncolored'] = player_name_uncolored
+		
 	""" A client changes team or class """
 	def Log_ClientTeamClass(self, gametime, line):
 		# Parse the line
@@ -443,8 +469,8 @@
 		result = match.groups()
 		player_id    = result[0]
 		player_team  = result[1]
-		player_class = result[2]
-
+		player_class = result[2]	
+		
 		# Set internal player data
 		self.players[player_id]['team']  = player_team
 		self.players[player_id]['class'] = player_class
@@ -489,7 +515,8 @@
 		# If player isn't in internal list, return
 		if player == None:
 			return
-
+		
+		# TODO: fix this space waste
 		# Insert everything into database
 		self.dbc.execute("""INSERT INTO `says` (`say_game_id`, `say_gametime`, `say_mode`, `say_player_id`, `say_message`)
 		                    VALUES (%s, %s, %s, %s, %s)""", (self.game_id, gametime, mode, player['id'], message))
Only in Tremstats-NightlyBuild-Rev-58/parser/internals: pk3_read.py
diff -ru Tremstats-NightlyBuild-Rev-58/parser/tremstats.py Tremstats-Slux/parser/tremstats.py
--- Tremstats-NightlyBuild-Rev-58/parser/tremstats.py	2006-12-16 20:12:49.000000000 +0100
+++ Tremstats-Slux/parser/tremstats.py	2007-09-11 15:42:37.000000000 +0200
@@ -22,7 +22,7 @@
 " @link http://tremstats.dasprids.de/
 " @author Ben 'DASPRiD' Scholzen <mail@dasprids.de>
 " @package Tremstats
-" @version 0.6.0
+" @version 0.6.0 ~ slux`s Mod <slux83@gmail.com>
 """
 
 # Main imports
@@ -81,6 +81,7 @@
 			self.dbc.execute("TRUNCATE `kills`")
 			self.dbc.execute("TRUNCATE `per_game_stats`")
 			self.dbc.execute("TRUNCATE `players`")
+			self.dbc.execute("TRUNCATE `nicks`")
 			self.dbc.execute("TRUNCATE `says`")
 
 			# Create the log to reparse
diff -ru Tremstats-NightlyBuild-Rev-58/sql/structure.sql Tremstats-Slux/sql/structure.sql
--- Tremstats-NightlyBuild-Rev-58/sql/structure.sql	2006-12-16 20:12:33.000000000 +0100
+++ Tremstats-Slux/sql/structure.sql	2007-09-12 13:35:21.000000000 +0200
@@ -77,6 +77,16 @@
   UNIQUE KEY `map_name` (`map_name`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
+DROP TABLE IF EXISTS `nicks`;
+CREATE TABLE `nicks` (
+  `nick_id` int(11) unsigned NOT NULL auto_increment,
+  `player_qkey` varchar(32) NOT NULL default '',
+  `nick_name_uncolored` varchar(200) NOT NULL default '',
+  `nick_name` varchar(200) NOT NULL default '',
+  PRIMARY KEY  (`nick_id`),
+  KEY `player_qkey` (`player_qkey`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
 DROP TABLE IF EXISTS `per_game_stats`;
 CREATE TABLE IF NOT EXISTS `per_game_stats` (
   `stats_id` int(11) unsigned NOT NULL auto_increment,
@@ -92,6 +102,7 @@
 DROP TABLE IF EXISTS `players`;
 CREATE TABLE IF NOT EXISTS `players` (
   `player_id` int(11) unsigned NOT NULL auto_increment,
+  `player_qkey` varchar(32) NOT NULL default 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
   `player_name` varchar(200) NOT NULL default '',
   `player_name_uncolored` varchar(200) NOT NULL default '',
   `player_games_played` int(11) NOT NULL default '0',
@@ -110,6 +121,7 @@
   `player_deaths_by_world` int(11) NOT NULL default '0',
   `player_total_deaths` int(11) NOT NULL default '0',
   PRIMARY KEY  (`player_id`),
+  KEY `player_qkey` (`player_qkey`),
   KEY `player_name` (`player_name`(15)),
   FULLTEXT KEY `player_name_uncolored` (`player_name_uncolored`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Only in Tremstats-Slux/sql: structure.sql~
diff -ru Tremstats-NightlyBuild-Rev-58/web/player_details.php Tremstats-Slux/web/player_details.php
--- Tremstats-NightlyBuild-Rev-58/web/player_details.php	2006-12-16 20:12:07.000000000 +0100
+++ Tremstats-Slux/web/player_details.php	2007-09-12 11:49:32.000000000 +0200
@@ -15,6 +15,7 @@
 // Player details
 $player_details = $db->GetRow("SELECT player_id,
                                       player_name,
+                                      player_qkey,
                                       player_games_played,
                                       player_games_paused,
                                       player_game_time_factor,
@@ -36,6 +37,12 @@
                                LIMIT 0, 1",
                                array($_GET['player_id']));
 
+// Other nicks used by this player
+$player_nicks = $db->GetAll("SELECT nick_name
+                              FROM `nicks`
+                              WHERE player_qkey = ?",
+                              array($player_details['player_qkey']));
+
 // Random quote
 $random_quote = $db->GetRow("SELECT say_mode, say_message
                              FROM says
@@ -69,6 +76,7 @@
 
 // Assign variables to template
 $tpl->assign('player_details',       $player_details);
+$tpl->assign('player_nicks',         $player_nicks);
 $tpl->assign('random_quote',         $random_quote);
 $tpl->assign('prefered_weapons',     $prefered_weapons);
 $tpl->assign('destroyed_structures', $destroyed_structures);
diff -ru Tremstats-NightlyBuild-Rev-58/web/search_player.php Tremstats-Slux/web/search_player.php
--- Tremstats-NightlyBuild-Rev-58/web/search_player.php	2006-12-16 20:12:07.000000000 +0100
+++ Tremstats-Slux/web/search_player.php	2007-09-12 16:12:40.000000000 +0200
@@ -26,9 +26,20 @@
                          WHERE player_name_uncolored LIKE '%".$_GET['query']."%'
                          ORDER BY ".$order);
   $players = $db->GetAll($pagelister->GetQuery());
+  
+  // Maybe an alias?
+  $players_tjw =  $db->GetAll("SELECT player_id,
+                                   nick_name AS player_name,
+                                   player_name  AS player_tjw_name,
+                                   player_total_kills,
+                                   player_total_deaths,
+                                   player_total_efficiency
+                            FROM players JOIN nicks ON players.player_qkey = nicks.player_qkey
+                            WHERE  nicks.nick_name_uncolored LIKE '%".$_GET['query']."%' OR players.player_name_uncolored LIKE '%scor%' 
+                            ORDER BY ".$order);
 
   // Assign variables to template
-  $tpl->assign('players', $players);
+  $tpl->assign('players', array_merge($players, $players_tjw));
 }
 
 // Show the template
diff -ru Tremstats-NightlyBuild-Rev-58/web/skins/default/default/skin.css Tremstats-Slux/web/skins/default/default/skin.css
--- Tremstats-NightlyBuild-Rev-58/web/skins/default/default/skin.css	2006-12-16 20:12:07.000000000 +0100
+++ Tremstats-Slux/web/skins/default/default/skin.css	2007-09-12 12:34:00.000000000 +0200
@@ -215,6 +215,10 @@
   color: #FFFFFF;
 }
 
+td.playerothernames {
+  vertical-align: top;
+}
+
 span.quakecolor_black {
   color: #000000;
 }
Only in Tremstats-Slux/web/skins/default/default: skin.css~
diff -ru Tremstats-NightlyBuild-Rev-58/web/templates/default/__footer__.tpl.php Tremstats-Slux/web/templates/default/__footer__.tpl.php
--- Tremstats-NightlyBuild-Rev-58/web/templates/default/__footer__.tpl.php	2006-12-10 21:44:20.000000000 +0100
+++ Tremstats-Slux/web/templates/default/__footer__.tpl.php	2007-09-12 16:19:12.000000000 +0200
@@ -9,7 +9,7 @@
         ?>
         seconds
       </span>
-      Tremstats v<?php echo VERSION; ?> by <a href="http://www.dasprids.de" title="DASPRiD's">DASPRiD</a>
+      Tremstats v<?php echo VERSION; ?> by <a href="http://www.dasprids.de" title="DASPRiD's">DASPRiD</a> ~ <a href="http://www.capponcino.it/alessio/" title="Slux's">Slux Mod</a>
     </div>
   </body>
 </html>
\ No newline at end of file
diff -ru Tremstats-NightlyBuild-Rev-58/web/templates/default/player_details.tpl.php Tremstats-Slux/web/templates/default/player_details.tpl.php
--- Tremstats-NightlyBuild-Rev-58/web/templates/default/player_details.tpl.php	2006-12-16 20:12:07.000000000 +0100
+++ Tremstats-Slux/web/templates/default/player_details.tpl.php	2007-09-12 12:35:32.000000000 +0200
@@ -20,6 +20,14 @@
         <td class="playername"><?php echo replace_color_codes(htmlspecialchars($this->player_details['player_name'])); ?></td>
       </tr>
       <tr>
+        <td class="playerothernames">Other Names</td>
+        <td>
+          <?php foreach($this->player_nicks as $other_nick): ?>
+            <?php echo replace_color_codes(htmlspecialchars($other_nick['nick_name'])) . "<br />"; ?>
+          <?php endforeach; ?>
+        </td>
+      </tr>
+      <tr>
         <td>Games played</td>
         <td><?php echo $this->player_details['player_games_played']; ?></td>
       </tr>
diff -ru Tremstats-NightlyBuild-Rev-58/web/templates/default/search_player.tpl.php Tremstats-Slux/web/templates/default/search_player.tpl.php
--- Tremstats-NightlyBuild-Rev-58/web/templates/default/search_player.tpl.php	2006-12-16 20:12:07.000000000 +0100
+++ Tremstats-Slux/web/templates/default/search_player.tpl.php	2007-09-12 15:53:04.000000000 +0200
@@ -4,16 +4,11 @@
   <h2>Search result</h2>
 
   <table>
-    <colgroup>
-      <col />
-      <col width="100" />
-      <col width="100" />
-      <col width="100" />
-    </colgroup>
 
     <thead>
       <tr>
         <th><?php echo custom_sort('Player',     'player'); ?></th>
+        <th><?php echo 'Know as'; ?></th>
         <th><?php echo custom_sort('Kills',      'kills'); ?></th>
         <th><?php echo custom_sort('Deaths',     'deaths'); ?></th>
         <th><?php echo custom_sort('Efficiency', 'efficiency'); ?></th>
@@ -22,7 +17,7 @@
 
     <tfoot>
       <tr>
-        <td colspan="4">
+        <td colspan="5">
           Pages: <?php echo $this->pagelister->GetHTML(); ?>
         </td>
       </tr>
@@ -32,6 +27,7 @@
       <?php foreach ($this->players AS $player): ?>
         <tr>
           <td class="playername"><a href="player_details.php?player_id=<?php echo $player['player_id'] ?>"><?php echo replace_color_codes(htmlspecialchars($player['player_name'])); ?></a></td>
+          <td><?php if(isset($player['player_tjw_name'])) { echo replace_color_codes(htmlspecialchars($player['player_tjw_name'])); }?></td>
           <td><?php echo $player['player_total_kills']; ?></td>
           <td><?php echo $player['player_total_deaths']; ?></td>
           <td><?php echo $player['player_total_efficiency']; ?></td>
@@ -40,7 +36,7 @@
 
       <?php if (!count($this->players)): ?>
         <tr>
-          <td colspan="4">No matching players found</td>
+          <td colspan="5">No matching players found</td>
         </tr>
       <?php endif; ?>
     </tbody>
