]> git.localhorst.tv Git - alttp.git/blob - app/Console/Commands/GenerateAosSeed.php
c51ce29a09a04a7acfe55e44fa6d1ab950994d84
[alttp.git] / app / Console / Commands / GenerateAosSeed.php
1 <?php
2
3 namespace App\Console\Commands;
4
5 use App\Beat\Encoder;
6 use App\Models\AosSeed;
7 use HeadlessChromium\BrowserFactory;
8 use Illuminate\Console\Command;
9 use Illuminate\Support\Facades\Storage;
10
11 class GenerateAosSeed extends Command
12 {
13         /**
14          * The name and signature of the console command.
15          *
16          * @var string
17          */
18         protected $signature = 'aos:generate {id}';
19
20         /**
21          * The console command description.
22          *
23          * @var string
24          */
25         protected $description = 'Generate AoS seed';
26
27         /**
28          * Execute the console command.
29          *
30          * @return int
31          */
32         public function handle()
33         {
34                 $seed = AosSeed::findOrFail($this->argument('id'));
35                 $seed->status = 'generating';
36                 $seed->error_detail = null;
37                 $seed->save();
38
39                 $stage = 'initial';
40                 try {
41                         $temp_dir = sys_get_temp_dir();
42
43                         $params = array_merge(['seed' => $seed->seed], $seed->settings);
44                         $url = config('aos.surge_url').'/?'.http_build_query($params, '', '&');
45
46                         $fac = new BrowserFactory('chromium');
47                         $fac->addOptions(['noSandbox' => true]);
48                         $browser = $fac->createBrowser();
49
50                         $stage = 'loading page';
51                         $page = $browser->createPage();
52                         $page->setDownloadPath($temp_dir);
53                         $page->navigate($url)->waitForNavigation();
54
55                         $stage = 'selecting rom';
56                         $fileInput = $page->dom()->querySelector('input[type=file]');
57                         $fileInput->sendFile(config('aos.base_rom'));
58                         $page->waitUntilContainsElement('select');
59
60                         $stage = 'clicking randomize';
61                         $page->mouse()->find('button', 2)->click();
62                         $page->waitUntilContainsElement('a[download]');
63
64                         $stage = 'clicking download';
65                         $page->dom()->querySelector('a[download]')->setAttributeValue('download', $seed->hash.'.gba');
66                         $page->mouse()->find('a[download]')->click();
67
68                         $stage = 'waiting for rom';
69                         $romFile = $temp_dir.'/'.$seed->hash.'.gba';
70                         for ($i = 0; $i < 100; ++$i) {
71                                 clearstatcache();
72                                 if (is_file($romFile) && filesize($romFile) >= 8388608) {
73                                         break;
74                                 }
75                                 usleep(100_000);
76                         }
77
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);
82                         unlink($romFile);
83
84                         $stage = 'done';
85                         $seed->status = 'generated';
86                         $seed->save();
87
88                         $browser->close();
89                 } catch (\Throwable $e) {
90                         $seed->status = 'error';
91                         $seed->error_detail = [
92                                 'stage' => $stage,
93                                 'type' => get_class($e),
94                                 'message' => $e->getMessage(),
95                         ];
96                         $seed->save();
97                         return 1;
98                 }
99
100                 return 0;
101         }
102 }