class HighlightFinder(object): def __init__(self, filename): self.filename = filename self.demo = DemoDump() self.players = {} self.current_round = 0 self.highlights = [] def parse(self): if self.demo.open(filename): print "Beginning parsing" self.demo.register_on_gameevent(7, self.player_connected) self.demo.register_on_gameevent(8, self.player_connected) self.demo.register_on_gameevent(9, self.player_disconnected) self.demo.register_on_gameevent(21, self.player_join_team) self.demo.register_on_gameevent(27, self.player_spawn) self.demo.register_on_gameevent(40, self.game_start) # only start counting when warmup is over self.demo.dump() else: print "Demo unparsable" pass def player_connected(self, data): if data.userid not in self.players.keys(): self.players[data.userid] = Player(data.index, data.name, data.userid, data.networkid) self.players[data.userid].is_connected = True print "New player %i" % data.userid def player_disconnected(self, data): if data.networkid == 'BOT': # if bot, just remove self.players.pop(data.userid, None) else: self.players[data.userid].is_connected = False def player_join_team(self, data): if data.team == 0: # disconnect? return print "%i joined team %i" % (data.userid, data.team) self.players[data.userid].team = data.team def player_spawn(self, data): self.players[data.userid].is_alive = True self.players[data.userid].kills_this_round = 0 self.players[data.userid].clutch_kills = 0 def game_start(self, data): self.current_round = 0 self.demo.register_on_gameevent(36, self.round_start) self.demo.register_on_gameevent(42, self.round_end) self.demo.register_on_gameevent(23, self.player_death) def round_start(self, data): self.current_round += 1 def round_end(self, data): print "Round ended, winner: %i, reason: %i, message: %s" % (data.winner, data.reason, data.message) for player in self.players.values(): if player.kills_this_round >= 3: self.highlights.append("%s got a %ik in round %i" % (player.name, player.kills_this_round, self.current_round)) if player.is_alive and player.team == data.winner and self.count_alive(player.team) == 1 and self.count_alive(self.invert_team(player.team)) == 0 and player.clutch_kills >= 2: self.highlights.append("%s clutched a 1v%i in round %i" % (player.name, player.clutch_kills, self.current_round)) def player_death(self, data): self.players[data.userid].deaths += 1 self.players[data.userid].is_alive = False if data.userid != data.attacker: # not suicide? self.players[data.attacker].kills += 1 self.players[data.attacker].kills_this_round += 1 # used for finding highlights if self.count_alive(self.players[data.attacker].team) == 1: self.players[data.attacker].clutch_kills += 1 print "%s killed %s with %s%s" % (self.players[data.attacker].name, self.players[data.userid].name, data.weapon, " (headshot)" if data.headshot else "") if data.assister != 0: # someone assisted self.players[data.assister].assists += 1 def count_alive(self, teamid): alive = 0 for player in self.players.values(): if player.is_connected and player.is_alive and player.team == teamid: alive += 1 return alive def invert_team(self, teamid): if teamid == 2 or teamid == 3: return 3 if teamid == 2 else 2 return teamid def print_results(self): print "%i players found" % len(self.players) for playerid, player in self.players.items(): if player.networkid != "BOT": print vars(player) print "" print "Highlights: %i" % len(self.highlights) for highlight in self.highlights: print highlight
class HeatmapGenerator(object): def __init__(self, filename, filter=None): self.demo = DemoDump() self.match = Match(self.demo) self.demo.open(filename) self.mapname = self.demo.demofile.demoheader.mapname self.map_overview = MAPS[self.mapname]() self.events = [] self.event_points = {} self.map_overview.get_image() #Set size, make a fix for this later self.demo.register_on_gameevent("round_announce_match_start", self.reset) self.demo.register_on_gameevent("round_start", self.round_start) #self.demo.register_on_gameevent("smokegrenade_detonate", self.on_smoke) #self.demo.register_on_gameevent("flashbang_detonate", self.on_flash) self.filter = filter def add_event(self, event_name): self.events.append(event_name) self.event_points[event_name] = {} for i in range(0, 50): self.event_points[event_name][i] = [] self.demo.register_on_gameevent(event_name, self.on_event) def reset(self, ignore=None): for i in range(0, 50): for event in self.events: self.event_points[event][i] = [] self.current_round = 0 def on_event(self, data): if self.match.current_round == 0: return if data.userid not in self.match.players.keys(): #Find out later print "ERROR: %i not found in player array" % data.userid data.userid = self.match.players[self.match.players.keys() [0]].userid player = self.match.players[data.userid] if self.filter is None or (str(data.userid) == self.filter or player.networkid == filter or player.name == filter): x, y = self.map_overview.convert_point(data.x, data.y) self.event_points[data.name][self.match.current_round].append( (x, y, self.match.players[data.userid].team)) def round_start(self, data): for event in self.events: self.event_points[event][self.match.current_round] = [] def dump(self): self.demo.dump() for event in self.events: self.dump_halves(self.event_points[event], "%s_first_half" % event, "%s_second_half" % event) for userid, player in self.match.players.items(): print vars(player) print "Total rounds %i" % self.match.current_round print self.match.team_score def dump_halves(self, points, first_half_name, second_half_name): fh_img = self.map_overview.get_image() sh_img = self.map_overview.get_image() fh_draw = ImageDraw.Draw(fh_img) sh_draw = ImageDraw.Draw(sh_img) ellipse_range = 2 #first half for i in range(1, 16): for p in points[i]: color = (255, 0, 0, 200) if p[2] == 2 else (0, 0, 255, 200) fh_draw.ellipse((p[0] - ellipse_range, p[1] - ellipse_range, p[0] + ellipse_range, p[1] + ellipse_range), fill=color) fh_img.save("%s.png" % first_half_name) for i in range(16, self.match.current_round + 1): for p in points[i]: color = (255, 0, 0, 200) if p[2] == 2 else (0, 0, 255, 200) sh_draw.ellipse((p[0] - ellipse_range, p[1] - ellipse_range, p[0] + ellipse_range, p[1] + ellipse_range), fill=color) sh_img.save("%s.png" % second_half_name)
class HeatmapGenerator(object): def __init__(self, filename, filter=None): self.demo = DemoDump() self.match = Match(self.demo) self.demo.open(filename) self.mapname = self.demo.demofile.demoheader.mapname self.smoke_points = {} self.flash_points = {} self.map_overview = MAPS[self.mapname]() self.map_overview.get_image() #Set size, make a fix for this later self.demo.register_on_gameevent("round_announce_match_start", self.game_start) self.filter = filter for i in range(0, 50): self.smoke_points[i] = [] self.flash_points[i] = [] def game_start(self, data): self.demo.register_on_gameevent("round_start", self.round_start) self.demo.register_on_gameevent("smokegrenade_detonate", self.on_smoke) self.demo.register_on_gameevent("flashbang_detonate", self.on_flash) def on_smoke(self, data): if data.userid not in self.match.players: #Find out later print "ERROR: %i not found in player" % data.userid return player = self.match.players[data.userid] if not filter or (data.userid == self.filter or player.networkid == filter or player.name == filter): x, y = self.map_overview.convert_point(data.x, data.y) self.smoke_points[self.match.current_round].append((x, y, self.match.players[data.userid].team)) def on_flash(self, data): if data.userid not in self.match.players: print "ERROR: %i not found in player" % data.userid return player = self.match.players[data.userid] if not filter or (data.userid == self.filter or player.networkid == filter or player.name == filter): x, y = self.map_overview.convert_point(data.x, data.y) self.flash_points[self.match.current_round].append((x, y, self.match.players[data.userid].team)) def round_start(self, data): self.smoke_points[self.match.current_round] = [] self.flash_points[self.match.current_round] = [] def dump(self): self.demo.dump() self.dump_halves(self.smoke_points, "smoke_first_half", "smoke_second_half") self.dump_halves(self.flash_points, "flash_first_half", "flash_second_half") def dump_halves(self, points, first_half_name, second_half_name): fh_img = self.map_overview.get_image() sh_img = self.map_overview.get_image() fh_draw = ImageDraw.Draw(fh_img) sh_draw = ImageDraw.Draw(sh_img) ellipse_range = 2 #first half for i in range(1, 16): for p in points[i]: color = (255,0, 0, 200) if p[2] == 2 else (0,0, 255, 200) fh_draw.ellipse((p[0]-ellipse_range, p[1]-ellipse_range, p[0]+ellipse_range, p[1]+ellipse_range), fill=color) fh_img.save("%s.png" % first_half_name) for i in range(16, self.match.current_round + 1): for p in points[i]: color = (255,0, 0, 200) if p[2] == 2 else (0,0, 255, 200) sh_draw.ellipse((p[0]-ellipse_range, p[1]-ellipse_range, p[0]+ellipse_range, p[1]+ellipse_range), fill=color) sh_img.save("%s.png" % second_half_name)
t.ParseFromString(data) for desc in t.descriptors: events[desc.name] = { "ID": desc.eventid, "name": desc.name, "params": {} } for key in desc.keys: events[desc.name]["params"][key.name] = _GAMEEVENT_TYPES[key.type + 1] if __name__ == '__main__': demo = DemoDump() filename = sys.argv[1] if len(sys.argv) <= 1: print "updateeventlist.py demofile.dem" sys.exit() if demo.open(filename): print "Beginning parsing" demo.register_on_netmsg(svc_GameEventList, on_list_received) demo.dump() ordered = collections.OrderedDict(sorted(events.items())) json_data = json.dumps(ordered, indent=4) print json_data f = open("../data/game_events.txt", "w") f.write(json_data) print "Saved to file data/game_events.txt"
class HeatmapGenerator(object): def __init__(self, filename, filter=None): self.demo = DemoDump() self.match = Match(self.demo) self.demo.open(filename) self.mapname = self.demo.demofile.demoheader.mapname self.map_overview = MAPS[self.mapname]() self.events = [] self.event_points = {} self.map_overview.get_image() #Set size, make a fix for this later self.demo.register_on_gameevent("round_announce_match_start", self.reset) self.demo.register_on_gameevent("round_start", self.round_start) #self.demo.register_on_gameevent("smokegrenade_detonate", self.on_smoke) #self.demo.register_on_gameevent("flashbang_detonate", self.on_flash) self.filter = filter def add_event(self, event_name): self.events.append(event_name) self.event_points[event_name] = {} for i in range(0, 50): self.event_points[event_name][i] = [] self.demo.register_on_gameevent(event_name, self.on_event) def reset(self, ignore=None): for i in range(0, 50): for event in self.events: self.event_points[event][i] = [] self.current_round = 0 def on_event(self, data): if self.match.current_round == 0: return if data.userid not in self.match.players.keys(): #Find out later print "ERROR: %i not found in player array" % data.userid data.userid = self.match.players[self.match.players.keys()[0]].userid player = self.match.players[data.userid] if self.filter is None or (str(data.userid) == self.filter or player.networkid == filter or player.name == filter): x, y = self.map_overview.convert_point(data.x, data.y) self.event_points[data.name][self.match.current_round].append((x, y, self.match.players[data.userid].team)) def round_start(self, data): for event in self.events: self.event_points[event][self.match.current_round] = [] def dump(self): self.demo.dump() for event in self.events: self.dump_halves(self.event_points[event], "%s_first_half" % event, "%s_second_half" % event) for userid, player in self.match.players.items(): print vars(player) print "Total rounds %i" % self.match.current_round print self.match.team_score def dump_halves(self, points, first_half_name, second_half_name): fh_img = self.map_overview.get_image() sh_img = self.map_overview.get_image() fh_draw = ImageDraw.Draw(fh_img) sh_draw = ImageDraw.Draw(sh_img) ellipse_range = 2 #first half for i in range(1, 16): for p in points[i]: color = (255,0, 0, 200) if p[2] == 2 else (0,0, 255, 200) fh_draw.ellipse((p[0]-ellipse_range, p[1]-ellipse_range, p[0]+ellipse_range, p[1]+ellipse_range), fill=color) fh_img.save("%s.png" % first_half_name) for i in range(16, self.match.current_round + 1): for p in points[i]: color = (255,0, 0, 200) if p[2] == 2 else (0,0, 255, 200) sh_draw.ellipse((p[0]-ellipse_range, p[1]-ellipse_range, p[0]+ellipse_range, p[1]+ellipse_range), fill=color) sh_img.save("%s.png" % second_half_name)
t = CSVCMsg_GameEventList() t.ParseFromString(data) for desc in t.descriptors: events[desc.name] = { "ID": desc.eventid, "name": desc.name, "params": {} } for key in desc.keys: events[desc.name]["params"][key.name] = _GAMEEVENT_TYPES[key.type + 1] if __name__ == '__main__': demo = DemoDump() filename = sys.argv[1] if len(sys.argv) <= 1: print "updateeventlist.py demofile.dem" sys.exit() if demo.open(filename): print "Beginning parsing" demo.register_on_netmsg(svc_GameEventList, on_list_received) demo.dump() ordered = collections.OrderedDict(sorted(events.items())) json_data = json.dumps(ordered, indent=4) print json_data f = open("../data/game_events.txt", "w") f.write(json_data) print "Saved to file data/game_events.txt"