def test_prime_thing(default_prime_configuration):
    config = {
        "mode": "two-way",
        "types_state": {
            "door": {
                "can_change_from": [
                    "Ice Door", "Missile Blast Shield", "Normal Door",
                    "Plasma Door", "Wave Door"
                ],
                "can_change_to": [
                    "Ice Door", "Ice Spreader Blast Shield",
                    "Missile Blast Shield (randomprime)", "Normal Door",
                    "Plasma Door", "Power Bomb Blast Shield",
                    "Super Missile Blast Shield", "Wave Door"
                ]
            },
            "morph_ball": {
                "can_change_from": [],
                "can_change_to": []
            },
            "other": {
                "can_change_from": [],
                "can_change_to": []
            }
        }
    }
    ref = {"reference": default_prime_configuration.dock_rando}

    dc = DockRandoConfiguration.from_json(config, RandovaniaGame.METROID_PRIME)
    encoded = bitpacking.pack_value(dc, metadata=ref)

    decoder = BitPackDecoder(encoded)
    decoded = DockRandoConfiguration.bit_pack_unpack(decoder, ref)

    assert dc == decoded
예제 #2
0
 def as_str(self) -> str:
     try:
         b = bitpacking.pack_value(self)
         b += bytes([single_byte_hash(b)])
         return base64.b64encode(b).decode("utf-8")
     except ValueError as e:
         return "Unable to create Permalink: {}".format(e)
예제 #3
0
    def as_bytes(self) -> bytes:
        key = "__cached_as_bytes"
        result = object.__getattribute__(self, key)
        if result is None:
            result = bitpacking.pack_value(self)
            object.__setattr__(self, key, result)

        return result
예제 #4
0
def test_encode_prime3(prime3_data):
    # Setup
    expected, default, value = prime3_data

    # Run
    result = bitpacking.pack_value(value, {"reference": default})

    # Assert
    assert result == expected
def test_encode(config_with_data):
    # Setup
    expected, value = config_with_data

    # Run
    result = bitpacking.pack_value(value)

    # Assert
    assert result == expected
예제 #6
0
def test_encode(config_with_data):
    # Setup
    expected, value, reference = config_with_data

    # Run
    result = bitpacking.pack_value(value, metadata={"reference": reference})

    # Assert
    assert result == expected
예제 #7
0
def test_encode(state_with_data):
    # Setup
    expected, value, ammo = state_with_data

    # Run
    result = bitpacking.pack_value(value, {"ammo": ammo})

    # Assert
    assert result == expected
예제 #8
0
def test_encode(layout_config_with_data):
    # Setup
    expected, value, expected_json = layout_config_with_data

    # Run
    result = bitpacking.pack_value(value)
    as_json = value.as_json

    # Assert
    assert result == expected
    assert as_json == expected_json
예제 #9
0
 def as_str(self) -> str:
     cached_result = object.__getattribute__(self, "__cached_as_str")
     if cached_result is not None:
         return cached_result
     try:
         b = bitpacking.pack_value(self)
         b += bytes([single_byte_hash(b)])
         result = base64.b64encode(b).decode("utf-8")
         object.__setattr__(self, "__cached_as_str", result)
         return result
     except ValueError as e:
         return "Unable to create Permalink: {}".format(e)
예제 #10
0
def serialize(patches: GamePatches, game_data: dict) -> dict:
    """
    Encodes a given GamePatches into a JSON-serializable dict.
    :param patches:
    :param game_data:
    :return:
    """
    game = data_reader.decode_data(game_data)
    world_list = game.world_list
    ordered_pickups = []

    result = {
        "starting_location":
        world_list.area_name(
            world_list.area_by_area_location(patches.starting_location)),
        "starting_items": {
            resource_info.long_name: quantity
            for resource_info, quantity in patches.starting_items.items()
        },
        "elevators": {
            world_list.area_name(
                world_list.nodes_to_area(
                    _find_node_with_teleporter(world_list, teleporter_id))):
            world_list.area_name(
                world_list.nodes_to_area(
                    world_list.resolve_teleporter_connection(connection)))
            for teleporter_id, connection in
            patches.elevator_connection.items()
        },
        "translators": {
            _name_for_gate(gate): requirement.long_name
            for gate, requirement in patches.translator_gates.items()
        },
        "locations": {
            key: value
            for key, value in _pickup_assignment_to_item_locations(
                world_list, patches.pickup_assignment,
                ordered_pickups).items()
        },
        "hints": {
            str(asset.asset_id): hint.as_json
            for asset, hint in patches.hints.items()
        }
    }

    b = bitpacking.pack_value(
        BitPackPickupEntryList(ordered_pickups, game.resource_database))
    result["_locations_internal"] = base64.b64encode(b).decode("utf-8")

    return result
