diff --git a/src/scon/analyze.py b/src/scon/analyze.py index bf74583..c62042b 100644 --- a/src/scon/analyze.py +++ b/src/scon/analyze.py @@ -38,7 +38,7 @@ settings = {'analyze_path': os.path.join(os.path.expanduser('~'), def select_parsing_sessions(alist): # for micro controlling, which sessions to parse. # default: return alist - return alist + return alist[-50:] if __name__ == '__main__': # set this to your liking: diff --git a/src/scon/logs/combat.py b/src/scon/logs/combat.py index 30a0385..8a1e1a7 100644 --- a/src/scon/logs/combat.py +++ b/src/scon/logs/combat.py @@ -88,23 +88,46 @@ class Gameplay(CombatLog): re.compile(r"^Gameplay\sfinished\.\sWinner\steam\:\s+(?P\d+).\sFinish\sreason\:\s'(?P[^']+)'\.\sActual\sgame\stime\s+(?P\d+|\d+\.\d+)\ssec"), ] -class Apply(CombatLog): # Apply Aura. +class Apply(CombatLog): + """ + Aura is applied. + aura_name, id, aura_type, target_name + """ __slots__ = CombatLog.__slots__ matcher = re.compile(r"^Apply\saura\s'(?P\w+)'\sid\s(?P\d+)\stype\s(?P\w+)\sto\s'(?P[^\']+)'") class Damage(CombatLog): + """ + Damage is done. + source_name, target_name, amount, module_class, flags + """ __slots__ = CombatLog.__slots__ matcher = re.compile(r"^Damage\s+(?P[^\s]+)\s\->\s+(?P[^\s]+)\s+(?P(?:\d+|\d+\.\d+))(?:\s(?P[^\s]+)\s|\s{2,2})(?P(?:\w|\|)+)") class Spawn(CombatLog): + """ + Something is spawned + player (number), name, hash, ship_class + player might be -1, name might be '' and hash might be 0 for npcs. + """ __slots__ = CombatLog.__slots__ matcher = re.compile(r"^Spawn\sSpaceShip\sfor\splayer(?P-*\d+)\s\((?P[^,]*),\s+(?P#\w+)\)\.\s+'(?P\w+)'") class Spell(CombatLog): + """ + Spell is cast + spell_name, source_name, module_name, target_num, targets + """ __slots__ = CombatLog.__slots__ matcher = re.compile(r"^Spell\s'(?P\w+)'\sby\s+(?P.*)(?:\((?P\w+)\)|)\stargets\((?P\d+)\)\:(?:\s(?P.+)|\s*)") class Reward(CombatLog): + """ + Reward is given. + name, ship_class + 0: amount, reward_type, reward_reason + 1: karma, reward_reason + """ __slots__ = CombatLog.__slots__ matcher = [ # ordinary reward: @@ -114,6 +137,11 @@ class Reward(CombatLog): ] class Participant(CombatLog): + """ + Has been participant (in a kill just before) + source_name + optional: ship_class, total_damage, module_class, additional, other + """ __slots__ = CombatLog.__slots__ matcher = [ # more complex version: @@ -124,6 +152,12 @@ class Participant(CombatLog): ] class Rocket(CombatLog): + """ + Rocket events. + event: launch or detonation + 0: name, def, target, reason, direct_hit + 1: rocket_id, name, def, target, reason, direct_hit + """ __slots__ = CombatLog.__slots__ # keys = [ 'event', 'name', 'def', 'target', 'reason', 'direct_hit', 'rocket_id' ] # changed 'missile_type' to 'def' @@ -136,10 +170,16 @@ class Rocket(CombatLog): ] class Heal(CombatLog): + """ + Healing is done. + 0: source_name, target_name, amount, module_class + 1: source_name, target_name, amount + 2: source_name, source_tid, target_name, target_tid, amount + """ __slots__ = CombatLog.__slots__ matcher = [ # heal by module - re.compile(r"^Heal\s+(?P[^\s]+)\s\->\s+(?P[^\s]+)\s+(?P(?:\d+|\d+\.\d+))\s(?P[^\s]+)"), + re.compile(r"^Heal\s+(?P[^\s]+)\s\->\s+(?P[^\s]+)\s+(?P(?:\d+\.\d+|\d+))\s(?P[^\s]+)"), # direct heal by source or n/a (global buff) re.compile(r"^Heal\s+(?:n/a|(?P\w+))\s+\->\s+(?P[^\s]+)\s+(?P(?:\d+\.\d+|\d+))"), # new heal with microtid @@ -147,11 +187,17 @@ class Heal(CombatLog): ] class Killed(CombatLog): + """ + Somebody or something is killed + 0: object, target_name, ship_class, killer + 1: object, target_name, killer + 2: object, killer + """ __slots__ = CombatLog.__slots__ matcher = [ - re.compile(r"^Killed\s(?P[^\s]+)\s+(?P\w+);\s+killer\s(?P[^\s]+)\s*"), - re.compile(r"^Killed\s(?P[^\(]+)\((?P\w+)\);\s+killer\s(?P[^\s]+)\s*"), - re.compile(r"^Killed\s(?P[^\;]+);\s+killer\s(?P[^\s]+)\s+.*"), + re.compile(r"^Killed\s(?P[^\s]+)\s+(?P\w+);\s+killer\s(?P[^\s]+)\s*"), + re.compile(r"^Killed\s(?P[^\(]+)\((?P\w+)\);\s+killer\s(?P[^\s]+)\s*"), + re.compile(r"^Killed\s(?P[^\;]+);\s+killer\s(?P[^\s]+)\s+.*"), ] class Captured(CombatLog): @@ -159,14 +205,25 @@ class Captured(CombatLog): matcher = re.compile(r"^Captured\s'(?P[^']+)'\(team\s(?P\d+)\)\.(?:\sAttackers\:(?P.*)|.*)") class AddStack(CombatLog): + """ A Stack is added to an aura, stack_count holds new stack + spell_name, id, type, stack_count + """ __slots__ = CombatLog.__slots__ matcher = re.compile(r"^AddStack\saura\s'(?P\w+)'\sid\s(?P\d+)\stype\s(?P\w+)\.\snew\sstacks\scount\s(?P\d+)") class Cancel(CombatLog): + """ + An Aura is cancelled, source_name holds the one canceling it. + spell_name, id, type, source_name + """ __slots__ = CombatLog.__slots__ matcher = re.compile(r"^Cancel\saura\s'(?P\w+)'\sid\s(?P\d+)\stype\s(?P\w+)\sfrom\s'(?P[^']*)'") class Scores(CombatLog): + """ + Scores are given. + team1_score, team2_score + """ __slots__ = CombatLog.__slots__ matcher = re.compile(r"^Scores\s+-\sTeam1\((?P(?:\d+|\d+\.\d+))\)\sTeam2\((?P(?:\d+|\d+\.\d+))\)") @@ -175,13 +232,52 @@ class Uncaptured(CombatLog): Variables: - objective (which was uncaptured (most likely something like VitalPointXY)) - team (number) - - attackers (split by space, names of the attackers, contains bots) + - attackers (split by space, names of the attackers, contains bots, optional) """ __slots__ = CombatLog.__slots__ matcher = re.compile(r"^Uncaptured\s'(?P[^']+)'\(team\s(?P\d+)\)\.(?:\sAttackers\:\s(?P.*)|)") + +class Respawn(CombatLog): + """ Respawn module - not really sure what it does + + logs: + Respawn module ModuleEngine_Race3_Huge_t3_Mk1|0000073187 + Respawn module ModuleCapacitor_race3_h_t3_capacitor_Mk1|0000077468 + Respawn module Module_Teleporter_T4_Epic(IAlexI)|0000000369 + Respawn module Module_AdaptiveBigShieldBoost_T4_Epic(IAlexI)|0000000370 + Respawn module Module_RocketSilo_T4_Epic(IAlexI)|0000000368 + """ + __slots__ = CombatLog.__slots__ + matcher = [ + # matching with name: + re.compile("^Respawn\smodule\s(?P\w+)\((?P\w+)\)\|(?P\d+)"), + # matching without: + re.compile("^Respawn\smodule\s(?P\w+)\|(?P\d+)"), + ] + +class Secondary(CombatLog): + """ + A secondary weapon was activated. + """ + __slots__ = CombatLog.__slots__ + matcher = re.compile("^Secondary\sweapon\sactivation\:\sentity\s(?P-*\d+),\sowner\s'(?P[^']+)',\sdef\s'(?P[^']+)'") + +class Teleporting(CombatLog): + """ + A teleport event. + """ + __slots__ = CombatLog.__slots__ + matcher = re.compile("^Teleporting\s(?P\d+)\sdef\s'(?P[^']+)'\sby\s(?P\d+)\sdef\s'(?P[^']+)',\sdistance\s(?P-*(?:\d+\.\d+|\d+)),\sduration\s(?P-*(?:\d+\.\d+|\d+))") # Special classes class GameEvent(CombatLog): + """ + GameEvents start with the big ===== + it can be select(_match_id): + 0: connect (game_session) + 1: start gameplay (gameplay_name, map_id, local_team) + 2: start pve mission (pve_name, map_id) + """ __slots__ = CombatLog.__slots__ matcher = [ # game session identifier. @@ -251,7 +347,7 @@ class Set(CombatLog): """ called on setting "relationship" / OpenSpace Variables in values: - - what (relationship) + - what (relationship): stage, reputation. Optionals: - name (who do i set?) @@ -294,7 +390,7 @@ class UserEvent(CombatLog): if log and 'earned medal' in log: return True elif log: - logging.debug('UserEvent saw unknown line:\n%s' % log) + logging.warning('UserEvent saw unknown line:\n%s' % log) return False # Action? @@ -302,6 +398,9 @@ COMBAT_LOGS = [ Apply, Damage, Spawn, Spell, Reward, Participant, Rocket, Heal, Gameplay, #? Scores, Killed, Captured, AddStack, Cancel, Uncaptured, + # + Teleporting, Secondary, Respawn, # added with ellydium. + # undone openspace: PVE_Mission, Looted, Set, Dropped, SqIdChange, Mailed, # unknown if these are important...