Esempio n. 1
0
 def create_game(self, ts):
     self.current_game = Game(0)
     packet_tree = packets.PacketTree(ts)
     packet_tree.spectator_mode = self.spectator_mode
     packet_tree.game = self.current_game
     self.games.append(packet_tree)
     self.current_block = packet_tree
     self._entity_packet = packets.CreateGame(ts, self.current_game)
     self._game_packet = self._entity_packet
     self.current_block.packets.append(self._entity_packet)
	def create_game(self, ts):
		self.current_game = Game(0)
		packet_tree = packets.PacketTree(ts)
		packet_tree.spectator_mode = self.spectator_mode
		packet_tree.game = self.current_game
		self.games.append(packet_tree)
		self.current_block = packet_tree
		self._entity_packet = packets.CreateGame(ts, self.current_game)
		self._game_packet = self._entity_packet
		self.current_block.packets.append(self._entity_packet)
Esempio n. 3
0
def test_eligible_for_unification():
    player1 = Player(1, 1, 144115193835963207, 37760170)
    player2 = Player(2, 2, 144115193835963207, 153376707)
    innkeeper = Player(3, 1, 0, 0)

    ladder_game = Game(1)
    ladder_game.players = [player1, player2]

    ai_game = Game(2)
    ai_game.players = [innkeeper, player1]

    assert eligible_for_unification(ladder_game, {})
    assert not eligible_for_unification(ladder_game, {"reconnecting": True})
    assert not eligible_for_unification(ai_game, {})
    assert not eligible_for_unification(ai_game, {"reconnecting": True})
def test_entities():
    game = Game(1)
    game.register_entity(game)

    assert game.find_entity_by_id(1) is game
    assert game.find_entity_by_id(2) is None
def test_player():
    game = Game(1)
    player = Player(2, 1, 0, 0, "Test Player")
    player.game = game

    assert player.starting_hero is None
Esempio n. 6
0
 def game(self):
     game = Game(1)
     game.register_entity(game)
     return game
