From: Daniel Karbach Date: Sat, 14 May 2022 13:44:17 +0000 (+0200) Subject: wait for seed generation before posting message X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=47033726a69270d991a496b433163b176ba58e71;p=alttp.git wait for seed generation before posting message --- diff --git a/app/Console/Commands/GenerateAosSeed.php b/app/Console/Commands/GenerateAosSeed.php new file mode 100644 index 0000000..77fd376 --- /dev/null +++ b/app/Console/Commands/GenerateAosSeed.php @@ -0,0 +1,101 @@ +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; + } +} diff --git a/app/DiscordAppCommands/AosrPresetCommand.php b/app/DiscordAppCommands/AosrPresetCommand.php index 6c694ca..9a537db 100644 --- a/app/DiscordAppCommands/AosrPresetCommand.php +++ b/app/DiscordAppCommands/AosrPresetCommand.php @@ -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', diff --git a/app/Http/Controllers/AosSeedController.php b/app/Http/Controllers/AosSeedController.php index 9d35bc0..7c7e5f9 100644 --- a/app/Http/Controllers/AosSeedController.php +++ b/app/Http/Controllers/AosSeedController.php @@ -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 index bd0d73c..0000000 --- a/app/Jobs/GenerateAosSeed.php +++ /dev/null @@ -1,100 +0,0 @@ -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; - -} diff --git a/app/Models/AosSeed.php b/app/Models/AosSeed.php index b0b1ee7..f1a3d4a 100644 --- a/app/Models/AosSeed.php +++ b/app/Models/AosSeed.php @@ -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); }