Exemplo n.º 1
0
def _get_removable_railroads():
    railroads_info = get_railroad_info(g.game_name)
    return {
        name
        for name, attribs in railroads_info.items()
        if attribs.get("is_removable")
    }
Exemplo n.º 2
0
def removable_railroads():
    LOG.info("Removable railroads request.")

    removable_railroads = _get_removable_railroads()

    LOG.info(f"Removable railroads response: {removable_railroads}")

    railroads_info = get_railroad_info(g.game_name)
    return jsonify({
        "railroads": list(sorted(removable_railroads)),
        "home-cities": {
            railroad: railroads_info[railroad]["home"]
            for railroad in removable_railroads
        }
    })
Exemplo n.º 3
0
def closable_railroads():
    LOG.info("Closable railroads request.")

    game = get_game(g.game_name)
    closable_railroads = _get_closable_railroads(game)

    LOG.info(f"Closable railroads response: {closable_railroads}")

    railroads_info = get_railroad_info(game)
    return jsonify({
        "railroads": list(sorted(closable_railroads)),
        "home-cities": {
            railroad: railroads_info[railroad]["home"]
            for railroad in closable_railroads
        }
    })
Exemplo n.º 4
0
def legal_railroads():
    LOG.info("Legal railroads request.")

    existing_railroads = {
        railroad
        for railroad in json.loads(request.args.get("railroads", "{}"))
        if railroad
    }

    railroads_info = get_railroad_info(g.game_name)
    legal_railroads = set(railroads_info.keys()) - existing_railroads

    LOG.info(f"Legal railroads response: {legal_railroads}")

    return jsonify({
        "railroads": list(sorted(legal_railroads)),
        "home-cities": {
            railroad: railroads_info[railroad]["home"]
            for railroad in legal_railroads
        }
    })
Exemplo n.º 5
0
def _validate_migration_data(migration_data):
    if not isinstance(migration_data, dict):
        LOG.debug(
            f"Migration validation failure: migration_data is not a dict")
        return {"error": "Failed to load migration data."}

    game = get_game("1846")
    railroad_info = get_railroad_info(game)
    private_companies = game.get_game_submodule("private_companies")
    for key, value in migration_data.items():
        # Make sure no control characters or non-ASCII characters are present.
        if not key.isascii() or not key.isprintable() or not value.isascii(
        ) or not value.isprintable():
            LOG.debug(
                f"Migration failure: key or value is not printable ASCII")
            return False

        try:
            migration_data[key] = json.dumps(json.loads(value))
        except Exception as exc:
            LOG.debug(
                f"Migration validation failure[{key}]: value not valid JSON: {value}"
            )
            return False

        if key == "placedTilesTable":
            tiles_json = json.loads(value)
            if not all(len(row) == 3 for row in tiles_json) or not all(
                    str(col).isalnum() for row in tiles_json for col in row):
                LOG.debug(f"Migration validation failure[{key}]: {value}")
                return False
        elif key == "railroadsTable":
            railroads_json = json.loads(value)
            for row in railroads_json:
                if len(row) not in (3,
                                    4) or row[0].strip() not in railroad_info:
                    LOG.debug(
                        f"Migration validation failure[{key}]: row wrong length, or railroad name invalid: {value}"
                    )
                    return False
                if row[1] and row[1].strip():
                    train_strs = [
                        train_str.strip().split("/", 1)
                        for train_str in row[1].strip().split(",")
                    ]
                    if not all(val.strip().isdigit()
                               for train_str in train_strs
                               for val in train_str):
                        LOG.debug(
                            f"Migration validation failure[{key}]: trains malformed: {value}"
                        )
                        return False
                if row[2] and row[2].strip():
                    if not all(station_str.strip().isalnum()
                               for station_str in row[2].strip().split(",")):
                        LOG.debug(
                            f"Migration validation failure[{key}]: stations malformed: {value}"
                        )
                        return False
        elif key == "removedRailroadsTable":
            removed_railroads = json.loads(value)
            for railroad in removed_railroads:
                if railroad.strip() not in railroad_info:
                    LOG.debug(
                        f"Migration validation failure[{key}]: railroad name invalid: {value}"
                    )
                    return False
        elif key == "privateCompaniesTable":
            private_companies_json = json.loads(value)
            for row in private_companies_json:
                if len(row) != 3 \
                        or row[0].strip() not in private_companies.COMPANIES \
                        or (row[1] and row[1].strip() not in railroad_info) \
                        or (row[2] and not row[2].strip().isalnum()):
                    LOG.debug(
                        f"Migration validation failure[{key}]: invalid row: {row}"
                    )
                    return False
        elif key == "hideCityPaths":
            if value not in ("true", "false"):
                LOG.debug(f"Migration validation failure[{key}]: {value}")
                return False
        else:
            LOG.debug(f"Migration validation failure: invalid key: {key}")
            return False

    return True
Exemplo n.º 6
0
def _get_closable_railroads(game):
    return set(get_railroad_info(
        game).keys()) if game.rules.railroads_can_close else set()
Exemplo n.º 7
0
def board_space_info():
    coord = request.args["coord"].strip()
    tile_id = request.args.get("tileId", "").strip()
    orientation = request.args.get("orientation", "").strip()
    phase = request.args.get("phase")

    game = get_game(g.game_name)
    board = get_board(game)
    railroad_info = get_railroad_info(game)
    cell = board.cell(coord)

    station_offsets = get_station_offsets(game)
    if tile_id and orientation:
        offset_data = station_offsets.get("tile", {})
        offset = _get_station_offset(offset_data, tile_id)

        space = placedtile.PlacedTile.place(cell, game.tiles[tile_id],
                                            orientation, board.get_space(cell))
        if isinstance(space, placedtile.SplitCity):
            # In the offset file, branches are indicated by side. To translate
            # into cells, add the orientation, and modulo by 6 to retrieve its
            # neighbor given the orientation.
            offset = {
                str(cell.neighbors[(int(exit) + int(orientation)) % 6]):
                offsetCoords
                for exit, offsetCoords in offset.items()
            }

        if "rotation" in offset:
            offset["rotation"] = math.radians(offset["rotation"])
    else:
        offset_data = station_offsets.get("board", {})
        offset = _get_station_offset(offset_data, coord)
        space = board.get_space(cell)

        if "rotation" in offset:
            offset["rotation"] = math.radians(offset["rotation"])

    if hasattr(space, "capacity"):
        # Stop-gap. I need to figure out what to actually do with capacity keys.
        capacity = sum(space.capacity.values()) if isinstance(
            space.capacity, dict) else space.capacity
    else:
        capacity = 0

    home = [
        railroad for railroad, info_dict in railroad_info.items()
        if info_dict.get("home") == coord
    ]
    if not phase or (game.rules.stations_reserved_until
                     and game.compare_phases(
                         game.rules.stations_reserved_until, phase) < 0):
        reserved = [
            railroad for railroad, info_dict in railroad_info.items()
            if coord in info_dict.get("reserved", [])
        ]
    else:
        reserved = []

    info = {
        "capacity":
        capacity,
        "offset":
        offset,
        "phase":
        getattr(space, "upgrade_level", 0),
        "is-split-city":
        isinstance(space, (boardtile.SplitCity, placedtile.SplitCity)),
        "home-to":
        home,
        "reserved-for":
        reserved
    }

    return jsonify({"info": info})