]> git.localhorst.tv Git - alttp.git/commitdiff
wait for seed generation before posting message
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 14 May 2022 13:44:17 +0000 (15:44 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 14 May 2022 13:44:17 +0000 (15:44 +0200)
app/Console/Commands/GenerateAosSeed.php [new file with mode: 0644]
app/DiscordAppCommands/AosrPresetCommand.php
app/Http/Controllers/AosSeedController.php
app/Jobs/GenerateAosSeed.php [deleted file]
app/Models/AosSeed.php

diff --git a/app/Console/Commands/GenerateAosSeed.php b/app/Console/Commands/GenerateAosSeed.php
new file mode 100644 (file)
index 0000000..77fd376
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Beat\Encoder;
+use App\Models\AosSeed;
+use HeadlessChromium\BrowserFactory;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Storage;
+
+class GenerateAosSeed extends Command
+{
+       /**
+        * The name and signature of the console command.
+        *
+        * @var string
+        */
+       protected $signature = 'aos:generate {id}';
+
+       /**
+        * The console command description.
+        *
+        * @var string
+        */
+       protected $description = 'Generate AoS seed';
+
+       /**
+        * Execute the console command.
+        *
+        * @return int
+        */
+       public function handle()
+       {
+               $seed = AosSeed::findOrFail($this->argument('id'));
+               $seed->status = 'generating';
+               $seed->error_detail = null;
+               $seed->save();
+
+               $stage = 'initial';
+               try {
+                       $temp_dir = sys_get_temp_dir();
+
+                       $params = array_merge(['seed' => $seed->seed], $seed->settings);
+                       $url = config('aos.surge_url').'/?'.http_build_query($params, '', '&');
+
+                       $fac = new BrowserFactory('chromium');
+                       $browser = $fac->createBrowser();
+
+                       $stage = 'loading page';
+                       $page = $browser->createPage();
+                       $page->setDownloadPath($temp_dir);
+                       $page->navigate($url)->waitForNavigation();
+
+                       $stage = 'selecting rom';
+                       $fileInput = $page->dom()->querySelector('input[type=file]');
+                       $fileInput->sendFile(config('aos.base_rom'));
+                       $page->waitUntilContainsElement('select');
+
+                       $stage = 'clicking randomize';
+                       $page->mouse()->find('button', 2)->click();
+                       $page->waitUntilContainsElement('a[download]');
+
+                       $stage = 'clicking download';
+                       $page->dom()->querySelector('a[download]')->setAttributeValue('download', $seed->hash.'.gba');
+                       $page->mouse()->find('a[download]')->click();
+
+                       $stage = 'waiting for rom';
+                       $romFile = $temp_dir.'/'.$seed->hash.'.gba';
+                       for ($i = 0; $i < 100; ++$i) {
+                               clearstatcache();
+                               if (is_file($romFile) && filesize($romFile) >= 8388608) {
+                                       break;
+                               }
+                               usleep(100_000);
+                       }
+
+                       $stage = 'calculating patch';
+                       $encoder = new Encoder(file_get_contents(config('aos.base_rom')));
+                       $patch = $encoder->createPatch(file_get_contents($romFile));
+                       Storage::disk('aos-seeds')->put($seed->hash.'.bps', $patch);
+                       unlink($romFile);
+
+                       $stage = 'done';
+                       $seed->status = 'generated';
+                       $seed->save();
+
+                       $browser->close();
+               } catch (\Throwable $e) {
+                       $seed->status = 'error';
+                       $seed->error_detail = [
+                               'stage' => $stage,
+                               'type' => get_class($e),
+                               'message' => $e->getMessage(),
+                       ];
+                       $seed->save();
+                       return 1;
+               }
+
+               return 0;
+       }
+}
index 6c694caf26677a4c980ef06d046f6f7387788003..9a537db8006452ed349a99cc7a1fec099746d856 100644 (file)
@@ -5,9 +5,6 @@ namespace App\DiscordAppCommands;
 use App\Models\AosSeed;
 use Discord\Builders\MessageBuilder;
 use Discord\Discord;
-use Discord\Parts\Embed\Embed;
-use Discord\Parts\Embed\Field;
-use Discord\Parts\Embed\Footer;
 use Discord\Parts\Interactions\Interaction;
 
 class AosrPresetCommand {
@@ -65,41 +62,33 @@ class AosrPresetCommand {
                                $presetName = $interaction->data->options['preset']->options['preset']->value;
                                $race =  isset($interaction->data->options['preset']->options['race'])
                                        ? $interaction->data->options['preset']->options['race']->value : false;
-                               $message = MessageBuilder::new();
                                if (isset(static::$presets[$presetName])) {
                                        $preset = static::$presets[$presetName];
                                        $seed = AosSeed::generateSurge($presetName, $preset['settings'], $race);
 
-                                       $embed = new Embed($discord, [
-                                               'fields' => [
-                                                       new Field($discord, [ 'name' => 'Generator', 'value' => 'This seed has been generated with fusecv\'s randomizer on aosrando.surge.sh.' ]),
-                                                       new Field($discord, [ 'name' => 'Preset', 'value' => $preset['name'], 'inline' => true ]),
-                                                       new Field($discord, [ 'name' => 'Seed', 'value' => $race ? 'secret' : $seed->seed, 'inline' => true ]),
-                                                       new Field($discord, [ 'name' => 'Logic', 'value' => $preset['settings']['logic'], 'inline' => true ]),
-                                                       new Field($discord, [ 'name' => 'Area', 'value' => $preset['settings']['area'], 'inline' => true ]),
-                                                       new Field($discord, [ 'name' => 'Boss', 'value' => $preset['settings']['boss'], 'inline' => true ]),
-                                                       new Field($discord, [ 'name' => 'Enemy', 'value' => $preset['settings']['enemy'], 'inline' => true ]),
-                                                       new Field($discord, [ 'name' => 'Permalink', 'value' => $seed->permalink ]),
-                                               ],
-                                               'footer' => new Footer($discord, [
-                                                       'text' => 'Grün',
-                                               ]),
-                                               'timestamp' => now(),
-                                               'title' => 'AoSRando Seed',
-                                               'type' => 'rich',
-                                               'url' => $seed->permalink,
-                                       ]);
-                                       $message->addEmbed($embed);
+                                       $process = $seed->createProcess();
+                                       $process->on('exit', function() use ($discord, $interaction, $seed) {
+                                               $seed = $seed->fresh();
+
+                                               $embed = $seed->createEmbed($discord);
+                                               $message = MessageBuilder::new();
+                                               $message->addEmbed($embed);
+
+                                               $interaction->updateOriginalResponse($message);
+                                       });
+
+                                       $process->start($discord->getLoop());
                                } else {
+                                       $message = MessageBuilder::new();
                                        $message->setContent('unknown preset '.$presetName);
+                                       $interaction->updateOriginalResponse($message);
                                }
-                               $interaction->updateOriginalResponse($message);
                        });
                        return true;
                });
        }
 
