forked from Ridepad/uwu-logs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogs_top.py
158 lines (133 loc) · 5.26 KB
/
logs_top.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import os
from collections import defaultdict
from time import perf_counter
import file_functions
import logs_main
from constants import LOGGER_REPORTS, TOP_FILE_NAME, get_ms_str, running_time
from logs_spell_info import AURAS_BOSS_MECHANICS, AURAS_CONSUME, AURAS_EXTERNAL, MULTISPELLS_D
try:
import _validate
except ImportError:
_validate = None
Z_SPELLS = [AURAS_EXTERNAL, AURAS_CONSUME, AURAS_BOSS_MECHANICS]
HUNGER_FOR_BLOOD = "63848"
FOCUS_MAGIC = "54646"
BATTLE_SQUAWK = "23060"
SPECS_NO_USE_FOR_CHICKEN = {*range(12, 16), *range(20, 24), 29, 31, 33, 35}
def f_auras(auras: dict[str, tuple[int, float]], spec: int):
if HUNGER_FOR_BLOOD in auras and spec == 25:
del auras[HUNGER_FOR_BLOOD]
if FOCUS_MAGIC in auras and spec in range(12, 16):
del auras[FOCUS_MAGIC]
if BATTLE_SQUAWK in auras and spec in SPECS_NO_USE_FOR_CHICKEN:
del auras[BATTLE_SQUAWK]
zz: dict[str, list[int, float, int]] = {}
for spell_id, (count, uptime) in auras.items():
spell_id = MULTISPELLS_D.get(spell_id, spell_id)
for n, auras_dict in enumerate(Z_SPELLS):
if spell_id not in auras_dict:
continue
uptime = round(uptime*100, 1)
if spell_id in zz:
count += zz[spell_id][0]
uptime += zz[spell_id][1]
zz[spell_id] = [count, uptime, n]
break
return [
[int(spell_id), *spell_data]
for spell_id, spell_data in zz.items()
]
def find_kill(segments):
for segment_info in segments:
if segment_info['attempt_type'] == 'kill' and segment_info['diff'] != "TBD":
yield segment_info
class Top(logs_main.THE_LOGS):
def make_report_top(self, rewrite=False):
top_path = self.relative_path(TOP_FILE_NAME)
if not rewrite and os.path.isfile(top_path):
return
pc = perf_counter()
q = _validate and _validate.pure_dog_water(self)
if q:
LOGGER_REPORTS.debug(f'{get_ms_str(pc)} | {self.NAME:50} | Dog water | {q}')
return
report_top = defaultdict(dict)
for boss_name, boss_segments in self.SEGMENTS.items():
for kill_segment in find_kill(boss_segments):
diff = kill_segment['diff']
s = kill_segment["start"]
f = kill_segment["end"]
report_top[boss_name][diff] = self.make_boss_top(s, f, boss_name)
file_functions.json_write(top_path, report_top, indent=None)
LOGGER_REPORTS.debug(f'{get_ms_str(pc)} | {self.NAME:50} | Done top')
return report_top
def get_vali_heal(self, s, f):
data = defaultdict(lambda: defaultdict(int))
for line in self.LOGS[s:f]:
if "_H" not in line:
continue
_line = line.split(',', 11)
data[_line[4]][_line[2]] += int(_line[9]) - int(_line[10])
return data
def get_vali_heal_wrap(self, s, f):
vali_data = self.get_vali_heal(s, f)
_useful = defaultdict(int)
_total = defaultdict(int)
for tguid, sources in vali_data.items():
# totems worked until ~21-12-20
# if tguid[5:12] == "0008FB5":
# for sguid, v in sources.items():
# dmg_useful[_sguid] += v
if tguid[5:12] == "0008FB5":
_useful = sources
for sguid, v in sources.items():
_sguid = self.get_master_guid(sguid)
_total[_sguid] += v
return {
"useful_total": _useful,
"damage_total": _total,
}
@running_time
def make_boss_top(self, s, f, boss_name: str):
def is_player(guid):
if guid in PLAYERS:
return True
# LOGGER_REPORTS.error(f"{report.NAME} {boss_name} Missing player {report.guid_to_name(guid)}")
PLAYERS = self.get_players_guids()
SPECS = self.get_players_specs_in_segments(s, f)
DURATION = self.get_slice_duration(s, f)
AURAS = self.auras_info(s, f)
if boss_name == "Valithria Dreamwalker":
_data = self.get_vali_heal_wrap(s, f)
else:
_damage = self.target_damage(s, f)
_total = _damage["total"]
_no_overkill = _damage["no_overkill"]
_specific = self.target_damage_specific(s, f, boss_name)
_data = self.target_damage_combine(_total, _no_overkill, _specific)
all_total = _data["damage_total"]
all_useful = _data["useful_total"]
return [
{
'r': self.NAME,
't': DURATION,
'i': guid[-7:],
'n': PLAYERS[guid],
'u': useful,
'd': all_total[guid],
's': SPECS[guid],
'a': f_auras(AURAS[guid], SPECS[guid])
}
for guid, useful in all_useful.items()
if is_player(guid)
]
def make_report_top_wrap(report_name, rewrite=False):
try:
t = Top(report_name)
return t.make_report_top(rewrite=rewrite)
except Exception:
LOGGER_REPORTS.exception(report_name)
def _test1():
make_report_top_wrap("24-02-09--20-49--Meownya--Lordaeron", rewrite=True)
if __name__ == "__main__":
_test1()