123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- #!/usr/bin/env python3
- """
- # sauerstats.py
- # Copyright (c) 2010-2011 Michael Buesch <m@bues.ch>
- # Licensed under the GNU/GPL version 2 or later.
- """
- import sys
- from gamestats import *
- class SauerbratenParser(Parser):
- _re_name = r'(.*)' # Player/item name
- re_init = re.compile(r'^init: .*$')
- re_waypoints = re.compile(r'^loaded (\d+) waypoints from ' + _re_name + r'$')
- re_intermission = re.compile(r'^intermission:$')
- re_info = re.compile(r'^Info: .*$')
- re_rendering = re.compile(r'^Rendering using .*$')
- re_game_mode = re.compile(r'^game mode is ' + _re_name + r'$')
- re_game_ended = re.compile(r'^game has ended!$')
- re_you_disconn = re.compile(r'^disconnected$')
- re_player_disconn = re.compile(r'^player ' + _re_name + r' disconnected$')
- re_conn_attempt = re.compile(r'^attempting to connect.*$')
- re_connected = re.compile(r'^connected to server$')
- re_player_connected = re.compile(r'^connected: ' + _re_name + r'$')
- re_connected_from = re.compile(r'^' + _re_name + r' connected from ' +\
- _re_name + r'$')
- re_connected_from2 = re.compile(r'^' + _re_name + r' is fragging in ' +\
- _re_name + r'$')
- re_disconn_attempt = re.compile(r'^attempting to disconnect\.\.\.$')
- re_rename = re.compile(r'^' + _re_name + r' is now known as ' + _re_name + r'$')
- re_read_map = re.compile(r'^read map (.*) \(\d+\.\d+ seconds\)$')
- re_suggest = re.compile(r'^' + _re_name + r' suggests ' + _re_name + r' on map ' +
- _re_name + r' \(select map to vote\)$')
- re_you_got_fragged = re.compile(r'^you got fragged by ' + _re_name + r'$')
- re_fragged = re.compile(r'^' + _re_name + r' fragged ' + _re_name + r'$')
- re_fragged_teammate = re.compile(r'^' + _re_name + r' fragged a teammate \(' +\
- _re_name + r'\)$')
- re_yougotkilledby_teammate = re.compile(r'^you got fragged by a teammate \(' +\
- _re_name + r'\)$')
- re_suicide = re.compile(r'^' + _re_name + r' suicided!?$')
- re_dropped_your = re.compile(r'^' + _re_name + r' dropped your flag$')
- re_dropped_enemy = re.compile(r'^' + _re_name + r' dropped the enemy flag$')
- re_stole_your = re.compile(r'^' + _re_name + r' stole your flag$')
- re_stole_enemy = re.compile(r'^' + _re_name + r' stole the enemy flag$')
- re_picked_your = re.compile(r'^' + _re_name + r' picked up your flag$')
- re_picked_enemy = re.compile(r'^' + _re_name + r' picked up the enemy flag$')
- re_score_your = re.compile(r'^' + _re_name + r' scored for your team$')
- re_score_enemy = re.compile(r'^' + _re_name + r' scored for the enemy team$')
- re_returned_your = re.compile(r'^' + _re_name + r' returned your flag$')
- re_returned_enemy = re.compile(r'^' + _re_name + r' returned the enemy flag$')
- re_stopped_by = re.compile(r'^' + _re_name + r' was stopped by ' + _re_name + r'$')
- re_rampage = re.compile(r'^' + _re_name + r' is on a RAMPAGE!!$')
- re_dominate = re.compile(r'^' + _re_name + r' is DOMINATING!!$')
- re_triplekill = re.compile(r'^' + _re_name + r' scored a TRIPLE KILL!$')
- re_msg = re.compile(r'^' + _re_name + r': .*$')
- # chat annotation patch
- re_chat = re.compile(r'^chat-message: ' + _re_name + r':\s*(.*)$')
- re_teamchat = re.compile(r'^teamchat-message: ' + _re_name + r':\s*(.*)$')
- def __init__(self, options):
- Parser.__init__(self, options)
- self.lastReadMap = "unknown"
- def __parseKill(self, timestamp, name0, name1, tk=False):
- # name0 fragged name1
- if not self.assertCurrentGame("kill"):
- return
- player0 = self.currentGame.playerOrMe(name0)
- player1 = self.currentGame.playerOrMe(name1)
- if tk:
- player0.addTeamkill(timestamp, player1)
- else:
- player0.addFrag(timestamp, player1)
- self.currentGame.hadFirstBlood = True
- def doParseLine(self, stamp, line):
- line = line.strip()
- m = self.re_chat.match(line)
- if m:
- debugMsg("Chat (%s: %s)" % (m.group(1), m.group(2)))
- return
- m = self.re_teamchat.match(line)
- if m:
- debugMsg("Teamchat (%s: %s)" % (m.group(1), m.group(2)))
- return
- m = self.re_info.match(line)
- if m:
- debugMsg("Info (%s)" % line)
- return
- m = self.re_game_ended.match(line)
- if m:
- if not self.assertCurrentGame("game ended"):
- return
- debugMsg("Game ended (%s)" % line)
- if self.currentGame.ended:
- print("Current game ended twice?!")
- return
- self.currentGame.ended = stamp
- self.gameEnded()
- return
- m = self.re_game_mode.match(line)
- if m:
- self.currentGame = None
- debugMsg("Game mode (%s)" % line)
- newGame = Game(options=self.options,
- timestamp=stamp, mode=m.group(1),
- mapname=self.lastReadMap,
- selfIDs=("you",))
- self.currentGame = newGame
- self.games.append(newGame)
- return
- m = self.re_yougotkilledby_teammate.match(line)
- if m:
- debugMsg("TK 1 (%s)" % line)
- self.__parseKill(stamp, m.group(1), None, tk=True)
- return
- m = self.re_fragged_teammate.match(line)
- if m:
- debugMsg("TK 2 (%s)" % line)
- self.__parseKill(stamp, m.group(1), m.group(2), tk=True)
- return
- m = self.re_you_got_fragged.match(line)
- if m:
- debugMsg("Frag 1 (%s)" % line)
- self.__parseKill(stamp, m.group(1), None)
- return
- m = self.re_fragged.match(line)
- if m:
- debugMsg("Frag 2 (%s)" % line)
- self.__parseKill(stamp, m.group(1), m.group(2))
- return
- m = self.re_suicide.match(line)
- if m:
- debugMsg("Suicide (%s)" % line)
- if not self.assertCurrentGame("suicide"):
- return
- player = self.currentGame.playerOrMe(m.group(1))
- player.addSuicide(stamp)
- return
- m = self.re_dropped_your.match(line)
- if m:
- debugMsg("Dropped your flag (%s)" % line)
- if not self.assertCurrentGame("dropped-your"):
- return
- player = self.currentGame.player(m.group(1))
- player.addCtfDrop(stamp)
- return
- m = self.re_dropped_enemy.match(line)
- if m:
- debugMsg("Dropped enemy flag (%s)" % line)
- if not self.assertCurrentGame("dropped-enemy"):
- return
- player = self.currentGame.playerOrMe(m.group(1))
- player.addCtfDrop(stamp)
- return
- m = self.re_stole_your.match(line)
- if m:
- debugMsg("Stole your flag (%s)" % line)
- if not self.assertCurrentGame("stole-your"):
- return
- player = self.currentGame.player(m.group(1))
- player.addCtfSteal(stamp)
- return
- m = self.re_stole_enemy.match(line)
- if m:
- debugMsg("Stole enemy flag (%s)" % line)
- if not self.assertCurrentGame("stole-enemy"):
- return
- player = self.currentGame.playerOrMe(m.group(1))
- player.addCtfSteal(stamp)
- return
- m = self.re_picked_your.match(line)
- if m:
- debugMsg("Picked your flag (%s)" % line)
- if not self.assertCurrentGame("picked-your"):
- return
- player = self.currentGame.player(m.group(1))
- player.addCtfPick(stamp)
- return
- m = self.re_picked_enemy.match(line)
- if m:
- debugMsg("Picked enemy flag (%s)" % line)
- if not self.assertCurrentGame("picked-enemy"):
- return
- player = self.currentGame.playerOrMe(m.group(1))
- player.addCtfPick(stamp)
- return
- m = self.re_score_your.match(line)
- if m:
- debugMsg("Scored for your team (%s)" % line)
- if not self.assertCurrentGame("scored-your"):
- return
- player = self.currentGame.playerOrMe(m.group(1))
- player.addCtfScore(stamp)
- return
- m = self.re_score_enemy.match(line)
- if m:
- debugMsg("Scored for enemy team (%s)" % line)
- if not self.assertCurrentGame("scored-enemy"):
- return
- player = self.currentGame.player(m.group(1))
- player.addCtfScore(stamp)
- return
- m = self.re_returned_your.match(line)
- if m:
- debugMsg("Returned your flag (%s)" % line)
- if not self.assertCurrentGame("returned-your"):
- return
- player = self.currentGame.playerOrMe(m.group(1))
- player.addCtfReturn(stamp)
- return
- m = self.re_returned_enemy.match(line)
- if m:
- debugMsg("Returned enemy flag (%s)" % line)
- if not self.assertCurrentGame("returned-enemy"):
- return
- player = self.currentGame.player(m.group(1))
- player.addCtfReturn(stamp)
- return
- m = self.re_stopped_by.match(line)
- if m:
- debugMsg("Stopped by (%s)" % line)
- return
- m = self.re_rampage.match(line)
- if m:
- debugMsg("Rampage (%s)" % line)
- return
- m = self.re_dominate.match(line)
- if m:
- debugMsg("Dominate (%s)" % line)
- return
- m = self.re_triplekill.match(line)
- if m:
- debugMsg("Triplekill (%s)" % line)
- return
- m = self.re_suggest.match(line)
- if m:
- debugMsg("Suggest (%s)" % line)
- return
- m = self.re_player_connected.match(line)
- if m:
- debugMsg("Player connected (%s)" % line)
- if not self.assertCurrentGame("player connected"):
- return
- name = m.group(1)
- self.currentGame.player(name).connected()
- return
- m = self.re_player_disconn.match(line)
- if m:
- debugMsg("Player disconnected (%s)" % line)
- if not self.assertCurrentGame("player connected"):
- return
- name = m.group(1)
- self.currentGame.player(name).disconnected()
- return
- m = self.re_conn_attempt.match(line)
- if m:
- debugMsg("Connection attempt (%s)" % line)
- return
- m = self.re_connected.match(line)
- if m:
- debugMsg("Connected (%s)" % line)
- return
- m = self.re_connected_from.match(line)
- if m:
- debugMsg("Connected from (%s)" % line)
- return
- m = self.re_connected_from2.match(line)
- if m:
- debugMsg("Connected from (%s)" % line)
- return
- m = self.re_disconn_attempt.match(line)
- if m:
- debugMsg("Disconnect attempt (%s)" % line)
- return
- m = self.re_you_disconn.match(line)
- if m:
- debugMsg("Disconnected (%s)" % line)
- return
- m = self.re_rename.match(line)
- if m:
- debugMsg("Player rename (%s)" % line)
- if not self.assertCurrentGame("player rename"):
- return
- oldName = m.group(1)
- newName = m.group(2)
- self.currentGame.player(oldName).rename(newName)
- return
- m = self.re_read_map.match(line)
- if m:
- if self.options.splitLogs:
- closeRawLog()
- debugMsg("Map (%s)" % line)
- mapname = m.group(1)
- mapname = mapname.split('/')[-1]
- if mapname.endswith(".ogz"):
- mapname = mapname[0:-4]
- self.lastReadMap = mapname
- return
- m = self.re_rendering.match(line)
- if m:
- debugMsg("Renderer (%s)" % line)
- return
- m = self.re_init.match(line)
- if m:
- debugMsg("Init (%s)" % line)
- return
- m = self.re_waypoints.match(line)
- if m:
- debugMsg("Waypoints (%s)" % line)
- return
- m = self.re_intermission.match(line)
- if m:
- debugMsg("Intermission (%s)" % line)
- return
- m = self.re_msg.match(line)
- if m:
- debugMsg("Message (%s)" % line)
- return
- if not line.replace("*", "") or\
- not line.replace(">", ""):
- debugMsg("Spacer (%s)" % line)
- return
- debugMsg("UNKNOWN console message: '%s'" % line)
- def main():
- return genericMain(scriptname="sauerstats",
- usageinfo=" Example: Convert and log stats into directory:\n"
- " sauerbraten_unix | sauerstats -n mynick -l ./logs\n"
- "\n"
- " Example: Create stats from logfile:\n"
- " sauerstats -n mynick ./logs/2011....log",
- parserClass=SauerbratenParser)
- if __name__ == "__main__":
- sys.exit(main())
|