3 namespace App\Console\Commands;
6 use App\Models\AosSeed;
7 use HeadlessChromium\BrowserFactory;
8 use Illuminate\Console\Command;
9 use Illuminate\Support\Facades\Storage;
11 class GenerateAosSeed extends Command
14 * The name and signature of the console command.
18 protected $signature = 'aos:generate {id}';
21 * The console command description.
25 protected $description = 'Generate AoS seed';
28 * Execute the console command.
32 public function handle()
34 $seed = AosSeed::findOrFail($this->argument('id'));
35 $seed->status = 'generating';
36 $seed->error_detail = null;
41 $temp_dir = sys_get_temp_dir();
43 $params = array_merge(['seed' => $seed->seed], $seed->settings);
44 $url = config('aos.surge_url').'/?'.http_build_query($params, '', '&');
46 $fac = new BrowserFactory('chromium');
47 $fac->addOptions(['noSandbox' => true]);
48 $browser = $fac->createBrowser();
50 $stage = 'loading page';
51 $page = $browser->createPage();
52 $page->setDownloadPath($temp_dir);
53 $page->navigate($url)->waitForNavigation();
55 $stage = 'selecting rom';
56 $fileInput = $page->dom()->querySelector('input[type=file]');
57 $fileInput->sendFile(config('aos.base_rom'));
58 $page->waitUntilContainsElement('select');
60 $stage = 'clicking randomize';
61 $page->mouse()->find('button', 2)->click();
62 $page->waitUntilContainsElement('a[download]');
64 $stage = 'clicking download';
65 $page->dom()->querySelector('a[download]')->setAttributeValue('download', $seed->hash.'.gba');
66 $page->mouse()->find('a[download]')->click();
68 $stage = 'waiting for rom';
69 $romFile = $temp_dir.'/'.$seed->hash.'.gba';
70 for ($i = 0; $i < 100; ++$i) {
72 if (is_file($romFile) && filesize($romFile) >= 8388608) {
78 $stage = 'calculating patch';
79 $encoder = new Encoder(file_get_contents(config('aos.base_rom')));
80 $patch = $encoder->createPatch(file_get_contents($romFile));
81 Storage::disk('aos-seeds')->put($seed->hash.'.bps', $patch);
85 $seed->status = 'generated';
89 } catch (\Throwable $e) {
90 $seed->status = 'error';
91 $seed->error_detail = [
93 'type' => get_class($e),
94 'message' => $e->getMessage(),