From 7925281cebb2a92e7de66ff89f46bf79524f2fc0 Mon Sep 17 00:00:00 2001 From: yrriban Date: Fri, 1 Aug 2025 02:03:30 -0400 Subject: [PATCH 1/4] Add "run it back" command to continue a practice run after failing a demo. --- dcc/doom_base.py | 5 +++-- dcc/rib.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ setup.py | 1 + 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 dcc/rib.py diff --git a/dcc/doom_base.py b/dcc/doom_base.py index e6e3024..cc96e57 100644 --- a/dcc/doom_base.py +++ b/dcc/doom_base.py @@ -92,7 +92,7 @@ class WadMap(Wad): def name_string(self): return "" if self._name is None else "_" + self._name - def dsda_preamble(self): + def dsda_preamble(self, warp=True): args = ["-iwad", self.iwad_path] wads = self.load_order() @@ -105,7 +105,8 @@ class WadMap(Wad): args = args + ["-complevel", str(self.complevel())] args = args + ["-skill", "4"] - args = args + ["-warp", self.map] + if warp: + args = args + ["-warp", self.map] args = args + self.options() return args diff --git a/dcc/rib.py b/dcc/rib.py new file mode 100644 index 0000000..aca28fd --- /dev/null +++ b/dcc/rib.py @@ -0,0 +1,44 @@ +import dcc.doom_base +import pathlib +import os +import subprocess +import time + + +class RIB(dcc.doom_base.WadMap): + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument("-s", "--secs_before", default=10) + return parser + + # TODO: the root path should probably be configurable. + def take_action(self, parsed_args): + demo = "" + dt = 0 + demodir = ( + pathlib.Path.home() / + ".dsda-doom" / + "dsda_doom_data" / + self.iwad_path.stem.lower() + ) + for w in self.load_order(): + demodir = demodir.joinpath(w.stem.lower()) + demodir = demodir / "failed_demos" + + for f in demodir.glob(f"*map{self.map}*", case_sensitive=False): + st = os.stat(f) + if st.st_mtime > dt: + demo = f + dt = st.st_mtime + + if demo == "": + raise Exception( + f"no failed demos found for wad {parsed_args.wad} " + + f"and map {parsed_args.map} (tried to look in {demodir})" + ) + + subprocess.run( + [self.dsda] + self.dsda_preamble(warp=False) + + ["-playdemo", demo] + + ["-skiptic", str(-35 * parsed_args.secs_before)] + ) diff --git a/setup.py b/setup.py index 6d11056..b58211a 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,7 @@ setup( 'dcc': [ 'play = dcc.play:Play', 'record = dcc.record:Record', + 'rib = dcc.rib:RIB', 'fabricate = dcc.fabricate:Fabricate', 'put = dcc.put:Put', 'pb = dcc.pb:PB', From 1ee4ea4dc6bad2704951387d0fe622c57135bff2 Mon Sep 17 00:00:00 2001 From: yrriban Date: Fri, 1 Aug 2025 02:05:05 -0400 Subject: [PATCH 2/4] Universally use double quotes for strings. --- dcc/config.py | 4 ++-- dcc/doom_base.py | 10 +++++----- setup.py | 52 ++++++++++++++++++++++++------------------------ 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/dcc/config.py b/dcc/config.py index cd70b4e..7fba22b 100644 --- a/dcc/config.py +++ b/dcc/config.py @@ -11,8 +11,8 @@ class Base(Command): def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( - '--doom', default=pathlib.Path.home().joinpath("doom")) - parser.add_argument('--config-name', default='config.toml') + "--doom", default=pathlib.Path.home().joinpath("doom")) + parser.add_argument("--config-name", default="config.toml") return parser def init_base(self, parsed_args): diff --git a/dcc/doom_base.py b/dcc/doom_base.py index cc96e57..d3400ff 100644 --- a/dcc/doom_base.py +++ b/dcc/doom_base.py @@ -10,7 +10,7 @@ import tomlkit class Wad(dcc.config.Base): def get_parser(self, prog_name): parser = super().get_parser(prog_name) - parser.add_argument('wad') + parser.add_argument("wad") return parser def wad_init(self, parsed_args): @@ -53,7 +53,7 @@ class Wad(dcc.config.Base): def load_order(self): wads = self._config.get("load_order") if wads is None: - wads = sorted(self.pwad_path.glob('*.wad', case_sensitive=False)) + wads = sorted(self.pwad_path.glob("*.wad", case_sensitive=False)) else: wads = [self.pwad_path.joinpath(wad) for wad in wads] return wads @@ -73,8 +73,8 @@ class Wad(dcc.config.Base): class WadMap(Wad): def get_parser(self, prog_name): parser = super().get_parser(prog_name) - parser.add_argument('map') - parser.add_argument('-n', '--name', '--demo_name') + parser.add_argument("map") + parser.add_argument("-n", "--name", "--demo_name") return parser def run(self, parsed_args): @@ -99,7 +99,7 @@ class WadMap(Wad): if len(wads) > 0: args = args + ["-file"] + wads - dehs = sorted(self.pwad_path.glob('*.deh', case_sensitive=False)) + dehs = sorted(self.pwad_path.glob("*.deh", case_sensitive=False)) if len(dehs) > 0: args = args + ["-deh"] + dehs diff --git a/setup.py b/setup.py index b58211a..9222cf5 100644 --- a/setup.py +++ b/setup.py @@ -1,42 +1,42 @@ from setuptools import find_packages from setuptools import setup -PROJECT = 'dcc' +PROJECT = "dcc" -VERSION = '0.0.1' +VERSION = "0.0.1" -long_description = '' +long_description = "" setup( name=PROJECT, version=VERSION, - description='Doom Command Center', + description="Doom Command Center", long_description=long_description, - author='yrriban', - author_email='yrriban@gmail.com', - platforms=['Any'], - install_requires=['cliff'], + author="yrriban", + author_email="yrriban@gmail.com", + platforms=["Any"], + install_requires=["cliff"], packages=find_packages(), include_package_data=True, entry_points={ - 'console_scripts': ['dcc=dcc.main:main'], - 'dcc': [ - 'play = dcc.play:Play', - 'record = dcc.record:Record', - 'rib = dcc.rib:RIB', - 'fabricate = dcc.fabricate:Fabricate', - 'put = dcc.put:Put', - 'pb = dcc.pb:PB', - 'ss = dcc.ss:SS', - 'extract = dcc.extract:Extract', - 'fetch = dcc.fetch:Fetch', - 'text = dcc.text:Text', - 'thumb = dcc.thumb:Thumb', - 'dsda = dcc.dsda:DSDA', - 'eureka = dcc.eureka:Eureka', - 'ls = dcc.ls:List', - 'configure = dcc.configure:Configure', - 'concat = dcc.concat:Concat', + "console_scripts": ["dcc=dcc.main:main"], + "dcc": [ + "play = dcc.play:Play", + "record = dcc.record:Record", + "rib = dcc.rib:RIB", + "fabricate = dcc.fabricate:Fabricate", + "put = dcc.put:Put", + "pb = dcc.pb:PB", + "ss = dcc.ss:SS", + "extract = dcc.extract:Extract", + "fetch = dcc.fetch:Fetch", + "text = dcc.text:Text", + "thumb = dcc.thumb:Thumb", + "dsda = dcc.dsda:DSDA", + "eureka = dcc.eureka:Eureka", + "ls = dcc.ls:List", + "configure = dcc.configure:Configure", + "concat = dcc.concat:Concat", ], }, zip_safe=False, From 70e1a3a39ea44b5924989a92c2010619634d908c Mon Sep 17 00:00:00 2001 From: yrriban Date: Fri, 1 Aug 2025 02:07:06 -0400 Subject: [PATCH 3/4] PEP 8 compliance. --- dcc/fetch.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dcc/fetch.py b/dcc/fetch.py index 181f83f..ed2aaca 100644 --- a/dcc/fetch.py +++ b/dcc/fetch.py @@ -54,11 +54,13 @@ class Fetch(dcc.config.Base): if fetcher is None: with urllib.request.urlopen(url) as response: return json.loads(response.read()) - + fetcher_path = shutil.which(fetcher) if fetcher_path is None: raise Exception(f"Fetch util {fetcher} not found on PATH.") - proc = subprocess.run([fetcher_path, url], capture_output=True, check = True) + proc = subprocess.run( + [fetcher_path, url], + capture_output=True, check=True + ) return json.loads(proc.stdout) - From e4c5c8b475d7da11d7eb7ab089b70d9d58e18f3c Mon Sep 17 00:00:00 2001 From: yrriban Date: Fri, 1 Aug 2025 02:09:15 -0400 Subject: [PATCH 4/4] Skip the warp flag when generating the dsda text file. This causes negative tics to work, for whatever reason. --- dcc/dsda.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dcc/dsda.py b/dcc/dsda.py index 9ad07f5..8fb1e00 100644 --- a/dcc/dsda.py +++ b/dcc/dsda.py @@ -21,12 +21,10 @@ class DSDA(dcc.doom_base.WadMap): command = [self.dsda] if shutil.which("xvfb-run") is not None: command = ["xvfb-run"] + command - # TODO: negative tics should seek from the end, but this doesn't - # seem to work. subprocess.run( - command + self.dsda_preamble() + [ - "-fastdemo", dip, "-nosound", "-skiptic", - "999999999", "-export_text_file" + command + self.dsda_preamble(warp=False) + [ + "-fastdemo", dip, "-nosound", + "-skiptic", "-1", "-export_text_file" ] ) editor = "nano"