Git repository creation. Added initial files
This commit is contained in:
parent
1236824d92
commit
d1990aa41f
3
README
Executable file
3
README
Executable file
@ -0,0 +1,3 @@
|
||||
Swtor combat log parser (work in progress)
|
||||
|
||||
To use: parser.py filename
|
147
parser.py
Executable file
147
parser.py
Executable file
@ -0,0 +1,147 @@
|
||||
# Danial Afzal
|
||||
# iotasquared@gmail.com
|
||||
import os
|
||||
import re
|
||||
from datetime import datetime
|
||||
import sys
|
||||
#[03/16/2012 22:53:45] [@Asdffljklasdfj] [@Asdffljklasdfj] [Unnatural Might {1781509484707840}] [RemoveEffect {836045448945478}: Unnatural Might {1781509484707840}] ()
|
||||
#[date] [src] [target] [ability] [effect] (value) <threat>
|
||||
#src = [foo {id}] or [@player]
|
||||
# ability = abil {id}
|
||||
# effect = type:effect
|
||||
# value = # or # type
|
||||
# roll? int
|
||||
class Event:
|
||||
regex = r'[\[<\(]([^\[<\(\]>\)]*)[\]>\)]'
|
||||
def __init__(self, x):
|
||||
#print x
|
||||
data = re.findall(Event.regex, x)
|
||||
data.append('')
|
||||
self.to_string = ' '.join(data)
|
||||
|
||||
date = datetime.strptime(data[0], '%m/%d/%Y %H:%M:%S')
|
||||
self.date = date
|
||||
self.source = Entity(data[1])
|
||||
self.target = Entity(data[2])
|
||||
self.ability = Ability(data[3])
|
||||
self.effect = Effect(data[4])
|
||||
self.value = Value(data[5])
|
||||
self.threat = Threat(data[6])
|
||||
|
||||
class Entity:
|
||||
def __init__(self, x):
|
||||
if not x:
|
||||
self.name = x
|
||||
self.player = False
|
||||
elif x[0] == '@':
|
||||
self.name = x[1:]
|
||||
self.player = True
|
||||
else:
|
||||
self.name = x
|
||||
self.player = False
|
||||
|
||||
class Ability:
|
||||
def __init__(self, x):
|
||||
self.name = x
|
||||
|
||||
class Effect:
|
||||
def __init__(self, x):
|
||||
if not x:
|
||||
self.type = ''
|
||||
self.detail = ''
|
||||
return
|
||||
foo = x.split(':')
|
||||
if len(foo) > 1:
|
||||
self.type = foo[0]
|
||||
self.detail = foo[1]
|
||||
else:
|
||||
self.type = x
|
||||
self.detail = ''
|
||||
|
||||
class Value:
|
||||
def __init__(self, x):
|
||||
if not x:
|
||||
self.value = 0
|
||||
self.type = ''
|
||||
return
|
||||
foo = x.replace('*','').split(' ')
|
||||
self.value = int(foo[0])
|
||||
if len(foo) > 1:
|
||||
self.type = foo[1]
|
||||
else:
|
||||
self.type=''
|
||||
|
||||
class Threat:
|
||||
def __init__(self, x):
|
||||
if not x:
|
||||
self.value = 0
|
||||
self.type = ''
|
||||
return
|
||||
foo = x.replace('*','').split(' ')
|
||||
self.value = int(foo[0])
|
||||
if len(foo) > 1:
|
||||
self.type = foo[1]
|
||||
else:
|
||||
self.type=''
|
||||
|
||||
#date, source, target, ability, effect.type/detail, value.value/type, threat
|
||||
# TODO:
|
||||
# multiple sources
|
||||
# more interesting output, graphs? What about that metric site? Google charts?
|
||||
# App engine seems fun
|
||||
# Details for abilities:
|
||||
# dmg per ability
|
||||
# Combine multiple entries per ability
|
||||
def main():
|
||||
if len(sys.argv) == 1:
|
||||
filename = 'argorash.txt'
|
||||
print 'File not specified, defaulting to ' + filename
|
||||
else:
|
||||
filename = sys.argv[1]
|
||||
file = open(filename, 'r')
|
||||
events = []
|
||||
for line in file.readlines():
|
||||
events.append(Event(line))
|
||||
|
||||
players = set([event.source.name for event in events])
|
||||
fights = []
|
||||
fight = []
|
||||
for event in events:
|
||||
if 'EnterCombat' in event.effect.detail:
|
||||
fight = []
|
||||
if 'ExitCombat' in event.effect.detail:
|
||||
fight.append(event)
|
||||
fights.append(fight)
|
||||
fight = []
|
||||
continue
|
||||
fight.append(event)
|
||||
|
||||
for i, fight in enumerate(fights):
|
||||
duration = fight[-1].date - fight[0].date
|
||||
print '\nCombat Statistics for Fight # %d (duration: %s)' %(i+1, str(duration))
|
||||
print str(fight[0].date) +" -> " + str(fight[-1].date)
|
||||
for player in players:
|
||||
dmg = 0
|
||||
heal = 0
|
||||
threat = 0
|
||||
for event in fight:
|
||||
if event.source.name == player and 'Damage ' in event.effect.detail:
|
||||
dmg += event.value.value
|
||||
if event.source.name == player and event.threat.value:
|
||||
threat += event.threat.value
|
||||
if event.source.name == player and 'Heal ' in event.effect.detail:
|
||||
heal += event.value.value
|
||||
secs = duration.seconds
|
||||
if not secs:
|
||||
secs = 1
|
||||
if dmg:
|
||||
print '%s did %d damage in %s (%d DPS)' % (player, dmg, str(duration), dmg/secs)
|
||||
if heal:
|
||||
print '%s did %d heals in %s (%d HPS)' % (player, heal, str(duration), heal/secs)
|
||||
if threat:
|
||||
print '%s did %d threat in %s (%d TPS)' % (player, threat, str(duration), threat/secs)
|
||||
|
||||
|
||||
#print "\n".join([event.to_string for event in events])
|
||||
if __name__ == "__main__":
|
||||
main()
|
4
setup.py
Executable file
4
setup.py
Executable file
@ -0,0 +1,4 @@
|
||||
from distutils.core import setup
|
||||
import py2exe
|
||||
|
||||
setup(console=['parser.py'])
|
171
swtor-parser.php
Executable file
171
swtor-parser.php
Executable file
@ -0,0 +1,171 @@
|
||||
#!/usr/bin/php
|
||||
|
||||
<?php
|
||||
|
||||
$listEncounters = array(
|
||||
## The Dread Fortress
|
||||
'Nefra, Who Bars the Way {3266533082005504}','Gate Commander Draxus {3273924720721920}','Grob\'thok, Who Feeds the Forge {3273929015689216}','Corruptor Zero {3273933310656512}','Dread Master Brontes {3273937605623808}',
|
||||
## Eternity Vault
|
||||
'Soa {2289823159156736}',
|
||||
## Assation
|
||||
'The Writhing Horror {2938874321960960}','Heirad {2938002443599872}','Ciphas {2938011033534464}','Kel\'sara {2938006738567168}','Operator IX {2942606648541184}','Kephess the Undying {2937620191510528}','The Terror From Beyond {2978340776443904}',
|
||||
##
|
||||
'The Eyeless {3328380611067904}',
|
||||
## Toborro
|
||||
'Golden Fury {3232800408862720}', 'Golden Fury {3232817588731904}',
|
||||
## The False Emperor
|
||||
'Tregg the Destroyer {1690314444111872}','Jindo Krey {770959514533888}','HK-47 {770955219566592}','Chondrus Berani {1690331623981056}','Sith Entity {1695962326106112}','Forsaken Sith Lord {781830076760064}','Darth Malgus {770963809501184}',
|
||||
## Battle of Rishi
|
||||
'Marko Ka {3533564083699712}','Rarrook {3533559788732416}','Lord Vodd {3533585558536192}','Shield Squadron Unit 1 {3533594148470784}','Darth Yun {4257506591244288}',
|
||||
## Objective Meridian
|
||||
'Commander Aster {4258021987319808}','Darth Malgus {4257502296276992}',
|
||||
## Heart of Ruin
|
||||
'Colossal Monolith {3541140406009856}',
|
||||
##
|
||||
'Toxxun {3340011382505472}',
|
||||
## Mutated Geonosian Queen
|
||||
'Mutated Geonosian Queen {4197299739688960}'
|
||||
);
|
||||
|
||||
$dmgTypes = array('energy','elemental','kinetic','internal');
|
||||
$instTypes = array('Story','Veteran','Master');
|
||||
$zoneNames = array(
|
||||
# Planet zones
|
||||
'Corellia','Coruscant','CZ-198','Rishi','Taris','Tatooine','Voss','Yavin 4','Ziost',
|
||||
# Instances zones
|
||||
'Lair of the Eyeless','Toborro\'s Palace Courtyard','The False Emperor','Battle of Rishi','Objective Meridian','Hive of the Mountain Queen'
|
||||
);
|
||||
|
||||
class loadFile
|
||||
{
|
||||
// Declare properties
|
||||
public $filename = "";
|
||||
public $handle = null;
|
||||
|
||||
// Constructor
|
||||
public function __construct(){
|
||||
// echo 'The class "' . __CLASS__ . '" was initiated!<br>';
|
||||
$this->fileName = "";
|
||||
$this->handle = null;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
public function __destruct(){
|
||||
// echo 'The class "' . __CLASS__ . '" was destroyed.<br>';
|
||||
}
|
||||
|
||||
// Method to get the filename
|
||||
public function getFileName(){
|
||||
return $this->fileName;
|
||||
}
|
||||
|
||||
// Method to set the filename
|
||||
public function setFileName($filename){
|
||||
$this->fileName = $filename;
|
||||
}
|
||||
|
||||
// Method to get the handle content
|
||||
public function getHandle(){
|
||||
// TODO Check file exists
|
||||
$this->handle = fopen($this->fileName, "r");
|
||||
// if($this->handle) {
|
||||
// while (($line = fgets($this->handle)) !== false) {
|
||||
// echo $line;
|
||||
// }
|
||||
// fclose($this->handle);
|
||||
// } else {
|
||||
// $this->handle = False;
|
||||
// }
|
||||
|
||||
return $this->handle;
|
||||
}
|
||||
}
|
||||
|
||||
// class Event:
|
||||
// regex = r'[\[<\(]([^\[<\(\]>\)]*)[\]>\)]'
|
||||
// def __init__(self, x):
|
||||
// data = re.findall(Event.regex, x)
|
||||
// data.append('')
|
||||
// self.to_string = ' '.join(data)
|
||||
//
|
||||
// dateandtime = datetime.strptime(list(sys.argv[1].split("_"))[1]+" "+data[0], '%Y-%m-%d %H:%M:%S.%f')
|
||||
//
|
||||
// self.date = dateandtime
|
||||
// self.source = Entity(data[1])
|
||||
// self.target = Entity(data[2])
|
||||
// self.ability = Ability(data[3])
|
||||
// self.effect = Effect(data[4])
|
||||
// self.value = Value(data[5])
|
||||
// self.threat = Threat(data[6])
|
||||
|
||||
class LogEvent
|
||||
{
|
||||
// Properties declaration
|
||||
public $event = "";
|
||||
// public $date = "";
|
||||
// public $source = "";
|
||||
// public $target = "";
|
||||
// public $ability = "";
|
||||
// public $effect = "";
|
||||
// public $value = 0;
|
||||
// public $threat = 0;
|
||||
|
||||
// Constructor
|
||||
public function __construct()
|
||||
{
|
||||
// echo 'The class "' . __CLASS__ . '" was initiated!<br>';
|
||||
$this->event = "";
|
||||
// $this->date = $date;
|
||||
// $this->source = $source;
|
||||
// $this->target = $target;
|
||||
// $this->ability = $ability;
|
||||
// $this->effect = $effect;
|
||||
// $this->value = $value;
|
||||
// $this->threat = $threat;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
public function __destruct(){
|
||||
// echo 'The class "' . __CLASS__ . '" was destroyed.<br>';
|
||||
}
|
||||
|
||||
// Method to set the event
|
||||
public function arrayEvent($logEvent){
|
||||
// [23:40:42.150] [@Comendatore] [Combat Training Target MK-10 {2816257300627456}:133000004817] [Ion Pulse {2199843594305536}] [ApplyEffect {836045448945477}: Damage {836045448945501}] (7659* elemental {836045448940875}) <19146>
|
||||
// [date] [src] [target] [ability] [effect] (value) <threat>
|
||||
$isMatching = preg_match_all('/[\[<\(]([^\[<\(\]>\)]*)[\]>\)]/m', $logEvent, $this->event, PREG_SET_ORDER, 0);
|
||||
return $this->event;
|
||||
}
|
||||
}
|
||||
|
||||
// $handle = fopen("combat_2020-06-11_18_06_42_493608.txt", "r");
|
||||
$handlecontent = new loadFile;
|
||||
$handlecontent->setFileName("combat_2020-07-25_22_39_58_532658.txt");
|
||||
$handleresult = $handlecontent->getHandle();
|
||||
|
||||
if($handleresult) {
|
||||
$totalAmount=0;$totalThreat=0;
|
||||
while (($line = fgets($handleresult)) !== false) {
|
||||
$log = new LogEvent;
|
||||
$log = $log->arrayEvent($line);
|
||||
if( array_key_exists(6, $log) );
|
||||
// print_r($log);
|
||||
$logDate = $log[0][1];
|
||||
$logSource = $log[1][1];
|
||||
$logTarget = $log[2][1];
|
||||
$logAbility = $log[3][1];
|
||||
$logEffect = $log[4][1];
|
||||
$logValue = (isset($log[5][1]) && ($log[5][1] != 0))?$log[5][1]:null;
|
||||
$logThreat = isset($log[6][1])?$log[6][1]:null;
|
||||
print("Date : ".$logDate." Source : ".$logSource." Target : ".$logTarget." Ability : ".$logAbility." Effect : ".$logEffect." Amount : ".$logValue." Menace : ".$logThreat."\n");
|
||||
|
||||
// if( $log[1][1]
|
||||
|
||||
$totalAmount+=$logValue;$totalThreat+=$logThreat;
|
||||
}
|
||||
print("Total Damages : ".$totalAmount."\n");
|
||||
print("Total Menace : ".$totalThreat."\n");
|
||||
} else {
|
||||
echo "Error while loading file handle !";
|
||||
}
|
||||
?>
|
318
swtor-parser.py
Executable file
318
swtor-parser.py
Executable file
@ -0,0 +1,318 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os, re, sys
|
||||
from time import strftime
|
||||
from datetime import datetime
|
||||
|
||||
#import matplotlib.pyplot as plt
|
||||
|
||||
## Declaring the points for first line plot
|
||||
#X1 = [1,2,3,4,5]
|
||||
#Y1 = [2,4,6,8,10]
|
||||
|
||||
## Setting the figure size
|
||||
#fig = plt.figure(figsize=(10,5))
|
||||
|
||||
## plotting the first plot
|
||||
#plt.plot(X1, Y1, label = "plot 1")
|
||||
|
||||
## Declaring the points for second line plot
|
||||
#X2 = [1,2,3,4,5]
|
||||
#Y2 = [1,4,9,16,25]
|
||||
|
||||
## plotting the second plot
|
||||
#plt.plot(X2, Y2, label = "plot 2")
|
||||
|
||||
## Labeling the X-axis
|
||||
#plt.xlabel('X-axis')
|
||||
|
||||
## Labeling the Y-axis
|
||||
#plt.ylabel('Y-axis')
|
||||
|
||||
## Give a title to the graph
|
||||
#plt.title('Two plots on the same graph')
|
||||
|
||||
## Show a legend on the plot
|
||||
#plt.legend()
|
||||
|
||||
##Saving the plot as an image
|
||||
#fig.savefig('line plot.png', bbox_inches='tight', dpi=150)
|
||||
|
||||
##Showing the plot
|
||||
#plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
# [03/16/2012 22:53:45] [@Asdffljklasdfj] [@Asdffljklasdfj] [Unnatural Might {1781509484707840}] [RemoveEffect {836045448945478}: Unnatural Might {1781509484707840}] ()
|
||||
# [21:18:16.172] [@Comendatore] [@Comendatore] [] [Event {836045448945472}: EnterCombat {836045448945489}] (Asation (8 Player Story))
|
||||
#[date] [src] [target] [ability] [effect] (value) <threat>
|
||||
#src = [foo {id}] or [@player]
|
||||
# ability = abil {id}
|
||||
# effect = type:effect
|
||||
# value = # or # type
|
||||
# roll? int
|
||||
|
||||
listEncounters = [
|
||||
## The Dread Fortress
|
||||
'Nefra, Who Bars the Way {3266533082005504}','Gate Commander Draxus {3273924720721920}','Grob\'thok, Who Feeds the Forge {3273929015689216}','Corruptor Zero {3273933310656512}','Dread Master Brontes {3273937605623808}',
|
||||
## Eternity Vault
|
||||
'Soa {2289823159156736}',
|
||||
##
|
||||
'The Writhing Horror {2938874321960960}','Heirad {2938002443599872}','Ciphas {2938011033534464}','Kel\'sara {2938006738567168}','Operator IX {2942606648541184}','Kephess the Undying {2937620191510528}','The Terror From Beyond {2978340776443904}','The Terror From Beyond {3025233229381632}',
|
||||
##
|
||||
'The Eyeless {3328380611067904}','Golden Fury {3232800408862720}','Golden Fury {3232817588731904}',
|
||||
## The False Emperor
|
||||
'Tregg the Destroyer {1690314444111872}','Jindo Krey {770959514533888}','HK-47 {770955219566592}','Chondrus Berani {1690331623981056}','Sith Entity {1695962326106112}','Forsaken Sith Lord {781830076760064}','Darth Malgus {770963809501184}',
|
||||
## Battle of Rishi
|
||||
'Marko Ka {3533564083699712}','Rarrook {3533559788732416}','Lord Vodd {3533585558536192}','Shield Squadron Unit 1 {3533594148470784}','Darth Yun {4257506591244288}',
|
||||
## Objective Meridian
|
||||
'Commander Aster {4258021987319808}','Darth Malgus {4257502296276992}',
|
||||
## Heart of Ruin
|
||||
'Colossal Monolith {3541140406009856}',
|
||||
##
|
||||
'Toxxun {3340011382505472}',
|
||||
## Mutated Geonosian Queen
|
||||
'Mutated Geonosian Queen {4197299739688960}',
|
||||
##
|
||||
'SCYVA {4108140513591296}'
|
||||
]
|
||||
|
||||
dmgTypes = ['energy','elemental','kinetic','internal']
|
||||
instTypes = ['Story','Veteran','Master']
|
||||
zoneNames = [
|
||||
# Planet zones
|
||||
'Corellia','Coruscant','CZ-198','Rishi','Taris','Tatooine','Voss','Yavin 4','Ziost',
|
||||
# Instances zones
|
||||
'Asation','Lair of the Eyeless','Toborro\'s Palace Courtyard','The False Emperor','Battle of Rishi','Objective Meridian','Hive of the Mountain Queen',
|
||||
# Operations Zones
|
||||
'Valley of the Machine Gods'
|
||||
]
|
||||
|
||||
class Event:
|
||||
regex = r'[\[<\(]([^\[<\(\]>\)]*)[\]>\)]'
|
||||
def __init__(self, x):
|
||||
data = re.findall(Event.regex, x)
|
||||
data.append('')
|
||||
self.to_string = ' '.join(data)
|
||||
|
||||
dateandtime = datetime.strptime(list(sys.argv[1].split("_"))[1]+" "+data[0], '%Y-%m-%d %H:%M:%S.%f')
|
||||
|
||||
self.date = dateandtime
|
||||
self.source = Entity(data[1])
|
||||
self.target = Entity(data[2])
|
||||
self.ability = Ability(data[3])
|
||||
self.effect = Effect(data[4])
|
||||
self.value = Value(data[5])
|
||||
self.threat = Threat(data[6])
|
||||
|
||||
class Entity:
|
||||
def __init__(self, x):
|
||||
if not x:
|
||||
self.name = x
|
||||
self.player = False
|
||||
#print(x+" is not a player !")
|
||||
elif x[0] == '@':
|
||||
self.name = x[1:]
|
||||
self.player = True
|
||||
#print(x+" is a player !")
|
||||
else:
|
||||
self.name = x
|
||||
self.player = False
|
||||
#print(x+" is not a player !")
|
||||
|
||||
class Ability:
|
||||
def __init__(self, x):
|
||||
self.name = x
|
||||
|
||||
class Effect:
|
||||
def __init__(self, x):
|
||||
if not x:
|
||||
self.type = ''
|
||||
self.detail = ''
|
||||
return
|
||||
foo = x.split(':')
|
||||
if len(foo) > 1:
|
||||
self.type = foo[0]
|
||||
self.detail = foo[1]
|
||||
else:
|
||||
self.type = x
|
||||
self.detail = ''
|
||||
|
||||
#class Value:
|
||||
#def __init__(self, x):
|
||||
#if not x:
|
||||
#self.value = 0
|
||||
#self.type = ''
|
||||
#return
|
||||
#foo = x.replace('*','').split(' ')
|
||||
#self.value = int(foo[0])
|
||||
#if len(foo) > 1:
|
||||
#self.type = foo[1]
|
||||
#else:
|
||||
#self.type=''
|
||||
|
||||
# [20:06:53.053] [@Comendatore] [@Comendatore] [] [Event {836045448945472}: EnterCombat {836045448945489}] (Ziost)
|
||||
# [21:31:45.974] [@Comendatore] [@Comendatore] [] [Event {836045448945472}: EnterCombat {836045448945489}] (Hive of the Mountain Queen (8 Player Story))
|
||||
# [21:32:18.105] [@Bidobulle] [@Comendatore] [Slow-release Medpac {3406415871868928}] [ApplyEffect {836045448945477}: Heal {836045448945500}] (5683*)
|
||||
# [21:32:19.499] [@Bidobulle] [@Comendatore] [Slow-release Medpac {3406415871868928}] [ApplyEffect {836045448945477}: Heal {836045448945500}] (3641)
|
||||
# [22:37:11.036] [@Comendatore] [Colossal Monolith {3541140406009856}:15814000004760] [Shocked {2044520397013249}] [ApplyEffect {836045448945477}: Damage {836045448945501}] (165 energy {836045448940874}) <1646>
|
||||
# [22:37:46.168] [@Comendatore] [Colossal Monolith {3541140406009856}:15814000004760] [Ion Storm {3389987621961728}] [ApplyEffect {836045448945477}: Damage {836045448945501}] (20879* elemental {836045448940875}) <52197>
|
||||
# [22:37:51.623] [Colossal Monolith {3541140406009856}:15814000004760] [@Comendatore] [Great Slam {3543287889657856}] [ApplyEffect {836045448945477}: Damage {836045448945501}] (86 kinetic {836045448940873} -shield {836045448945509} (86 absorbed {836045448945511})) <86>
|
||||
# [22:38:30.231] [Colossal Monolith {3541140406009856}:15814000004760] [@Comendatore] [Bleeding {3546045258662192}] [ApplyEffect {836045448945477}: Damage {836045448945501}] (10668 internal {836045448940876}) <10668>
|
||||
|
||||
class Value:
|
||||
def __init__(self, x):
|
||||
if not x:
|
||||
self.value = 0
|
||||
self.type = ''
|
||||
return
|
||||
foo = x.replace('*','')
|
||||
#print(foo)
|
||||
#if not re.search('[a-zA-Z]+', x):
|
||||
#print(foo)
|
||||
if any(z in foo for z in dmgTypes) and not any(y in foo for y in instTypes) or not any(w in foo for w in zoneNames) or foo.isdigit():
|
||||
foo = x.replace('*','').split(' ')
|
||||
if foo[0].isdigit():
|
||||
self.value = int(foo[0])
|
||||
else:
|
||||
self.value = 0
|
||||
if len(foo) > 1:
|
||||
self.type = foo[1]
|
||||
else:
|
||||
self.type=''
|
||||
else:
|
||||
#print(foo)
|
||||
self.type = ''
|
||||
|
||||
class Threat:
|
||||
def __init__(self, x):
|
||||
if not x:
|
||||
self.value = 0
|
||||
self.type = ''
|
||||
return
|
||||
foo = x.replace('*','').split(' ')
|
||||
self.value = int(foo[0])
|
||||
if len(foo) > 1:
|
||||
self.type = foo[1]
|
||||
else:
|
||||
self.type=''
|
||||
|
||||
#date, source, target, ability, effect.type/detail, value.value/type, threat
|
||||
# TODO:
|
||||
# multiple sources
|
||||
# more interesting output, graphs? What about that metric site? Google charts?
|
||||
# App engine seems fun
|
||||
# Details for abilities:
|
||||
# dmg per ability
|
||||
# Combine multiple entries per ability
|
||||
def main():
|
||||
if len(sys.argv) == 1:
|
||||
filename = 'combat_2020-07-25_22_39_58_532658.txt'
|
||||
print('File not specified, defaulting to ' + filename)
|
||||
else:
|
||||
filename = sys.argv[1]
|
||||
file = open(filename, 'r')
|
||||
events = []
|
||||
for line in file.readlines():
|
||||
events.append(Event(line))
|
||||
|
||||
players = set([event.source.name for event in events])
|
||||
fights = []
|
||||
isBoss = False
|
||||
fight = []
|
||||
for event in events:
|
||||
if 'EnterCombat' in event.effect.detail:
|
||||
fight = []
|
||||
#fight.extend(fight)
|
||||
#isBoss = False
|
||||
|
||||
if 'Death' in event.effect.detail:
|
||||
#print(event.effect.detail)
|
||||
#if any(t in event.target.name for t in listEncounters):
|
||||
fight.append(event)
|
||||
#print(listEncounters)
|
||||
#isBoss = False
|
||||
for event in fight:
|
||||
##print(event.source.name)
|
||||
if any(t in event.target.name for t in listEncounters):
|
||||
isBoss = True
|
||||
if isBoss:
|
||||
fights.append(fight)
|
||||
fight = []
|
||||
continue
|
||||
|
||||
if 'ExitCombat' in event.effect.detail:
|
||||
#if any(t in event.effect.detail for t in ['ExitCombat','Death']):
|
||||
fight.append(event)
|
||||
#print(listEncounters)
|
||||
isBoss = False
|
||||
for event in fight:
|
||||
#print(event.source.name)
|
||||
if any(t in event.target.name for t in listEncounters):
|
||||
isBoss = True
|
||||
if isBoss:
|
||||
fights.append(fight)
|
||||
fight = []
|
||||
continue
|
||||
|
||||
fight.append(event)
|
||||
|
||||
for i, fight in enumerate(fights):
|
||||
duration = fight[-1].date - fight[0].date
|
||||
for event in fight:
|
||||
if any(t in event.target.name for t in listEncounters):
|
||||
namedTarget = event.target.name.split(' {')
|
||||
namedTarget = namedTarget[0]
|
||||
#print('\nCombat Statistics for Fight # %d (duration: %s)' %(i+1, str(duration)))
|
||||
print('\nCombat Statistics for Fight #%d -> %s (%s)' %(i+1, namedTarget, str(duration)))
|
||||
print("Started: " + str(fight[0].date) +" Ended: " + str(fight[-1].date))
|
||||
for player in players:
|
||||
if '{' not in player:
|
||||
dmg = 0
|
||||
tdmg = 0
|
||||
heal = 0
|
||||
theal = 0
|
||||
threat = 0
|
||||
death = False
|
||||
for event in fight:
|
||||
## Domages done by player (DPS)
|
||||
if event.source.name == player and 'Damage ' in event.effect.detail:
|
||||
dmg += event.value.value
|
||||
## Domages taken by player (DTPS)
|
||||
if event.target.name == player and 'Damage ' in event.effect.detail:
|
||||
tdmg += event.value.value
|
||||
## Heal done by player (HPS)
|
||||
if event.source.name == player and 'Heal ' in event.effect.detail:
|
||||
heal += event.value.value
|
||||
## Heal received by player (HTPS)
|
||||
if event.target.name == player and 'Heal ' in event.effect.detail:
|
||||
theal += event.value.value
|
||||
## Generated threat by player (TPS)
|
||||
if event.source.name == player and event.threat.value:
|
||||
threat += event.threat.value
|
||||
## Dead
|
||||
if event.source.name == player and 'Death' in event.effect.detail:
|
||||
death = True
|
||||
|
||||
secs = duration.seconds
|
||||
|
||||
if not secs:
|
||||
secs = 1
|
||||
if dmg:
|
||||
print('%s did %d damage in %s (%d DPS)' % (player, dmg, str(duration), dmg/secs))
|
||||
if tdmg:
|
||||
print('%s took %d damage in %s (%d DTPS)' % (player, tdmg, str(duration), tdmg/secs))
|
||||
if heal:
|
||||
print('%s did %d heals in %s (%d HPS)' % (player, heal, str(duration), heal/secs))
|
||||
if theal:
|
||||
print('%s received %d heals in %s (%d HTPS)' % (player, theal, str(duration), theal/secs))
|
||||
if threat:
|
||||
print('%s did %d threat in %s (%d TPS)' % (player, threat, str(duration), threat/secs))
|
||||
if death:
|
||||
print('%s died on %s' % (player, namedTarget))
|
||||
|
||||
|
||||
#print("\n".join([event.to_string for event in events]))
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user