-       private static $presets = [
+       public static $presets = [
                'Normal' => [
                        'name' => 'Normal',
                        'value' => 'Normal',
index 9d35bc09fd0fcc44324a94178665f0158c974a9f..7c7e5f9fdaf04012e1f52def459b52bfabc8b88e 100644 (file)
@@ -2,9 +2,9 @@
 
 namespace App\Http\Controllers;
 
-use App\Jobs\GenerateAosSeed;
 use App\Models\AosSeed;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Artisan;
 
 class AosSeedController extends Controller
 {
@@ -28,7 +28,7 @@ class AosSeedController extends Controller
                if ($seed->status == 'error') {
                        $seed->status = 'pending';
                        $seed->save();
-                       GenerateAosSeed::dispatch($seed)->onConnection('database');
+                       Artisan::call('aos:generate '.intval($seed->id));
                }
 
                return $seed->toJson();
diff --git a/app/Jobs/GenerateAosSeed.php b/app/Jobs/GenerateAosSeed.php
deleted file mode 100644 (file)
index bd0d73c..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-namespace App\Jobs;
-
-use App\Beat\Encoder;
-use App\Models\AosSeed;
-use HeadlessChromium\BrowserFactory;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldBeUnique;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Foundation\Bus\Dispatchable;
-use Illuminate\Queue\InteractsWithQueue;
-use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Storage;
-
-class GenerateAosSeed implements ShouldQueue
-{
-       use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
-
-       /**
-        * Create a new job instance.
-        *
-        * @return void
-        */
-       public function __construct(AosSeed $seed)
-       {
-               $this->seed = $seed;
-       }
-
-       /**
-        * Execute the job.
-        *
-        * @return void
-        */
-       public function handle()
-       {
-               $stage = 'initial';
-               try {
-                       $temp_dir = sys_get_temp_dir();
-
-                       $seed = $this->seed;
-                       $params = array_merge(['seed' => $seed->seed], $seed->settings);
-                       $url = config('aos.surge_url').'/?'.http_build_query($params, '', '&');
-
-                       $fac = new BrowserFactory('chromium');
-                       $browser = $fac->createBrowser();
-
-                       $stage = 'loading page';
-                       $page = $browser->createPage();
-                       $page->setDownloadPath($temp_dir);
-                       $page->navigate($url)->waitForNavigation();
-
-                       $stage = 'selecting rom';
-                       $fileInput = $page->dom()->querySelector('input[type=file]');
-                       $fileInput->sendFile(config('aos.base_rom'));
-                       $page->waitUntilContainsElement('select');
-
-                       $stage = 'clicking randomize';
-                       $page->mouse()->find('button', 2)->click();
-                       $page->waitUntilContainsElement('a[download]');
-
-                       $stage = 'clicking download';
-                       $page->dom()->querySelector('a[download]')->setAttributeValue('download', $seed->hash.'.gba');
-                       $page->mouse()->find('a[download]')->click();
-
-                       $stage = 'waiting for rom';
-                       $romFile = $temp_dir.'/'.$seed->hash.'.gba';
-                       for ($i = 0; $i < 100; ++$i) {
-                               clearstatcache();
-                               if (is_file($romFile) && filesize($romFile) >= 8388608) {
-                                       break;
-                               }
-                               usleep(100_000);
-                       }
-
-                       $stage = 'calculating patch';
-                       $encoder = new Encoder(file_get_contents(config('aos.base_rom')));
-                       $patch = $encoder->createPatch(file_get_contents($romFile));
-                       Storage::disk('aos-seeds')->put($seed->hash.'.bps', $patch);
-                       unlink($romFile);
-
-                       $stage = 'done';
-                       $seed->status = 'generated';
-                       $seed->save();
-
-                       $browser->close();
-               } catch (\Throwable $e) {
-                       $seed->status = 'error';
-                       $seed->error_detail = [
-                               'stage' => $stage,
-                               'type' => get_class($e),
-                               'message' => $e->getMessage(),
-                       ];
-                       $seed->save();
-               }
-       }
-
-       protected $seed;
-
-}
index b0b1ee743669f76ca722091ab56eeeca99b47921..f1a3d4a38e36ed223dfe1dde3f62868d42bee79a 100644 (file)
@@ -2,10 +2,15 @@
 
 namespace App\Models;
 
-use App\Jobs\GenerateAosSeed;
+use App\DiscordAppCommands\AosrPresetCommand;
+use Discord\Discord;
+use Discord\Parts\Embed\Embed;
+use Discord\Parts\Embed\Field;
+use Discord\Parts\Embed\Footer;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Str;
+use React\ChildProcess\Process;
 
 class AosSeed extends Model
 {
@@ -22,10 +27,46 @@ class AosSeed extends Model
                $seed->settings = $settings;
                $seed->status = 'pending';
                $seed->save();
-               GenerateAosSeed::dispatch($seed)->onConnection('database');
                return $seed;
        }
 
+       public function createProcess() {
+               return new Process('php artisan aos:generate '.intval($this->id), base_path());
+       }
+
+       public function createEmbed(Discord $discord) {
+               $preset = AosrPresetCommand::$presets[$this->preset];
+
+               $fields = [
+                       new Field($discord, [ 'name' => 'Generator', 'value' => 'This seed has been generated with fusecv\'s randomizer on aosrando.surge.sh.' ]),
+                       new Field($discord, [ 'name' => 'Preset', 'value' => $preset['name'], 'inline' => true ]),
+               ];
+
+               if (!$this->race) {
+                       $fields[] = new Field($discord, [ 'name' => 'Seed', 'value' => $this->seed, 'inline' => true ]);
+               }
+
+               if (!$this->mystery) {
+                       $fields[] = new Field($discord, [ 'name' => 'Logic', 'value' => $this->settings['logic'], 'inline' => true ]);
+                       $fields[] = new Field($discord, [ 'name' => 'Area', 'value' => $this->settings['area'], 'inline' => true ]);
+                       $fields[] = new Field($discord, [ 'name' => 'Boss', 'value' => $this->settings['boss'], 'inline' => true ]);
+                       $fields[] = new Field($discord, [ 'name' => 'Enemy', 'value' => $this->settings['enemy'], 'inline' => true ]);
+               }
+
+               $fields[] = new Field($discord, [ 'name' => 'Permalink', 'value' => $this->permalink ]);
+
+               return new Embed($discord, [
+                       'fields' => $fields,
+                       'footer' => new Footer($discord, [
+                               'text' => 'Grün',
+                       ]),
+                       'timestamp' => now(),
+                       'title' => 'AoSRando Seed',
+                       'type' => 'rich',
+                       'url' => $this->permalink,
+               ]);
+       }
+
        public function getPermalinkAttribute() {
                return config('aos.url').'/h/'.rawurlencode($this->hash);
        }