Skip to content

Commit aee2c60

Browse files
committed
detached branch merge
2 parents 60fc9c8 + e1859a5 commit aee2c60

File tree

5 files changed

+79
-49
lines changed

5 files changed

+79
-49
lines changed

hslog/live/entities.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,20 @@ def game(self, value):
2121
if value is not None:
2222
terminal_output("ENTITY CREATED", self)
2323
# push data to an end-point
24+
pass
2425

2526
def tag_change(self, tag, value):
2627
if tag == GameTag.CONTROLLER and not self._initial_controller:
2728
self._initial_controller = self.tags.get(GameTag.CONTROLLER, value)
2829
self.tags[tag] = value
2930
terminal_output("TAG UPDATED", self, tag, value)
3031
# push data to an end-point
32+
pass
3133

3234
def update_callback(self, caller):
3335
terminal_output("ENTITY UPDATED", self)
3436
# push data to an end-point
37+
pass
3538

3639

3740
class LiveCard(Card, LiveEntity):

hslog/live/export.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from hslog.export import EntityTreeExporter
44
from hslog.live.entities import LiveCard, LiveGame, LivePlayer
5-
from hslog.live.utils import ACCESS_DEBUG
65

76

87
class LiveEntityTreeExporter(EntityTreeExporter):
@@ -18,7 +17,6 @@ def __init__(self, packet_tree):
1817
super(LiveEntityTreeExporter, self).__init__(packet_tree)
1918

2019
def handle_player(self, packet):
21-
ACCESS_DEBUG(self.__class__, "handle_player")
2220
entity_id = int(packet.entity)
2321

2422
if hasattr(self.packet_tree, "manager"):

hslog/live/parser.py

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22
from collections import deque
33
from threading import Thread
44

5-
from hearthstone.enums import FormatType, GameType
6-
75
from hslog import packets, tokens
86
from hslog.exceptions import RegexParsingError
97
from hslog.live.packets import LivePacketTree
108
from hslog.live.player import LivePlayerManager
119
from hslog.parser import LogParser
1210
from hslog.player import LazyPlayer
13-
from hslog.utils import parse_enum, parse_tag
11+
from hslog.utils import parse_tag
1412

1513

1614
class LiveLogParser(LogParser):
@@ -46,14 +44,17 @@ def new_packet_tree(self, ts):
4644
self.current_block = self._packets
4745
self.games.append(self._packets)
4846

49-
"""
50-
why is this return important?
51-
it"s called only here:
47+
def handle_entities_chosen(self, ts, data):
48+
super(LiveLogParser, self).handle_entities_chosen(ts, data)
49+
if data.startswith("id="):
50+
sre = tokens.ENTITIES_CHOSEN_RE.match(data)
51+
if not sre:
52+
raise RegexParsingError(data)
53+
player_name = sre.groups()[1]
5254

53-
def create_game(self, ts):
54-
self.new_packet_tree(ts)
55-
"""
56-
return self._packets
55+
# pick up opponent name from GameState.DebugPrintEntitiesChosen()
56+
m = self._packets.manager
57+
m.complete_player_names(player_name, self._packets)
5758

5859
def handle_game(self, ts, data):
5960
if data.startswith("PlayerID="):
@@ -62,25 +63,13 @@ def handle_game(self, ts, data):
6263
raise RegexParsingError(data)
6364
player_id, player_name = sre.groups()
6465

65-
# set the name of the player
66-
players = self.games[-1].liveExporter.game.players
67-
for p in players:
68-
if p.player_id == int(player_id):
69-
p.name = player_name
66+
# set initial name based on GameState.DebugPrintGame()
67+
m = self._packets.manager
68+
m.set_initial_player_name(player_id, player_name, self._packets)
7069

7170
player_id = int(player_id)
7271
else:
73-
key, value = data.split("=")
74-
key = key.strip()
75-
value = value.strip()
76-
if key == "GameType":
77-
value = parse_enum(GameType, value)
78-
elif key == "FormatType":
79-
value = parse_enum(FormatType, value)
80-
else:
81-
value = int(value)
82-
83-
self.game_meta[key] = value
72+
super(LiveLogParser, self).handle_game(ts, data)
8473

