all latent changes, undisclosed and without warranty.
This commit is contained in:
parent
8411ed858c
commit
10c557dea3
28
analyze.py
28
analyze.py
@ -27,31 +27,39 @@ if __name__ == '__main__':
|
||||
'Documents', 'My Games', 'sc'))
|
||||
coll.collect_unique()
|
||||
#f = open('output.txt', 'w')
|
||||
rex = {}
|
||||
rex_combat = {}
|
||||
rex_game = {}
|
||||
for logf in coll.sessions:
|
||||
logf.parse_files(['game.log',])
|
||||
print "Combat Log %s" % logf.idstr
|
||||
logf.parse_files(['game.log', 'combat.log'])
|
||||
print "----- Log %s -----" % logf.idstr
|
||||
if logf.combat_log:
|
||||
for l in logf.combat_log.lines:
|
||||
if isinstance(l, dict):
|
||||
#print l
|
||||
pass
|
||||
rex_combat['dict'] = rex_combat.get('dict', 0) + 1
|
||||
else:
|
||||
if not l.unpack():
|
||||
rex[l.__class__.__name__] = rex.get(l.__class__.__name__, 0) + 1
|
||||
rex_combat[l.__class__.__name__] = rex_combat.get(l.__class__.__name__, 0) + 1
|
||||
if not isinstance(l, combat.UserEvent):
|
||||
print l.values['log']
|
||||
if logf.game_log:
|
||||
for l in logf.game_log.lines:
|
||||
if isinstance(l, dict):
|
||||
pass
|
||||
rex_game['dict'] = rex_game.get('dict', 0) + 1
|
||||
elif isinstance(l, str):
|
||||
print l
|
||||
else:
|
||||
if l.unpack():
|
||||
pass
|
||||
else:
|
||||
rex_game[l.__class__.__name__] = rex_game.get(l.__class__.__name__, 0) + 1
|
||||
print l.values['log']
|
||||
# ClientInfo introspection for ping
|
||||
if isinstance(l, ClientInfo) and l.values.get('clinfo', '') == 'avgPing':
|
||||
print l.values
|
||||
# fix avgPing parsing!
|
||||
print rex
|
||||
#if isinstance(l, ClientInfo) and l.values.get('clinfo', '') == 'avgPing':
|
||||
# print l.values
|
||||
# # fix avgPing parsing!
|
||||
print 'Analysis complete:'
|
||||
print '#'*20+' RexCombat ' + '#' *20
|
||||
print rex_combat
|
||||
print '#'*20+' RexGame ' + '#' *20
|
||||
print rex_game
|
||||
|
31
battle.py
31
battle.py
@ -1,2 +1,33 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Tool to analyze Logs in general.
|
||||
"""
|
||||
import os, sys, logging
|
||||
from logs.logfiles import LogFileResolver as LogFile
|
||||
from logs import combat, game, chat
|
||||
from logs.session import LogSessionCollector
|
||||
from logs.game import ClientInfo
|
||||
|
||||
# for windows its kinda this:
|
||||
settings = {'root_path': os.path.join(os.path.expanduser('~'),
|
||||
'Documents',
|
||||
'My Games',
|
||||
'StarConflict',),
|
||||
'logfiles': os.path.join(os.path.expanduser('~'),
|
||||
'Documents',
|
||||
'My Games',
|
||||
'StarConflict',
|
||||
'logs'
|
||||
)}
|
||||
if __name__ == '__main__':
|
||||
coll = LogSessionCollector(os.path.join(os.path.expanduser('~'),
|
||||
'Documents', 'My Games', 'sc'))
|
||||
coll.collect_unique()
|
||||
for logf in coll.sessions:
|
||||
logf.parse_files(['game.log', 'combat.log'])
|
||||
logf.clean()
|
||||
if logf.combat_log:
|
||||
print 'length combat log ', len(logf.combat_log.lines)
|
||||
if logf.game_log:
|
||||
print 'length game log ', len(logf.game_log.lines)
|
@ -28,6 +28,7 @@ QUALITY_TYPES = (
|
||||
(5, 'Mk5'),
|
||||
(10, 'Universal'),
|
||||
(14, 'Pirate Mk4'),
|
||||
(99, 'Alien'),
|
||||
)
|
||||
D_QUALITY = dict(QUALITY_TYPES)
|
||||
|
||||
@ -51,9 +52,13 @@ ROLE_TYPES = (
|
||||
(6, 'Gunship'),
|
||||
(7, 'Engineer'),
|
||||
(8, 'Guard'),
|
||||
(9, 'Longrange')
|
||||
(9, 'Longrange'),
|
||||
(10, 'Interceptors'),
|
||||
(20, 'Fighters'),
|
||||
(30, 'Frigates'),
|
||||
)
|
||||
# Create your models here.
|
||||
|
||||
|
||||
class Item(models.Model):
|
||||
name = models.CharField(max_length=128)
|
||||
description = models.TextField(blank=True, null=True)
|
||||
|
@ -5,13 +5,25 @@
|
||||
"""
|
||||
|
||||
class Battle(object):
|
||||
__slots__ = ['players',
|
||||
'teams',
|
||||
'time_start',
|
||||
'time_end',]
|
||||
def __init__(self, parent=None):
|
||||
# parent is a log-session usually
|
||||
self.players = []
|
||||
self.teams = []
|
||||
self.time_start = None
|
||||
self.time_end = None
|
||||
self.owner = None
|
||||
|
||||
|
||||
def battle_factory(logs):
|
||||
''' takes a log session and returns the battles in it
|
||||
makes a preliminary scan for information
|
||||
'''
|
||||
|
||||
if logs.combat_log and logs.game_log:
|
||||
# without these it does not make sense
|
||||
# check combat_log
|
||||
|
||||
pass
|
||||
|
||||
return []
|
||||
|
||||
|
28
game/screener.py
Normal file
28
game/screener.py
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
"""
|
||||
Screener Module.
|
||||
|
||||
Upon receiving a logfile, the screener module tries a first pass to retrieve the informations:
|
||||
- who am i? am i in steam?
|
||||
- which os do i use? whats the date? other specifics?
|
||||
- battles, when did they begin, when did they end, which players were in it, which teams (game.log)
|
||||
|
||||
It should act as a factory for a second, more in depth parsing mechanism, which can retrieve and
|
||||
manage the rest of the details.
|
||||
|
||||
"""
|
||||
class Information:
|
||||
def __init__(self):
|
||||
self.steam_id = None # steam id
|
||||
self.steam_username = None # optional steam username.
|
||||
self.username = None # ingame username.
|
||||
self.uid = None # does not change.
|
||||
self.pid = None # changes per battle. needed once to identify pilot.
|
||||
|
||||
|
||||
|
||||
class Screener(object):
|
||||
def __init__(self):
|
||||
pass
|
@ -92,11 +92,14 @@ class WarningLog(Log):
|
||||
# Individual logs.
|
||||
|
||||
class SteamInitialization(GameLog):
|
||||
matcher = []
|
||||
matcher = [
|
||||
re.compile(r"^Steam\sinitialized\sappId\s(?P<steam_app_id>\d+),\suserSteamID\s(?P<steam_id_universe>\d+)\|(?P<steam_id_type>\d+)\|(?P<steam_id_account_hex>\w+),\suserName\s'(?P<steam_username>[^']+)'"),
|
||||
]
|
||||
|
||||
class MasterServerSession(GameLog):
|
||||
matcher = [
|
||||
re.compile(r"^MasterServerSession\:\sconnect\sto\sdedicated\sserver(?:,\s|session\s(?P<session_id>\d+)|at addr (?P<addr>\d+\.\d+\.\d+\.\d+)\|(?P<port>\d+))+"),
|
||||
re.compile(r"^MasterServerSession:\sconnect\sto\sZoneInstance,\ssession\s(?P<session_id>\d+),\sat\saddr\s(?P<addr>\d+\.\d+\.\d+\.\d+)\|(?P<port>\d+),\szoneId\s(?P<zone_id>\d+)"),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
|
@ -9,6 +9,7 @@
|
||||
data by setting the LogFile<instance>._data yourself.
|
||||
"""
|
||||
import re
|
||||
from .base import Log
|
||||
RE_SCLOG = r'^(?P<hh>\d{2,2})\:(?P<mm>\d{2,2})\:(?P<ss>\d{2,2})\.(?P<ns>\d{3,3})\s(?P<logtype>\s*[^\|\s]+\s*|\s+)\|\s(?P<log>.*)'
|
||||
R_SCLOG = re.compile(RE_SCLOG)
|
||||
|
||||
@ -34,6 +35,15 @@ class LogFile(object):
|
||||
def _unset_data(self):
|
||||
self._data = None
|
||||
|
||||
def filter(self, klasses):
|
||||
ret = []
|
||||
for line in self.lines:
|
||||
for k in klasses:
|
||||
if isinstance(line, k):
|
||||
ret.append(line)
|
||||
break
|
||||
return ret
|
||||
|
||||
def parse(self):
|
||||
# parse _data if we still have no lines.
|
||||
if self._data:
|
||||
@ -84,3 +94,17 @@ class LogFile(object):
|
||||
# try to find a class that is responsible for this log.
|
||||
return line
|
||||
|
||||
def clean(self):
|
||||
# cleans the logs by removing all non parsed packets.
|
||||
lines = []
|
||||
for l in self.lines:
|
||||
if isinstance(l, Log):
|
||||
if l.unpack():
|
||||
if not getattr(l, 'trash', False):
|
||||
lines.append(l)
|
||||
else:
|
||||
print type(l)
|
||||
print l
|
||||
self.lines = lines
|
||||
self._unset_data()
|
||||
|
||||
|
@ -15,6 +15,7 @@ class LogSession(object):
|
||||
''' if directory is a file, it will be handled as a compressed folder '''
|
||||
self.battles = []
|
||||
self.user = None
|
||||
self.files_parsed = []
|
||||
|
||||
# various logfiles used.
|
||||
self.combat_log = None
|
||||
@ -27,6 +28,15 @@ class LogSession(object):
|
||||
self.idstr = None # id string to identify this log instance.
|
||||
self._error = False
|
||||
|
||||
def clean(self):
|
||||
if self.combat_log:
|
||||
self.combat_log.clean()
|
||||
if self.game_log:
|
||||
self.game_log.clean()
|
||||
if self.chat_log:
|
||||
self.chat_log.clean()
|
||||
|
||||
|
||||
def validate(self, contents=False):
|
||||
"""
|
||||
- validates if the logfiles are within this package.
|
||||
@ -56,14 +66,18 @@ class LogSession(object):
|
||||
if self._zip_source:
|
||||
self._unzip_logs(files)
|
||||
else:
|
||||
if 'combat.log' in files:
|
||||
if files is None:
|
||||
files = self.VALID_FILES
|
||||
if 'combat.log' in files and not 'combat.log' in self.files_parsed:
|
||||
self.combat_log = CombatLogFile(os.path.join(self.directory, 'combat.log'))
|
||||
self.combat_log.read()
|
||||
self.combat_log.parse()
|
||||
if 'game.log' in files:
|
||||
self.files_parsed.append('combat.log')
|
||||
if 'game.log' in files and not 'game.log' in self.files_parsed:
|
||||
self.game_log = GameLogFile(os.path.join(self.directory, 'game.log'))
|
||||
self.game_log.read()
|
||||
self.game_log.parse()
|
||||
self.files_parsed.append('game.log')
|
||||
|
||||
def determine_owner(self):
|
||||
''' determines the user in the parsed gamelog '''
|
||||
@ -80,12 +94,16 @@ class LogSession(object):
|
||||
fn = os.path.split(filename)[1] or ''
|
||||
fn = fn.lower()
|
||||
if fn:
|
||||
if fn == 'combat.log' and (not files or fn in files):
|
||||
if fn == 'combat.log' and (not files or fn in files) and not 'combat.log' in self.files_parsed:
|
||||
self.combat_log = CombatLogFile(fn)
|
||||
self.combat_log.set_data(z.read(filename))
|
||||
elif fn == 'game.log' and (not files or fn in files):
|
||||
self.combat_log.parse()
|
||||
self.files_parsed.append('combat.log')
|
||||
elif fn == 'game.log' and (not files or fn in files) and not 'game.log' in self.files_parsed:
|
||||
self.game_log = GameLogFile(fn)
|
||||
self.game_log.set_data(z.read(filename))
|
||||
self.game_log.parse()
|
||||
self.files_parsed.append('game.log')
|
||||
except:
|
||||
self._error = True
|
||||
return
|
||||
|
0
utils/__init__.py
Normal file
0
utils/__init__.py
Normal file
28
utils/steam.py
Normal file
28
utils/steam.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""
|
||||
X:Y:Z
|
||||
|
||||
X - Universe
|
||||
0 Individual / Unspecified
|
||||
1 Public
|
||||
2 Beta
|
||||
3 Internal
|
||||
4 Dev
|
||||
5 RC
|
||||
|
||||
Y - Steam Type
|
||||
0 I Invalid No
|
||||
1 U Individual Yes profiles / id 0x0110000100000000
|
||||
2 M Multiseat Yes
|
||||
3 G GameServer Yes
|
||||
4 A AnonGameServer Yes
|
||||
5 P Pending No
|
||||
6 C ContentServer Unknown
|
||||
7 g Clan Yes groups / gid 0x0170000000000000
|
||||
8 c, L, T Chat Yes
|
||||
9 P2P SuperSeeder No
|
||||
10 AnonUser No
|
||||
|
||||
Z - account or group uid
|
||||
|
||||
|
||||
"""
|
Loading…
Reference in New Issue
Block a user