-
Notifications
You must be signed in to change notification settings - Fork 2
/
process_match_information.py
198 lines (173 loc) · 10.1 KB
/
process_match_information.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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import requests
import os
from dotenv import load_dotenv
import outputs
def main():
# Accept user input for the file name
tournament_name = input("Enter the tournament file name (Enter to use LCC_Season_2): ")
file_path = f"tournaments/{(tournament_name,'LCC_Season_2')[tournament_name == '']}.txt"
file_name = file_path.split("/")[-1].split(".")[0]
# Open the file and read the match IDs
with open(file_path, "r") as file:
match_ids = file.readlines()
if not match_ids:
print("No match IDs found in the file.")
return
processed_matches = []
# For each listed match, fetch and transform the data
for match_id in match_ids:
match_id = match_id.strip()
match_url = f"https://americas.api.riotgames.com/lol/match/v5/matches/NA1_{match_id}"
riot_match_data = fetch_riot_data(match_url)
processed_match = process_match_data(riot_match_data)
# Fetch and process timeline data
timeline_url = match_url + "/timeline"
riot_timeline_data = fetch_riot_data(timeline_url)
processed_timeline_data = process_timeline_data(riot_timeline_data)
position_data = get_position_data(riot_match_data["info"]["participants"])
for position, teams in position_data.items():
processed_timeline_data[teams[100]]["csd14"] = processed_timeline_data[teams[100]]["cs14"] - processed_timeline_data[teams[200]]["cs14"]
processed_timeline_data[teams[200]]["csd14"] = processed_timeline_data[teams[200]]["cs14"] - processed_timeline_data[teams[100]]["cs14"]
# Merge the timeline data with the match data
processed_match["participants"] = [dict(participant, **processed_timeline_data[participant["puuid"]]) for participant in processed_match["participants"]]
ordered_keys = ["puuid", "player", "champion", "role", "win", "gameLength", "champLevel", "kills", "deaths", "assists", "kda", "kp", "cs", "csm", "cs14", "csd14", "gold", "gpm", "dmg", "dpm", "teamDmg%", "dmgTakenTeam%", "firstBlood", "soloBolos", "tripleKills", "quadraKills", "pentaKills", "multikills", "visionScore", "vspm", "ccTime", "effectiveHealShield", "objectivesStolen"]
processed_match["participants"] = [{key: participant[key] for key in ordered_keys} for participant in processed_match["participants"]]
# Dump each processed match data to json file for future additional programmatic use
outputs.build_match_json(file_name, match_id, processed_match)
# Add to list for excel workbook
processed_matches.append(processed_match)
outputs.build_cumulative_reports(processed_matches, aggregate_player_season_data(processed_matches))
outputs.build_match_sheets(processed_matches)
outputs.build_player_sheets(processed_matches)
print("Excel workbook created successfully.")
def get_position_data(participants):
position_data = {
'TOP': {100: None, 200: None},
'JUNGLE': {100: None, 200: None},
'MIDDLE': {100: None, 200: None},
'BOTTOM': {100: None, 200: None},
'UTILITY': {100: None, 200: None},
}
for participant in participants:
position = participant['teamPosition']
team = participant['teamId']
puuid = participant['puuid']
if position in position_data and team in position_data[position]:
position_data[position][team] = puuid
return position_data
def aggregate_player_season_data(match_data):
player_data = {}
for match in match_data:
for participant in match["participants"]:
puuid = participant['puuid']
if puuid not in player_data:
player_data[puuid] = {
'riotIdGameName': participant['player'],
'matches': 0,
'game_minutes': 0,
'kills': 0,
'deaths': 0,
'assists': 0,
'kda': 0,
'dmg': 0,
'dpm': 0,
'cs': 0,
'csm': 0,
'totalCsd14': 0,
'avgCsd14': 0,
'first_blood': 0,
'solo_kills': 0
}
player_data[puuid]['matches'] += 1
player_data[puuid]['game_minutes'] += round(participant['gameLength'], 2)
player_data[puuid]['kills'] += participant['kills']
player_data[puuid]['deaths'] += participant['deaths']
player_data[puuid]['assists'] += participant['assists']
if player_data[puuid]['deaths'] == 0:
player_data[puuid]['kda'] = player_data[puuid]['kills'] + player_data[puuid]['assists']
else:
player_data[puuid]['kda'] = round((player_data[puuid]['kills'] + player_data[puuid]['assists']) / player_data[puuid]['deaths'], 2)
player_data[puuid]['dmg'] += participant['dmg']
player_data[puuid]['dpm'] = round(player_data[puuid]['dmg'] / player_data[puuid]['game_minutes'], 2)
player_data[puuid]['cs'] += participant['cs']
player_data[puuid]['csm'] = round(player_data[puuid]['cs'] / player_data[puuid]['game_minutes'], 2)
player_data[puuid]['totalCsd14'] += participant['csd14']
player_data[puuid]['first_blood'] += participant['firstBlood']
player_data[puuid]['solo_kills'] += participant['soloBolos']
for puuid, pdata in player_data.items():
pdata['avgCsd14'] = round(pdata['totalCsd14']/pdata["matches"], 1)
return player_data
def fetch_riot_data(url):
api_key = os.getenv("RIOT_API_KEY")
headers = {"X-Riot-Token": api_key}
response = requests.get(url, headers=headers)
if response.status_code != 200:
raise requests.exceptions.HTTPError(f"Failed to fetch match data: {response.text}")
return response.json()
def process_match_data(match_data):
match_information = {}
participant_information = []
match_information["game_id"] = match_data["metadata"]["matchId"]
for participant in match_data["info"]["participants"]:
participant_information.append(process_participant_data(participant))
match_information["participants"] = participant_information
return match_information
def process_timeline_data(timeline_data):
#Find 14 minute
for frame in timeline_data["info"]["frames"]:
#840000 is the millisecond timestamp for 14 minutes. Timestamps are not exact, so we need to check a range of timestamps
if frame["timestamp"] > 840000 and frame["timestamp"] < 850000:
minute_14 = frame["participantFrames"]
break
#Find Game participants
participant_data_dict = {}
for participant in timeline_data["info"]["participants"]:
puuid = participant["puuid"]
participant_id = participant["participantId"]
#Match participant data with 14 minute data
for pid, pdata in minute_14.items():
if str(pid) == str(participant_id):
participant_data_dict[puuid] = pdata
#Pull and aggregate data from timeline per participant
participants = {}
for puuid, pdata in participant_data_dict.items():
participant_data_14 = {}
participant_data_14["cs14"] = pdata["minionsKilled"] + pdata["jungleMinionsKilled"]
participants[puuid] = participant_data_14
return participants
def process_participant_data(participant_data):
participant_information = {}
participant_information["puuid"] = participant_data["puuid"]
participant_information["player"] = participant_data["riotIdGameName"]
participant_information["champion"] = participant_data["championName"]
participant_information["role"] = participant_data["teamPosition"]
participant_information["win"] = participant_data["win"]
participant_information["gameLength"] = round(participant_data["challenges"]["gameLength"]/60, 1)
participant_information["champLevel"] = participant_data["champLevel"]
participant_information["kills"] = participant_data["kills"]
participant_information["deaths"] = participant_data["deaths"]
participant_information["assists"] = participant_data["assists"]
participant_information["kda"] = round(participant_data["challenges"]["kda"], 2)
participant_information["kp"] = round(participant_data["challenges"]["killParticipation"], 2)
participant_information["cs"] = participant_data["totalMinionsKilled"] + participant_data["neutralMinionsKilled"]
participant_information["csm"] = round(participant_information["cs"]/participant_information["gameLength"], 2)
participant_information["gold"] = participant_data["goldEarned"]
participant_information["gpm"] = round(participant_data["challenges"]["goldPerMinute"],2)
participant_information["objectivesStolen"] = participant_data["objectivesStolen"]
participant_information["dmg"] = participant_data["totalDamageDealtToChampions"]
participant_information["dpm"] = round(participant_data["challenges"]["damagePerMinute"],2)
participant_information["teamDmg%"] = round(participant_data["challenges"]["teamDamagePercentage"]*100, 0)
participant_information["dmgTakenTeam%"] = round(participant_data["challenges"]["damageTakenOnTeamPercentage"]*100, 0 )
participant_information["firstBlood"] = participant_data["firstBloodKill"]
participant_information["soloBolos"] = participant_data["challenges"]["soloKills"]
participant_information["tripleKills"] = participant_data["tripleKills"]
participant_information["quadraKills"] = participant_data["quadraKills"]
participant_information["pentaKills"] = participant_data["pentaKills"]
participant_information["multikills"] = participant_data["challenges"]["multikills"]
participant_information["visionScore"] = participant_data["visionScore"]
participant_information["vspm"] = round(participant_data["challenges"]["visionScorePerMinute"],2)
participant_information["ccTime"] = participant_data["totalTimeCCDealt"]
participant_information["effectiveHealShield"] = round(participant_data["challenges"]["effectiveHealAndShielding"],0)
return participant_information
load_dotenv(dotenv_path=".env", verbose=True, override=True)
main()