From 67e4ac8a95e626b1050af3859b606a5d3117bc9b Mon Sep 17 00:00:00 2001 From: Some Dude <159159789+Curvature9761@users.noreply.github.com> Date: Thu, 31 Jul 2025 21:46:11 +0200 Subject: [PATCH 1/3] New subcommand --fromName Added a new subcommand --fromName=NAME It makes it possible to resume download from a specified name onwards. Very useful if previous downloads have aborted due to TimeOut. --- src/Command/DownloadCommand.php | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Command/DownloadCommand.php b/src/Command/DownloadCommand.php index ab0d4be..c092c55 100644 --- a/src/Command/DownloadCommand.php +++ b/src/Command/DownloadCommand.php @@ -127,6 +127,12 @@ protected function configure() mode: InputOption::VALUE_NONE, description: 'Remove downloaded files that failed hash check and try downloading it again.' ) + ->addOption( + name: 'fromName', + mode: InputOption::VALUE_REQUIRED, + description: 'Resume downloads starting from the game with this name' + ) + ; } @@ -166,9 +172,27 @@ protected function execute(InputInterface $input, OutputInterface $output): int $iterable = $this->getGames($input, $output, $this->ownedItemsManager); $downloadsToSkip = $input->getOption('skip-download'); $removeInvalid = $input->getOption('remove-invalid'); + $fromName = $input->getOption('fromName'); + $pastNameLoop = false; #Did we reach the game we want to continue from? + + if ($fromName !== null) { + // Trim whitespace and make sure it's at least 1 character + $fromName = trim($fromName); + if ($fromName === '' || strlen($fromName) < 1) { + throw new \InvalidArgumentException('--fromName must be a non-empty string.'); + } + } + + $this->dispatchSignals(); foreach ($iterable as $game) { + if (strcasecmp($fromName, $game->title) === 0) { #Iterate to the game name given with the FromIndex Parameter + $$pastNameLoop = true; + } elseif (!$pastNameLoop) { + continue; + } + $downloads = []; if (!$input->getOption('no-games')) { $downloads = [...$downloads, ...$game->downloads]; @@ -177,7 +201,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $downloads = [...$downloads, ...$game->extras]; } - foreach ($downloads as $download) { + foreach ($downloads as $download) { try { $this->retryService->retry(function (?Throwable $retryReason) use ( $removeInvalid, From 245152f7f099929be2d174358a69081fd3ac65d6 Mon Sep 17 00:00:00 2001 From: Some Dude <159159789+Curvature9761@users.noreply.github.com> Date: Thu, 31 Jul 2025 22:21:10 +0200 Subject: [PATCH 2/3] Bugfix Fixed a slight a slight bug. One $ to much. Added a output for skipped games. --- src/Command/DownloadCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Command/DownloadCommand.php b/src/Command/DownloadCommand.php index c092c55..2b16b35 100644 --- a/src/Command/DownloadCommand.php +++ b/src/Command/DownloadCommand.php @@ -188,8 +188,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->dispatchSignals(); foreach ($iterable as $game) { if (strcasecmp($fromName, $game->title) === 0) { #Iterate to the game name given with the FromIndex Parameter - $$pastNameLoop = true; + $pastNameLoop = true; } elseif (!$pastNameLoop) { + $io->writeln("{$game->title}: Skipping because we haven't found the given name --FromName={$fromName} Yet"); continue; } From d5041818c5cf90d9ca95ea00d4aa0add12cb7ccc Mon Sep 17 00:00:00 2001 From: Some Dude <159159789+Curvature9761@users.noreply.github.com> Date: Fri, 1 Aug 2025 00:27:46 +0200 Subject: [PATCH 3/3] Added FromIndex command I originally wanted to implement a fromIndex command aligned to the game command. Couldn't figure it out. Now had a new idea. Made a new version that is independent from the game output. But you can still now resume from an index number based on your last run. --- src/Command/DownloadCommand.php | 36 ++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/Command/DownloadCommand.php b/src/Command/DownloadCommand.php index 2b16b35..6268a4d 100644 --- a/src/Command/DownloadCommand.php +++ b/src/Command/DownloadCommand.php @@ -130,7 +130,12 @@ protected function configure() ->addOption( name: 'fromName', mode: InputOption::VALUE_REQUIRED, - description: 'Resume downloads starting from the game with this name' + description: 'Resume downloads starting from the game with this name. Mutally exclusive to fromIndex' + ) + ->addOption( + name: 'fromIndex', + mode: InputOption::VALUE_REQUIRED, + description: 'Resume downloads starting from the index number. Uses a internal number. Index can be incorrect if update has been made or the parameters are different. Mutally exclusive to --fromName' ) ; @@ -173,7 +178,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int $downloadsToSkip = $input->getOption('skip-download'); $removeInvalid = $input->getOption('remove-invalid'); $fromName = $input->getOption('fromName'); + $fromIndex = $input->getOption('fromIndex'); $pastNameLoop = false; #Did we reach the game we want to continue from? + $currentGameIndex = 0; #What is the current iteration in the foreach below? + + if ($fromName !== null && $fromIndex !== null) { + throw new \InvalidArgumentException('--fromName and --fromIndex are mutally exclusive.'); + } if ($fromName !== null) { // Trim whitespace and make sure it's at least 1 character @@ -183,13 +194,32 @@ protected function execute(InputInterface $input, OutputInterface $output): int } } + if ($fromIndex !== null) { + if (!is_numeric($fromIndex) || (int)$fromIndex < 0){ + throw new \InvalidArgumentException('--fromIndex must be a positive integer.'); + } + $fromIndex = (int)$fromIndex; + } + $this->dispatchSignals(); foreach ($iterable as $game) { - if (strcasecmp($fromName, $game->title) === 0) { #Iterate to the game name given with the FromIndex Parameter + + $io->writeln("Iterating [{$currentGameIndex}] | {$game->title}"); #Just outputting the current game index and title. Should probably refactored to abide by -v. But the spammy output is also a intentional feature for the user. + $currentGameIndex++; + + if (isset($fromIndex) && $fromIndex > 0) { + if ($fromIndex === 1) { + $pastNameLoop = true; + } + $fromIndex--; + continue; + } + + if (strcasecmp($fromName, $game->title) === 0 && !$pastNameLoop && strlen($fromName) > 0) { #Iterate to the game name given with the FromName Parameter $pastNameLoop = true; - } elseif (!$pastNameLoop) { + } elseif (!$pastNameLoop && strlen($fromName) > 0) { $io->writeln("{$game->title}: Skipping because we haven't found the given name --FromName={$fromName} Yet"); continue; }