def test_bit_pack_pickup_entry(has_convert: bool, echoes_resource_database):
    # Setup
    name = "Some Random Name"
    if has_convert:
        convert_resources = (ResourceConversion(
            find_resource_info_with_long_name(echoes_resource_database.item,
                                              "Morph Ball"),
            find_resource_info_with_long_name(echoes_resource_database.item,
                                              "Item Percentage")), )
    else:
        convert_resources = ()

    pickup = PickupEntry(
        name=name,
        model_index=26,
        item_category=ItemCategory.TEMPLE_KEY,
        broad_category=ItemCategory.KEY,
        resources=(ConditionalResources(
            "Morph Ball",
            None,
            (
                (find_resource_info_with_long_name(
                    echoes_resource_database.item, "Morph Ball"), 2),
                (find_resource_info_with_long_name(
                    echoes_resource_database.item, "Item Percentage"), 5),
            ),
        ),
                   ConditionalResources(
                       "Grapple Beam",
                       find_resource_info_with_long_name(
                           echoes_resource_database.item, "Morph Ball"),
                       ((find_resource_info_with_long_name(
                           echoes_resource_database.item,
                           "Grapple Beam"), 3), ),
                   )),
        convert_resources=convert_resources)

    # Run
    encoded = bitpacking.pack_value(
        BitPackPickupEntry(pickup, echoes_resource_database))
    decoder = BitPackDecoder(encoded)
    decoded = BitPackPickupEntry.bit_pack_unpack(decoder, name,
                                                 echoes_resource_database)

    # Assert
    assert pickup == decoded
예제 #12
0
def test_bit_pack_pickup_entry(has_convert: bool, echoes_resource_database,
                               generic_item_category):
    # Setup
    name = "Some Random Name"
    if has_convert:
        resource_lock = ResourceLock(
            find_resource_info_with_long_name(echoes_resource_database.item,
                                              "Morph Ball"),
            find_resource_info_with_long_name(echoes_resource_database.item,
                                              "Item Percentage"),
            find_resource_info_with_long_name(echoes_resource_database.item,
                                              "Space Jump Boots"),
        )
    else:
        resource_lock = None

    pickup = PickupEntry(
        name=name,
        model=PickupModel(
            game=RandovaniaGame.METROID_PRIME_CORRUPTION,
            name="HyperMissile",
        ),
        item_category=generic_item_category,
        broad_category=generic_item_category,
        progression=(
            (find_resource_info_with_long_name(echoes_resource_database.item,
                                               "Morph Ball"), 1),
            (find_resource_info_with_long_name(echoes_resource_database.item,
                                               "Grapple Beam"), 1),
        ),
        extra_resources=((find_resource_info_with_long_name(
            echoes_resource_database.item, "Item Percentage"), 5), ),
        resource_lock=resource_lock)

    # Run
    encoded = bitpacking.pack_value(
        BitPackPickupEntry(pickup, echoes_resource_database))
    decoder = BitPackDecoder(encoded)
    decoded = BitPackPickupEntry.bit_pack_unpack(decoder,
                                                 echoes_resource_database)

    # Assert
    assert pickup == decoded
예제 #13
0
    def as_bytes(self) -> bytes:
        cached_result = object.__getattribute__(self, "__cached_as_bytes")
        if cached_result is not None:
            return cached_result

        encoded = bitpacking.pack_value(self)
        # Add extra bytes so the base64 encoding never uses == at the end
        encoded += b"\x00" * (3 - (len(encoded) + 1) % 3)

        # Rotate bytes, so the slightest change causes a cascading effect.
        # But skip the first byte so the version check can be done early in decoding.
        byte_hash = single_byte_hash(encoded)
        new_bytes = [encoded[0]]
        new_bytes.extend(rotate_bytes(encoded[1:], byte_hash, byte_hash, inverse=False))

        # Append the hash, so the rotation can be reversed and the checksum verified
        new_bytes.append(byte_hash)

        result = bytes(new_bytes)
        object.__setattr__(self, "__cached_as_bytes", result)
        return result
예제 #14
0
def _base64_encode_pickup(pickup: PickupEntry,
                          resource_database: ResourceDatabase) -> str:
    encoded_pickup = bitpacking.pack_value(
        BitPackPickupEntry(pickup, resource_database))
    return base64.b85encode(encoded_pickup).decode("utf-8")
예제 #15
0
def test_compare_encode_round_trip(pickup_quantities: Dict[str, int]):
    original = PickupQuantities.from_params(pickup_quantities)
    encoded = pack_value(original)

    decoded = PickupQuantities.bit_pack_unpack(BitPackDecoder(encoded))
    assert original == decoded