$what) { if ($what == 'auth' && (empty($AoWoWconf['auth']) || empty($AoWoWconf['auth']['host']))) continue; // init proper access for further setup if (DB::test($AoWoWconf[$what], $err)) { DB::load($idx, $AoWoWconf[$what]); switch ($idx) { case DB_AOWOW: if (DB::Aowow()->selectCell('SHOW TABLES LIKE ?', 'aowow_dbversion')) Cfg::load(); // first time load after successful db setup else $error[] = ' * '.$what.': doesn\'t seem to contain aowow tables!'; break; case DB_WORLD: if (!DB::World()->selectCell('SHOW TABLES LIKE ?', 'version')) $error[] = ' * '.$what.': doesn\'t seem to contain TrinityCore world tables!'; else if (DB::World()->selectCell('SELECT `cache_id` FROM `version`') < TDB_WORLD_MINIMUM_VER) $error[] = ' * '.$what.': TDB world db is structurally outdated! (min rev.: '.CLI::bold(TDB_WORLD_MINIMUM_VER).')'; break; default: // no further checks at this time } } else $error[] = ' * '.$what.': '.$err; } return empty($error); } function testSelf(array &$error) : bool { $error = []; $test = function(&$protocol, &$host, $testFile, &$rCode) { $res = get_headers($protocol.$host.$testFile, true); if (!preg_match("/HTTP\/[0-9\.]+\s+([0-9]+)/", $res[0], $m)) return false; $rCode = $m[1]; if ($rCode == 200) return true; if ($rCode == 301 || $rCode == 302) { if (!empty($res['Location']) && preg_match("/(https?:\/\/)(.*)".strtr($testFile, ['/' => '\/', '.' => '\.'])."/i", is_array($res['Location']) ? array_pop($res['Location']) : $res['Location'], $n)) { $protocol = $n[1]; $host = $n[2]; } return false; } $rCode = 0; return false; }; if (!DB::isConnected(DB_AOWOW)) { $error[] = ' * not connected to DB'; return false; } $prot = Cfg::get('FORCE_SSL') ? 'https://' : 'http://'; $cases = array( 'site_host' => [$prot, Cfg::get('SITE_HOST'), '/README.md'], 'static_host' => [$prot, Cfg::get('STATIC_HOST'), '/css/aowow.css'] ); foreach ($cases as $conf => [$protocol, $host, $testFile]) { if ($host) { if (!$test($protocol, $host, $testFile, $resp)) { if ($resp == 301 || $resp == 302) { CLI::write('self test received status '.CLI::bold($resp).' (page moved) for '.$conf.', pointing to: '.$protocol.$host.$testFile, CLI::LOG_WARN); if (!CLI::read(['x' => ['should '.CLI::bold($conf).' be set to '.CLI::bold($host).' and force_ssl be updated? (y/n)', true, true, '/y|n/i']], $uiYN) || !$uiYN || strtolower($uiYN['x']) == 'n') $error[] = ' * '.$protocol.$host.$testFile.' ['.$resp.']'; else { Cfg::set($conf, $host); Cfg::set('FORCE_SSL', $protocol == 'https://'); } CLI::write(); } else $error[] = ' * '.$protocol.$host.$testFile.' ['.$resp.']'; } } else $error[] = ' * '.strtoupper($conf).' is empty'; } return empty($error); } function testAcc(array &$error) : bool { $error = []; return !!DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE `userPerms` = 1'); } /********************/ /* get current step */ /********************/ $startStep = 0; if (file_exists('cache/firstrun')) { $rows = file('cache/firstrun'); if ((int)$rows[0] == AOWOW_REVISION) $startStep = (int)$rows[1]; } if (CLISetup::getOpt('help')) { CLI::write(); CLI::write(' usage: php aowow --setup [--locales: --mpqDataDir:]', -1, false); CLI::write(); CLI::write(' Initially essential connection information are set up and basic connectivity tests are run afterwards.', -1, false); CLI::write(' In the main stage dbc and world data is compiled into the database and required sound, image and data files are generated.', -1, false); CLI::write(' This does not require further input and will take about 15-20 minutes, plus 10 minutes per additional locale.', -1, false); CLI::write(' Lastly pending updates are applied and you are prompted to create an administrator account.', -1, false); if ($startStep) { CLI::write(); CLI::write(' You are currently on step '.($startStep + 1).' / '.count($steps).'. You can resume or restart the setup process.', -1, false); } CLI::write(); return; } if ($startStep) { CLI::write('Found firstrun progression info. (Halted on subscript '.($steps[$startStep][1][0] ? $steps[$startStep][1] : $steps[$startStep][0]).')', CLI::LOG_INFO); $msg = ''; if (!CLI::read(['x' => ['continue setup? (y/n)', true, true, '/y|n/i']], $uiYN) || !$uiYN || strtolower($uiYN['x']) == 'n') { $msg = 'Starting setup from scratch...'; $startStep = 0; } else $msg = 'Resuming setup from step '.$startStep.'...'; CLI::write(); CLI::write($msg); sleep(1); } /*******/ /* run */ /*******/ CLISetup::siteLock(CLISetup::LOCK_ON); foreach ($steps as $idx => $step) { if ($startStep > $idx) continue; if (!strpos($step[0], '::') && !is_callable($step[0])) require_once 'setup/tools/clisetup/'.$step[0].'.func.php'; if ($step[3]) { CLI::write($step[3]); if (!CLI::read([['Press any key to continue', true]])) // we don't actually care about the input return; } while (true) { if (strpos($step[0], '::')) $res = call_user_func($step[0], $step[1]); else { $args = &$step[1]; // see: https://github.com/php/php-src/issues/14202 $res = $step[0]($args[0], $args[1]); } // check script result if ($step[2]) { $errors = []; if (!$step[2]($errors)) { CLI::write($step[4], CLI::LOG_ERROR); foreach ($errors as $e) CLI::write($e); } else { $saveProgress($idx); break; } } else if ($res !== false) { $saveProgress($idx); break; } if (CLI::read(['x' => ['['.CLI::bold('c').']ontinue anyway? ['.CLI::bold('r').']etry? ['.CLI::bold('a').']bort?', true, true, '/c|r|a/i']], $uiCRA) && $uiCRA) { CLI::write(); switch(strtolower($uiCRA['x'])) { case 'c': $saveProgress($idx); break 2; case 'r': break; case 'a': return; } } else { CLI::write(); return; } } } unlink('cache/firstrun'); CLISetup::siteLock(CLISetup::LOCK_OFF); CLI::write('setup finished', CLI::LOG_OK); return; } ?>