from nicegui import ui from bot_instance import bot import re from dom5game import Dom5game import servermanager import os from dotenv import load_dotenv def create_ui(): pages = ui.sub_pages() rows = [] for game in bot.tracked_games: pages.add(f"/{game.name}", lambda name=game.name: game_page(name)) rows.append({"Name": game.name, "Turn": game.turn}) pages.add("/", lambda: main_page(rows)) pages.add("/create", lambda: creator_page()) # ui.dark_mode().enable() ui.run(reload=False, show=False) def main_page(rows): game_table = ui.table(rows=rows, title="Currently Running Games") with game_table.add_slot("body-cell-Name"): with game_table.cell("Name"): ui.link().props(":href=props.value :innerHTML=props.value") def game_page(game_name: str): rows = [] game = Dom5game.get_game_by_name(game_name, bot.tracked_games) for player in game.players.keys(): if game.players[player] not in {"AI", "Eliminated"}: rows.append({"Player": player, "Status": game.players[player]}) ui.table(rows=rows, title=game_name) # hell def creator_page(): # Game Name name = ui.input( label="Game Name", validation={ "Game with that name already exists": lambda value: not ( os.path.isdir("games/" + value) ), "Name contains an invalid symbol": lambda value: bool( re.match("^[A-Za-z0-9_-]*$", value) ), }, ) # Port load_dotenv() port_min = int(os.getenv("PORT_MIN", 1024)) port_max = int(os.getenv("PORT_MAX", 65535)) port = ui.input( label="Port", validation={ f"Port must be between {str(port_min)} and {str(port_max)}": lambda value: value.isdigit() and port_min <= int(value) <= port_max, "Port in use": lambda value: value.isdigit() and not servermanager.is_port_in_use(int(value)), }, ) # Era + AI # This sucks but idk how else to move the radio selector above the table ai_slots = [] era_container = ui.row() table_container = ui.column() with era_container: era = ( ui.radio({1: "Early Age", 2: "Middle Age", 3: "Late Age"}) .props("inline") .on_value_change( lambda e: create_ai_table(e.value, table_container, ai_slots) ) ) # client_start = ui.checkbox("Allow clients to start the game") checkbox_container = ui.row() with checkbox_container: team_game = ui.checkbox("Disciple Game") clustered_start = ui.checkbox("Clustered Spawns (Disciple games only)") random_start_research = ui.checkbox("Random Start Research") score_graphs = ui.checkbox("Score Graphs") renaming = ui.checkbox("Allow Renaming", value=True) no_nation_info = ui.checkbox("No Info About Other Nations") no_cheat_det = ui.checkbox("Disable Anticheat") no_artifact_rest = ui.checkbox("Disable Artifact Forge Limit") no_new_ai = ui.checkbox("Disable Becoming AI Controlled") vwrap = ui.checkbox("North South Wrapping") hwrap = ui.checkbox("East West Wrapping") description_container = ui.row() toggle_container = ui.row() # TODO: Are these containers still needed? with toggle_container: event_rarity = ui.toggle({1: "Common", 2: "Rare"}, value=1) random_map = ui.toggle([10, 15, 20], value=15) with description_container: ui.label("Event Rarity") # TODO: Fix Padding ui.label("Provinces per player:") with ui.row(): ui.label("Gold Multiplier:").classes("w-36") richness = ui.input( validation={ "Value must be between 50 and 300": lambda value: value.isdigit() and 50 <= int(value) <= 300, }, value="100", ) with ui.row(): ui.label("Resource Multiplier:").classes("w-36") resources = ui.input( validation={ "Value must be between 50 and 300": lambda value: value.isdigit() and 50 <= int(value) <= 300, }, value="100", ) with ui.row(): ui.label("Recruitment Multiplier:").classes("w-36") recruitment = ui.input( validation={ "Value must be between 50 and 300": lambda value: value.isdigit() and 50 <= int(value) <= 300, }, value="100", ) with ui.row(): ui.label("Supplies Multiplier:").classes("w-36") supplies = ui.input( validation={ "Value must be between 50 and 300": lambda value: value.isdigit() and 50 <= int(value) <= 300, }, value="100", ) # TODO: REMOVE THIS it is just for testing ui.button( "Generate String", on_click=lambda: print( servermanager.server_command_builder( name=name.value, port=int(port.value), era=int(era.value), ai_slots=ai_slots, random_map=int(random_map.value), event_rarity=int(event_rarity.value), hwrap=hwrap.value, vwrap=vwrap.value, no_new_ai=no_new_ai.value, no_artifact_rest=no_artifact_rest.value, no_cheat_det=no_cheat_det.value, renaming=renaming.value, score_graphs=score_graphs.value, random_start_research=random_start_research.value, clustered_start=clustered_start.value, team_game=team_game.value, no_nation_info=no_nation_info.value, recruitment=int(recruitment.value), resources=int(resources.value), richness=int(richness.value), supplies=int(supplies.value), ) ), ) def create_ai_table(era, table_container, ai_slots): # TODO: move this somewhere else AI_LEVELS = [ "Human", "Easy", "Normal", "Difficult", "Mighty", "Master", "Impossible", "Closed", ] table_container.clear() nations = servermanager.get_nations() with table_container: with ui.card().classes("w-full"): with ui.row().classes("font-bold w-full"): ui.label("ID").classes("w-16") ui.label("Nation").classes("w-104") ui.label("AI Level") ui.separator() with ui.row().classes("items-center, w-full"): ui.label("All").classes("w-124") master_select = ui.select( AI_LEVELS, value="Human", ) for nation_id, nation in nations[str(era)].items(): nation_name, title = nation["name"] with ui.row().classes("items-center w-full"): ui.label(str(nation_id)).classes("w-16") ui.label(nation_name + ", " + title).classes("w-104") # TODO: Random nations? # Although that logic should probably go into servermanager.py ui.select( AI_LEVELS, value="Human", on_change=lambda e, nid=nation_id: set_ai_level( e.value, nid, ai_slots ), ).bind_value_from(master_select) def set_ai_level(value, nid, ai_slots): level_map = { "Closed": 0, "Easy": 1, "Normal": 2, "Difficult": 3, "Mighty": 4, "Master": 5, "Impossible": 6, } for ai in ai_slots: if ai[0] == nid: ai_slots.remove(ai) if value == "Human": return ai_slots.append((nid, level_map[value]))