Esempio n. 7
0
class PowerHandler(object):
    def __init__(self):
        super(PowerHandler, self).__init__()
        self.current_block = None
        self._entity_node = None
        self._metadata_node = None

    def _check_for_mulligan_hack(self, ts, entity, tag, value):
        # Old game logs didn't handle asynchronous mulligans properly.
        # If we're missing an ACTION_END packet after the mulligan SendChoices,
        # we just close it out manually.
        if tag == enums.GameTag.MULLIGAN_STATE and value == enums.Mulligan.DEALING:
            assert self.current_block
            if isinstance(self.current_block, packets.Block):
                logging.warning(
                    "WARNING: Broken mulligan nesting. Working around...")
                self.block_end(ts)

    def find_callback(self, method):
        if method == self.parse_method("DebugPrintPower"):
            return self.handle_data

    def parse_initial_tag(self, data):
        sre = TAG_VALUE_RE.match(data)
        tag, value = sre.groups()
        return parse_tag(tag, value)

    def handle_data(self, ts, data):
        opcode = data.split()[0]

        if opcode in PowerType.__members__:
            return self.handle_power(ts, opcode, data)

        if opcode == "GameEntity":
            self.flush()
            sre = GAME_ENTITY_RE.match(data)
            self.register_game(ts, *sre.groups())
        elif opcode == "Player":
            self.flush()
            sre = PLAYER_ENTITY_RE.match(data)
            self.register_player(ts, *sre.groups())
        elif opcode.startswith("tag="):
            tag, value = self.parse_initial_tag(data)
            self._entity_packet.tags.append((tag, value))
        elif opcode.startswith("Info["):
            if not self._metadata_node:
                logging.warning("Metadata Info outside of META_DATA: %r", data)
                return
            sre = METADATA_INFO_RE.match(data)
            idx, entity = sre.groups()
            entity = self.parse_entity(entity)
            self._metadata_node.info.append(entity)
        else:
            raise NotImplementedError(data)

    def flush(self):
        if self._entity_node:
            for k, v in self._entity_packet.tags:
                self._entity_node.tags[k] = v
            self._entity_node = None

        if self._metadata_node:
            self._metadata_node = None

    def handle_power(self, ts, opcode, data):
        self.flush()

        if opcode == "CREATE_GAME":
            regex, callback = CREATE_GAME_RE, self.create_game
        elif opcode in ("ACTION_START", "BLOCK_START"):
            sre = BLOCK_START_RE.match(data)
            if sre is None:
                sre = ACTION_START_OLD_RE.match(data)
                entity, type, index, target = sre.groups()
                effectid, effectindex = None, None
            else:
                type, entity, effectid, effectindex, target = sre.groups()
                index = None
            self.block_start(ts, entity, type, index, effectid, effectindex,
                             target)
            return
        elif opcode in ("ACTION_END", "BLOCK_END"):
            regex, callback = BLOCK_END_RE, self.block_end
        elif opcode == "FULL_ENTITY":
            if data.startswith("FULL_ENTITY - Updating"):
                regex, callback = FULL_ENTITY_UPDATE_RE, self.full_entity_update
            else:
                regex, callback = FULL_ENTITY_CREATE_RE, self.full_entity
        elif opcode == "SHOW_ENTITY":
            regex, callback = SHOW_ENTITY_RE, self.show_entity
        elif opcode == "HIDE_ENTITY":
            regex, callback = HIDE_ENTITY_RE, self.hide_entity
        elif opcode == "CHANGE_ENTITY":
            regex, callback = CHANGE_ENTITY_RE, self.change_entity
        elif opcode == "TAG_CHANGE":
            regex, callback = TAG_CHANGE_RE, self.tag_change
        elif opcode == "META_DATA":
            regex, callback = META_DATA_RE, self.meta_data
        else:
            raise NotImplementedError(data)

        sre = regex.match(data)
        if not sre:
            logging.warning("Could not correctly parse %r", data)
            return
        callback(ts, *sre.groups())

    # Messages
    def create_game(self, ts):
        self.current_game = Game(0)
        packet_tree = packets.PacketTree(ts)
        packet_tree.spectator_mode = self.spectator_mode
        packet_tree.game = self.current_game
        self.games.append(packet_tree)
        self.current_block = packet_tree
        self._entity_packet = packets.CreateGame(ts, self.current_game)
        self._game_packet = self._entity_packet
        self.current_block.packets.append(self._entity_packet)

    def block_start(self, ts, entity, type, index, effectid, effectindex,
                    target):
        entity = self.parse_entity(entity)
        type = parse_enum(enums.BlockType, type)
        if index is not None:
            index = int(index)
        target = self.parse_entity(target)
        block = packets.Block(ts, entity, type, index, effectid, effectindex,
                              target)
        block.parent = self.current_block
        self.current_block.packets.append(block)
        self.current_block = block

    def block_end(self, ts):
        if not self.current_block.parent:
            logging.warning("[%s] Orphaned BLOCK_END detected" % (ts))
            return self.current_block
        self.current_block.end()
        block = self.current_block
        self.current_block = self.current_block.parent
        return block

    def full_entity(self, ts, id, cardid):
        id = int(id)
        entity = Card(id, cardid)
        self.current_game.register_entity(entity)
        self._entity_node = entity
        self._entity_packet = packets.FullEntity(ts, entity, cardid)
        self.current_block.packets.append(self._entity_packet)

    def full_entity_update(self, ts, entity, cardid):
        id = self.parse_entity_id(entity)
        return self.full_entity(ts, id, cardid)

    def show_entity(self, ts, entity, cardid):
        entity = self.parse_entity(entity)
        entity.reveal(cardid)
        self._entity_node = entity
        self._entity_packet = packets.ShowEntity(ts, entity, cardid)
        self.current_block.packets.append(self._entity_packet)

    def hide_entity(self, ts, entity, tag, value):
        entity = self.parse_entity(entity)
        entity.hide()
        tag, value = parse_tag(tag, value)
        assert tag == GameTag.ZONE
        packet = packets.HideEntity(ts, entity, value)
        self.current_block.packets.append(packet)

    def change_entity(self, ts, entity, cardid):
        entity = self.parse_entity(entity)
        entity.change(cardid)
        self._entity_node = entity
        self._entity_packet = packets.ChangeEntity(ts, entity, cardid)
        self.current_block.packets.append(self._entity_packet)

    def meta_data(self, ts, meta, data, info):
        meta = parse_enum(enums.MetaDataType, meta)
        if meta == enums.MetaDataType.JOUST:
            data = self.parse_entity(data)
        count = int(info)
        self._metadata_node = packets.MetaData(ts, meta, data, count)
        self.current_block.packets.append(self._metadata_node)

    def tag_change(self, ts, e, tag, value):
        entity = self.parse_entity(e)
        tag, value = parse_tag(tag, value)
        self._check_for_mulligan_hack(ts, entity, tag, value)

        if not isinstance(entity, Entity):
            entity = self.check_for_player_registration(tag, value, e)

        packet = packets.TagChange(ts, entity, tag, value)
        self.current_block.packets.append(packet)

        if not entity or not isinstance(entity, Entity):
            if tag == enums.GameTag.ENTITY_ID:
                self.register_player_name(self.current_game, e, value)
            else:
                self.buffer_packet_entity_update(packet, e)
        else:
            entity.tag_change(tag, value)
        return entity