8574
def tag_change(self, ts, e, tag, value, def_change):
8675
entity_id = self.parse_entity_or_player(e)

hslog/live/player.py

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,56 @@
66

77
class LivePlayerManager(PlayerManager):
88

9-
def register_player_name_on_tag_change(self, player, tag, value):
10-
"""
11-
Triggers on every TAG_CHANGE where the corresponding entity is a LazyPlayer.
12-
Will attempt to return a new value instead
13-
"""
14-
if tag == GameTag.ENTITY_ID:
15-
# This is the simplest check. When a player entity is declared,
16-
# its ENTITY_ID is not available immediately (in pre-6.0).
17-
# If we get a matching ENTITY_ID, then we can use that to match it.
18-
return self.register_player_name(player.name, value)
19-
elif tag == GameTag.LAST_CARD_PLAYED:
20-
# This is a fallback to register_player_name_mulligan in case the mulligan
21-
# phase is not available in this game (spectator mode, reconnects).
22-
if value not in self._entity_controller_map:
23-
raise ParsingError("Unknown entity ID on TAG_CHANGE: %r" % (value))
24-
player_id = self._entity_controller_map[value]
25-
entity_id = int(self._players_by_player_id[player_id])
26-
return self.register_player_name(player.name, entity_id)
27-
elif tag == GameTag.MULLIGAN_STATE:
28-
return None
29-
return player
9+
def __init__(self):
10+
super(LivePlayerManager, self).__init__()
11+
12+
self.actual_player_names = set()
13+
self.names_used = set()
14+
self.name_assignment_done = False
15+
16+
def register_player_name_on_tag_change(self, player, tag, value):
17+
"""
18+
Triggers on every TAG_CHANGE where the corresponding entity is a LazyPlayer.
19+
Will attempt to return a new value instead
20+
"""
21+
if tag == GameTag.ENTITY_ID:
22+
# This is the simplest check. When a player entity is declared,
23+
# its ENTITY_ID is not available immediately (in pre-6.0).
24+
# If we get a matching ENTITY_ID, then we can use that to match it.
25+
return self.register_player_name(player.name, value)
26+
elif tag == GameTag.LAST_CARD_PLAYED:
27+
# This is a fallback to register_player_name_mulligan in case the mulligan
28+
# phase is not available in this game (spectator mode, reconnects).
29+
if value not in self._entity_controller_map:
30+
raise ParsingError("Unknown entity ID on TAG_CHANGE: %r" % (value))
31+
player_id = self._entity_controller_map[value]
32+
entity_id = int(self._players_by_player_id[player_id])
33+
return self.register_player_name(player.name, entity_id)
34+
else:
35+
return None
36+
return player
37+
38+
def set_initial_player_name(self, player_id, player_name, current_game):
39+
players = current_game.liveExporter.game.players
40+
for p in players:
41+
if p.player_id == int(player_id):
42+
p.name = player_name
43+
44+
def complete_player_names(self, player_name, current_game):
45+
# populate names if they haven"t been used already
46+
if player_name not in self.names_used:
47+
self.actual_player_names.add(player_name)
48+
49+
# if there are two names available we have enough to assign
50+
if len(self.actual_player_names) == 2 and not self.name_assignment_done:
51+
unnamed = None
52+
for p in current_game.liveExporter.game.players:
53+
if p.name in self.actual_player_names:
54+
self.names_used.add(p.name)
55+
self.actual_player_names.remove(p.name)
56+
else:
57+
unnamed = p
58+
other_player_name = self.actual_player_names.pop()
59+
self.names_used.add(other_player_name)
60+
unnamed.name = other_player_name
61+
self.name_assignment_done = True

hslog/live/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,11 @@ def terminal_output(msg_type, obj, attr=None, value=None):
4848
align(repr(attr), 40),
4949
align(value, 30),
5050
)
51+
52+
53+
def debug_player_names(player_manager):
54+
print("{} | {} | {}".format(
55+
align(player_manager.actual_player_names, 40),
56+
align(player_manager.names_used, 40),
57+
align(player_manager.name_assignment_done, 10),
58+
))

0 commit comments

Comments
 (0)