--- /dev/null
+from subprocess import run
+from shutil import which
+from os import environ
+from pathlib import PurePath
+
+__programs: dict[str, str] = None
+
+def program(program: str) -> str:
+ global __programs
+
+ if (__programs == None):
+ __programs = {}
+
+ if (program not in __programs):
+ __programs[program] = which(program)
+
+ return __programs[program]
+
+def dosbox(dir: PurePath, link: PurePath) -> int:
+ if (program("app.sh") != None):
+ cmd = [ program("app.sh"),"--wait","dosbox","--link",link.as_posix() ]
+ elif(program("dosbox") != None):
+ cmd = [ program("dosbox") ]
+ else:
+ raise RuntimeError("DosBox not found")
+
+ base = dir.joinpath("base.conf")
+ if (base.exists()):
+ cmd.append("-conf")
+ cmd.append(base.as_posix())
+ cmd.append("-conf")
+ cmd.append(dir.joinpath("start.conf").as_posix())
+
+ return run(cmd, cwd=dir).returncode
+
+def start_sh(start: PurePath) -> int:
+ env = environ.copy()
+
+ if (program("launch.sh") != None):
+ cmd = [ program("launch.sh"), "games", "--dlink", start.as_posix() ]
+ env["OPTS"] = "--entrypoint=bash"
+ else:
+ cmd = [ start.as_posix() ]
+
+
+ return run(cmd, cwd=start.parent, env=env).returncode
+
+def wine(dir: PurePath) -> int:
+ env = environ.copy()
+
+ wine_bat = dir.joinpath("wine.bat").as_posix()
+ wine_prefix = dir.joinpath("wine.prefix").as_posix()
+
+ if (program("launch.sh") != None):
+ cmd = [ program("launch.sh"), "wine", "--dlink", wine_bat ]
+ env["OPTS"] = "-e WINEPREFIX='" + wine_prefix.replace("'", "\\'") + "'"
+ elif (program("wine") != None):
+ cmd = [ "wine", wine_bat ]
+ else:
+ raise RuntimeError("wine not found")
+
+
+ return run(cmd, cwd=dir, env=env).returncode
+
from ..game import Game
class Support:
- programs: dict[str, str] = None
-
"""Can detect and start games."""
- def __init__(self):
- pass
-
+
def supports(self, game: Game) -> bool:
return False
def start(self, game: Game, params: list[str] = []):
if (not self.supports(game)):
raise RuntimeError("Unsupported game was called: " + game.name)
-
- def program(name: str) -> str:
- if (Support.programs == None):
- Support.programs = {}
-
- if (name not in Support.programs):
- Support.programs[name] = which(name)
+
+ def running(self, game: Game):
+ print("Running", game.name)
- return Support.programs[name]
+ def error(self, game: Game, rc: int):
+ print("\nError when running", game.name + ":", "RC", rc)
-from subprocess import run
-from shutil import which
-
-from . import Support
-from ..game import Game
+from . import Support
+from .commands import dosbox
+from ..game import Game
class SupportDos(Support):
"""Supports DOS games via DosBox."""
- def __init__(self):
- pass
-
+
def supports(self, game: Game):
return game.dir.joinpath("start.conf").exists()
def start(self, game: Game, params: list[str] = []):
- dir = game.dir.resolve()
- link_dir = self.get_link_dir(game).resolve()
-
- if (Support.program("app.sh") != None):
- cmd = [
- Support.program("app.sh"),
- "--wait", "dosbox", "--link", link_dir.as_posix()
- ]
- elif (Support.program("dosbox") != None):
- cmd = [ Support.program("dosbox") ]
- else:
- raise RuntimeError("DosBox not found")
-
- base = dir.joinpath("base.conf")
- if (base.exists()):
- cmd.append("-conf")
- cmd.append(base.as_posix())
- cmd.append("-conf")
- cmd.append(dir.joinpath("start.conf").as_posix())
-
- print("Running", game.name)
- rep = run(cmd, cwd=dir)
- if (rep.returncode != 0):
- print("\nError when running", game.name, ": RC", rep.returncode)
-
- def get_link_dir(self, game: Game) -> str:
- return game.dir
+ self.running(game)
+ rep = dosbox(game.dir.resolve(), game.dir.resolve())
+ if (rep != 0):
+ self.error(game, rep)
-from random import random
-from math import floor
-from os import environ
-from pathlib import Path
-from subprocess import run
-from shutil import which
-
-from . import Support
-from ..game import Game
+from . import Support
+from .commands import start_sh
+from ..game import Game
class SupportExt(Support):
"""Supports external games via the 'games' docker or natively."""
- def __init__(self):
- pass
def supports(self, game: Game):
return game.dir.joinpath("start.sh").exists()
def start(self, game: Game, params: list[str] = []):
- dir = game.dir.resolve()
-
- env = environ.copy()
-
- ffile = None
- if (Support.program("launch.sh") != None):
- tfile = Path(
- "/tmp/shared/.game-"
- + "{0:6d}".format(floor(random() * 1000000))
- + ".sh"
- )
- with open(tfile, 'w', encoding="utf-8") as data:
- data.write("#!/bin/sh\n")
- data.write("cd '" + dir.as_posix() + "'\n")
- data.write("./start.sh\n")
- tfile.chmod(0o777)
- env["OPTS"] = "--entrypoint=" + tfile.as_posix()
- cmd = [
- Support.program("launch.sh"),
- "games", "--link", dir.as_posix()
- ]
- else:
- cmd = [ dir.joinpath("start.sh").as_posix() ]
-
- print("Running", game.name)
- rep = run(cmd, cwd=dir, env=env)
- if (rep.returncode != 0):
- print("\nError when running", game.name, ": RC", rep.returncode)
+ start = game.dir.resolve().joinpath("start.sh")
- if (tfile != ""):
- tfile.unlink()
+ self.running(game)
+ rep = start_sh(start)
+ if (rep != 0):
+ self.error(game, rep)
-from random import random
-from math import floor
-from os import environ
-from pathlib import Path
-from subprocess import run
-from shutil import which
-
-from . import Support
-from ..game import Game
+from . import Support
+from .commands import start_sh
+from ..game import Game
class SupportGog(Support):
"""Supports GoG games via the 'games' docker or natively."""
- def __init__(self):
- pass
def supports(self, game: Game):
return game.dir.joinpath("gameinfo").exists()
def start(self, game: Game, params: list[str] = []):
- dir = game.dir.resolve()
+ start = game.dir.resolve().joinpath("start.sh")
- if (not dir.joinpath("start.sh").exists()):
+ if (not start.exists()):
raise RuntimeError("GoG game without a start.sh script")
- env = environ.copy()
-
- tfile = None
- if (Support.program("launch.sh") != None):
- tfile = Path(
- "/tmp/shared/.game-"
- + "{0:6d}".format(floor(random() * 1000000))
- + ".sh"
- )
- with open(tfile, 'w', encoding="utf-8") as data:
- data.write("#!/bin/sh\n")
- data.write("cd '" + dir.as_posix() + "'\n")
- data.write("./start.sh\n")
- tfile.chmod(0o777)
- env["OPTS"] = "--entrypoint=" + tfile.as_posix()
- cmd = [
- Support.program("launch.sh"),
- "games", "--link", dir.as_posix()
- ]
- else:
- cmd = [ dir.joinpath("start.sh").as_posix() ]
-
- # GoG launcher already does this:
- # print("Running", game.name)
- rep = run(cmd, cwd=dir, env=env)
- if (rep.returncode != 0):
- print("\nError when running", game.name, ": RC", rep.returncode)
-
- if (tfile != None):
- tfile.unlink()
-
+ # No running, GoG launcher already does it:
+ #self.running(game)
+ rep = start_sh(start)
+ if (rep != 0):
+ self.error(game, rep)
-from random import random
-from math import floor
-from os import environ
-from pathlib import Path
-from subprocess import run
-from shutil import which
-
-from . import Support
-from ..game import Game
+from . import Support
+from .commands import wine
+from ..game import Game
class SupportWin(Support):
"""Supports Windows games via wine."""
- def __init__(self):
- pass
def supports(self, game: Game):
return game.dir.joinpath("wine.bat").exists()
if (not dir.joinpath("wine.prefix").exists()):
raise RuntimeError("Windows game without a wine.prefix")
- wine_bat = dir.joinpath("wine.bat")
- wine_prefix = dir.joinpath("wine.prefix").as_posix()
-
- env = environ.copy()
-
- tfile = None
- if (Support.program("launch.sh") != None):
- env["OPTS"] = "-e WINEPREFIX='" +wine_prefix.replace("'","\\'")+ "'"
- cmd = [
- Support.program("launch.sh"),
- "wine", "--dlink", wine_bat
- ]
- else:
- env["WINEPREFIX"] = wine_prefix
- cmd = [ "wine", wine_bat ]
-
- print("Running", game.name)
- rep = run(cmd, env=env)
- if (rep.returncode != 0):
- print("\nError when running", game.name, ": RC", rep.returncode)
-
+ self.running(game)
+ rep = wine(dir)
+ if (rep != 0):
+ self.error(game, rep)
-from pathlib import PurePath
-from subprocess import run
-from shutil import which
+from . import Support
+from .commands import dosbox
+from ..game import Game
-from . import Support, SupportDos
-from ..game import Game
-
-class SupportWin31(SupportDos):
+class SupportWin31(Support):
"""Supports Windows 3.1 games via DosBox."""
-
- # TODO: must be tried befoer SupportDos
def supports(self, game: Game):
return (
and game.dir.joinpath("C", "WINDOWS").exists()
)
- def get_link_dir(self, game: Game) -> PurePath:
- return game.library.dir
+ def start(self, game: Game, params: list[str] = []):
+ self.running(game)
+ rep = dosbox(game.dir.resolve(), game.library.dir.resolve())
+ if (rep != 0):
+ self.error(game, rep)