class PowerHandler(object):
	def __init__(self):
		super(PowerHandler, self).__init__()
		self.current_block = None
		self._entity_node = None
		self._metadata_node = None

	def _check_for_mulligan_hack(self, ts, entity, tag, value):
		# Old game logs didn't handle asynchronous mulligans properly.
		# If we're missing an ACTION_END packet after the mulligan SendChoices,
		# we just close it out manually.
		if tag == enums.GameTag.MULLIGAN_STATE and value == enums.Mulligan.DEALING:
			assert self.current_block
			if isinstance(self.current_block, packets.Block):
				logging.warning("WARNING: Broken mulligan nesting. Working around...")
				self.block_end(ts)

	def find_callback(self, method):
		if method == self.parse_method("DebugPrintPower"):
			return self.handle_data

	def parse_initial_tag(self, data):
		sre = TAG_VALUE_RE.match(data)
		tag, value = sre.groups()
		return parse_tag(tag, value)

	def handle_data(self, ts, data):
		opcode = data.split()[0]

		if opcode in PowerType.__members__:
			return self.handle_power(ts, opcode, data)

		if opcode == "GameEntity":
			self.flush()
			sre = GAME_ENTITY_RE.match(data)
			self.register_game(ts, *sre.groups())
		elif opcode == "Player":
			self.flush()
			sre = PLAYER_ENTITY_RE.match(data)
			self.register_player(ts, *sre.groups())
		elif opcode.startswith("tag="):
			tag, value = self.parse_initial_tag(data)
			self._entity_packet.tags.append((tag, value))
		elif opcode.startswith("Info["):
			sre = METADATA_INFO_RE.match(data)
			idx, entity = sre.groups()
			entity = self.parse_entity(entity)
			self._metadata_node.info.append(entity)
		else:
			raise NotImplementedError(data)

	def flush(self):
		if self._entity_node:
			for k, v in self._entity_packet.tags:
				self._entity_node.tags[k] = v
			self._entity_node = None

		if self._metadata_node:
			self._metadata_node = None

	def handle_power(self, ts, opcode, data):
		self.flush()

		if opcode == "CREATE_GAME":
			regex, callback = CREATE_GAME_RE, self.create_game
		elif opcode in ("ACTION_START", "BLOCK_START"):
			sre = BLOCK_START_RE.match(data)
			if sre is None:
				sre = ACTION_START_OLD_RE.match(data)
				entity, type, index, target = sre.groups()
				effectid, effectindex = None, None
			else:
				type, entity, effectid, effectindex, target = sre.groups()
				index = None
			self.block_start(ts, entity, type, index, effectid, effectindex, target)
			return
		elif opcode in ("ACTION_END", "BLOCK_END"):
			regex, callback = BLOCK_END_RE, self.block_end
		elif opcode == "FULL_ENTITY":
			if data.startswith("FULL_ENTITY - Updating"):
				regex, callback = FULL_ENTITY_UPDATE_RE, self.full_entity_update
			else:
				regex, callback = FULL_ENTITY_CREATE_RE, self.full_entity
		elif opcode == "SHOW_ENTITY":
			regex, callback = SHOW_ENTITY_RE, self.show_entity
		elif opcode == "HIDE_ENTITY":
			regex, callback = HIDE_ENTITY_RE, self.hide_entity
		elif opcode == "CHANGE_ENTITY":
			regex, callback = CHANGE_ENTITY_RE, self.change_entity
		elif opcode == "TAG_CHANGE":
			regex, callback = TAG_CHANGE_RE, self.tag_change
		elif opcode == "META_DATA":
			regex, callback = META_DATA_RE, self.meta_data
		else:
			raise NotImplementedError(data)

		sre = regex.match(data)
		if not sre:
			logging.warning("Could not correctly parse %r", data)
			return
		callback(ts, *sre.groups())

	# Messages
	def create_game(self, ts):
		self.current_game = Game(0)
		packet_tree = packets.PacketTree(ts)
		packet_tree.spectator_mode = self.spectator_mode
		packet_tree.game = self.current_game
		self.games.append(packet_tree)
		self.current_block = packet_tree
		self._entity_packet = packets.CreateGame(ts, self.current_game)
		self._game_packet = self._entity_packet
		self.current_block.packets.append(self._entity_packet)

	def block_start(self, ts, entity, type, index, effectid, effectindex, target):
		entity = self.parse_entity(entity)
		type = parse_enum(enums.BlockType, type)
		if index is not None:
			index = int(index)
		target = self.parse_entity(target)
		block = packets.Block(ts, entity, type, index, effectid, effectindex, target)
		block.parent = self.current_block
		self.current_block.packets.append(block)
		self.current_block = block

	def block_end(self, ts):
		if not self.current_block.parent:
			logging.warning("[%s] Orphaned BLOCK_END detected" % (ts))
			return self.current_block
		self.current_block.end()
		block = self.current_block
		self.current_block = self.current_block.parent
		return block

	def full_entity(self, ts, id, cardid):
		id = int(id)
		entity = Card(id, cardid)
		self.current_game.register_entity(entity)
		self._entity_node = entity
		self._entity_packet = packets.FullEntity(ts, entity, cardid)
		self.current_block.packets.append(self._entity_packet)

	def full_entity_update(self, ts, entity, cardid):
		id = self.parse_entity_id(entity)
		return self.full_entity(ts, id, cardid)

	def show_entity(self, ts, entity, cardid):
		entity = self.parse_entity(entity)
		entity.reveal(cardid)
		self._entity_node = entity
		self._entity_packet = packets.ShowEntity(ts, entity, cardid)
		self.current_block.packets.append(self._entity_packet)

	def hide_entity(self, ts, entity, tag, value):
		entity = self.parse_entity(entity)
		entity.hide()
		tag, value = parse_tag(tag, value)
		assert tag == GameTag.ZONE
		packet = packets.HideEntity(ts, entity, value)
		self.current_block.packets.append(packet)

	def change_entity(self, ts, entity, cardid):
		entity = self.parse_entity(entity)
		entity.change(cardid)
		self._entity_node = entity
		self._entity_packet = packets.ChangeEntity(ts, entity, cardid)
		self.current_block.packets.append(self._entity_packet)

	def meta_data(self, ts, meta, data, info):
		meta = parse_enum(enums.MetaDataType, meta)
		if meta == enums.MetaDataType.JOUST:
			data = self.parse_entity(data)
		count = int(info)
		self._metadata_node = packets.MetaData(ts, meta, data, count)
		self.current_block.packets.append(self._metadata_node)

	def tag_change(self, ts, e, tag, value):
		entity = self.parse_entity(e)
		tag, value = parse_tag(tag, value)
		self._check_for_mulligan_hack(ts, entity, tag, value)

		if not isinstance(entity, Entity):
			entity = self.check_for_player_registration(tag, value, e)

		packet = packets.TagChange(ts, entity, tag, value)
		self.current_block.packets.append(packet)

		if not entity or not isinstance(entity, Entity):
			if tag == enums.GameTag.ENTITY_ID:
				self.register_player_name(self.current_game, e, value)
			else:
				self.buffer_packet_entity_update(packet, e)
		else:
			entity.tag_change(tag, value)
		return entity