linux-mod-manager/lmm/cli.py

137 lines
3.7 KiB
Python

import os
from typing import Optional
from lmm.const import LMM_GAMES_PATH
from lmm.games.config import load_game_configs
from lmm.games.game import Game
from lmm.games.bg3 import GAME_NAME as BG3
from lmm.mods.bg3 import install_mod as bg3_install_mod
import click
def get_game_by_name(name: str) -> Optional[Game]:
games = load_game_configs()
for game in games:
if game.name == name:
return game
return None
@click.group()
@click.pass_context
def cli(ctx):
if ctx.invoked_subcommand is None:
click.echo("Invoked without a subcommand")
@cli.command()
@click.option("-g", "--game", required=True)
@click.option("-p", "--profile", required=True)
def launch(game: str, profile: str):
game = get_game_by_name(game)
if game is None:
click.echo("Game not found")
return
profile = game.get_profile_by_name(profile)
if profile is None:
click.echo("Profile not found")
return
runner = None
if profile.runner is not None:
runner = profile.runner
elif game.default_runner is not None:
runner = game.default_runner
if runner is None:
click.echo("Cannot launch profile as no runner or default runner is configured")
return
# Prepare mounts
mounts_ok = True
mounts = game.prepare_overlays(profile)
for mount in mounts:
result = mount.mount()
if result is None:
click.echo("Mount failed")
mounts_ok = False
break
print(f"Mounted overlayfs at {result}")
# Launch the game
if mounts_ok:
#runner.run()
#game.wait()
print(f"Stub runner: Would use {runner.__class__.__name__}")
# Unmount
for mount in mounts:
mount.unmount()
@cli.command()
@click.option("-g", "--game", required=True)
@click.option("-P", "--path", required=True)
def install(game: str, path: str):
install = {
BG3: bg3_install_mod,
}.get(game, None)
if install is None:
click.echo(f"Unknown game \"{game}\"")
return
install(Path(path))
@cli.command()
@click.option("-g", "--game")
def mods(game: Optional[str]):
if game is not None:
games = [game]
else:
games = [
item for item in os.listdir(LMM_GAMES_PATH) if (LMM_GAMES_PATH / item).is_dir()
]
for idx, game_name in enumerate(games):
click.echo(f"Installed mods for {game_name}:")
for item in os.listdir(LMM_GAMES_PATH / game_name):
path = LMM_GAMES_PATH / game_name / item
if not path.is_dir():
continue
click.echo(f"- {item}")
if idx < len(games) - 1:
click.echo()
@cli.command
def list():
games = load_game_configs()
for idx, game in enumerate(games):
if game.default_runner is not None:
default_runner_name = game.default_runner.__class__.__name__
else:
default_runner_name = "None"
click.echo(f"- {game.name}")
click.echo(f" {game.installation_path}")
click.echo(f" Can start: {game.can_start()}")
click.echo(f" Default runner: {default_runner_name}")
click.echo(" Profiles:")
for profile in game.profiles:
mods = ", ".join(profile.get_mod_names())
if profile.runner is not None:
runner_name = profile.runner.__class__.__name__
else:
runner_name = "None"
click.echo(f" - {profile.name}")
click.echo(f" Runner: {runner_name}")
click.echo(f" Mods: {mods}")
if idx < len(games) - 1:
click.echo()
def main():
cli()
if __name__ == "__main__":
cli()