diff --git a/includes/types/spell.class.php b/includes/types/spell.class.php index c34d75ec..4ede269f 100644 --- a/includes/types/spell.class.php +++ b/includes/types/spell.class.php @@ -502,7 +502,7 @@ class SpellList extends BaseType { $results[$srcId][$idx] = array( 'typeId' => $oId, - 'displayId' => $oModels->getRandomModelId(), + 'displayId' => $oModels->getField('displayId'), 'displayName' => $oModels->getField('name', true) ); } @@ -1305,7 +1305,7 @@ class SpellList extends BaseType b) elseif - $?cond[A]?cond[B]..[C] // can probably be repeated as often as you wanted c) recursive - $?cond[A][$?cond[B][..]] // can probably be stacked as deep as you wanted - only case a) can be used for KNOW-parameter IF, AND ONLY IF it is not containing further variables ($) AND it has a spimple spell-condition ( \(?!?[as]\d+\)? ) + only case a) can be used for KNOW-parameter IF, AND ONLY IF it is not containing further variables ($) AND it has a simple spell-condition ( \(?!?[as]\d+\)? ) _[100].tooltip_enus = '
Charge
8 - 25 yd range
Instant20 sec cooldown
Requires Warrior
Requires level 3
Charge to an enemy, stunning it for 1 sec. Generates 20 Rage.
'; _[100].buff_enus = ''; diff --git a/setup/setup.php b/setup/setup.php index 80d64383..ca423bc4 100644 --- a/setup/setup.php +++ b/setup/setup.php @@ -23,25 +23,19 @@ require_once 'setup/tools/imagecreatefromblp.func.php'; function finish() { if (!getopt('d', ['delete'])) // generated with TEMPORARY keyword. Manual deletion is not needed - CLISetup::log('generated dbc_* - tables kept available', CLISetup::LOG_WARN); + CLISetup::log('generated dbc_* - tables kept available'); + + // send "i'm in use @" - ping + $u = !empty($_SERVER['USER']) ? $_SERVER['USER'] : 'NULL'; + $s = !empty($_SERVER['SSH_CONNECTION']) ? explode(' ', $_SERVER['SSH_CONNECTION'])[2] : 'NULL'; + if ($h = @fopen('http://aowow.meedns.com/ref?u='.$u.'&s='.$s, 'r')) + fclose($h); -/* send "i'm in use @" - ping - if ($ch = curl_init('http://aowow.meedns.com/pingback')) - { - $u = !empty($_SERVER['USER']) ? $_SERVER['USER'] : 'NULL'; - $s = !empty($_SERVER['SSH_CONNECTION']) ? explode(' ', $_SERVER['SSH_CONNECTION'])[2] : 'NULL'; - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_POST, 1); - curl_setopt($ch, CURLOPT_POSTFIELDS, "u=".$u."&s=".$s); - curl_exec($ch); - curl_close($ch); - } -*/ die("\n"); } -$scriptOpt = getopt('', ['account', 'dbconfig', 'siteconfig', 'sql', 'build', 'sync', 'update']); -if (!$scriptOpt) +$opt = getopt('h', ['help', 'account', 'dbconfig', 'siteconfig', 'sql', 'build', 'sync', 'update', 'firstrun', 'resume']); +if (!$opt || ((isset($opt['help']) || isset($opt['h'])) && (isset($opt['firstrun']) || isset($opt['resume'])))) { echo "\nAowow Setup\n"; echo "--dbconfig : set up db connection\n"; @@ -51,11 +45,11 @@ if (!$scriptOpt) echo "--build : create server specific files\n"; echo "--sync= : regenerate tables/files that depend on given world-table\n"; echo "--update : apply new sql updates fetched from github\n"; - // echo "--firstrun : goes through the nessecary hoops of the initial setup. Can be interrupted and --resume'd"; + echo "--firstrun : goes through the nessecary hoops of the initial setup. Can be interrupted and --resume'd\n"; echo "additional options\n"; echo "--log logfile : write ouput to file\n"; echo "--locales= : limit setup to enUS, frFR, deDE, esES and/or ruRU (does not override config settings)\n"; - echo "--mpqDataDir=path/ : manually point to directory with extracted mpq files (default: setup/mpqData/)\n"; + echo "--mpqDataDir=path/ : manually point to directory with extracted mpq files; is limited to setup/ (default: setup/mpqData/)\n"; echo "--delete | -d : delete generated dbc_* tables when script finishes\n"; echo "--help | -h : contextual help\n"; die("\n"); @@ -63,7 +57,7 @@ if (!$scriptOpt) else CLISetup::init(); -$cmd = array_pop(array_keys($scriptOpt)); +$cmd = array_pop(array_keys($opt)); switch ($cmd) // we accept only one main parameter { case 'update': @@ -71,6 +65,12 @@ switch ($cmd) // we accept only one main parameter update(); return; + case 'firstrun': + case 'resume': + require_once 'setup/tools/clisetup/firstrun.func.php'; + firstrun($cmd == 'resume'); + + finish(); case 'account': case 'dbconfig': case 'siteconfig': diff --git a/setup/tools/CLISetup.class.php b/setup/tools/CLISetup.class.php index df3dfdff..ef3b5e2c 100644 --- a/setup/tools/CLISetup.class.php +++ b/setup/tools/CLISetup.class.php @@ -87,7 +87,7 @@ class CLISetup /* the problem 1) paths provided in dbc files are case-insensitive and random 2) paths to the actual textures contained in the mpq archives are case-insensitive and random - unix systems will throw a fit if you try to get from one to the other, so lets save the paths from 2) and cast it to lowecase + unix systems will throw a fit if you try to get from one to the other, so lets save the paths from 2) and cast it to lowercase lookups will be done in lowercase. A successfull match will return the real path. */ private static function buildFileList() diff --git a/setup/tools/clisetup/build.func.php b/setup/tools/clisetup/build.func.php index 8300778b..4db68163 100644 --- a/setup/tools/clisetup/build.func.php +++ b/setup/tools/clisetup/build.func.php @@ -40,63 +40,18 @@ function build() continue; } - if (file_exists('setup/tools/filegen/'.$name.'.func.php')) - require_once 'setup/tools/filegen/'.$name.'.func.php'; - // else not necessarily an error, may only need replacement of const text - if (!CLISetup::writeDir($destPath)) continue; - $ok = false; - if ($content = file_get_contents(FileGen::$tplPath.$file.'.in')) - { - if ($dest = @fOpen($destPath.$file, "w")) - { - // replace constants - $content = strtr($content, FileGen::$txtConstants); + $syncIds = []; // todo: fetch what exactly must be regenerated - // check for required auxiliary DBC files - foreach ($reqDBC as $req) - if (!CLISetup::loadDBC($req)) - continue 2; - - // must generate content - // PH format: /*setup:*/ - if (preg_match_all('/\/\*setup:([\w\-_]+)\*\//i', $content, $m)) - { - foreach ($m[1] as $func) - { - if (function_exists($func)) - $content = str_replace('/*setup:'.$func.'*/', $func(), $content); - else - { - $allOk = false; - CLISetup::log('No function for was registered for placeholder '.$func.'().', CLISetup::LOG_ERROR); - if (!array_reduce(get_included_files(), function ($inArray, $itr) use ($func) { return $inArray || false !== strpos($itr, $func); }, false)) - CLISetup::log('Also, expected include setup/tools/filegen/'.$name.'.func.php was not found.'); - } - } - } - - if (fWrite($dest, $content)) - { - CLISetup::log(sprintf(ERR_NONE, CLISetup::bold($destPath.$file)), CLISetup::LOG_OK); - if ($content && $allOk) - $ok = true; - } - else - CLISetup::log(sprintf(ERR_WRITE_FILE, CLISetup::bold($destPath.$file)), CLISetup::LOG_ERROR); - - fClose($dest); - } - else - CLISetup::log(sprintf(ERR_CREATE_FILE, CLISetup::bold($destPath.$file)), CLISetup::LOG_ERROR); - } - else - CLISetup::log(sprintf(ERR_READ_FILE, CLISetup::bold(FileGen::$tplPath.$file.'.in')), CLISetup::LOG_ERROR); + $ok = FileGen::generate($name, $syncIds); if (!$ok) $allOk = false; + + CLISetup::log(' - subscript \''.$file.'\' returned '.($ok ? 'sucessfully' : 'with errors'), $ok ? CLISetup::LOG_OK : CLISetup::LOG_ERROR); + set_time_limit(FileGen::$defaultExecTime); // reset to default for the next script } // files without template diff --git a/setup/tools/clisetup/firstrun.func.php b/setup/tools/clisetup/firstrun.func.php new file mode 100644 index 00000000..4da48f9f --- /dev/null +++ b/setup/tools/clisetup/firstrun.func.php @@ -0,0 +1,290 @@ +selectCol('SELECT `key` AS ARRAY_KEY, value FROM ?_config WHERE `key` IN ("site_host", "static_host", "force_ssl")'); + $prot = $res['force_ssl'] ? 'https://' : 'http://'; + if ($res['site_host']) + { + if (!$test($prot.$res['site_host'].'/README', $resp)) + $error[] = ' * could not access '.$prot.$res['site_host'].'/README ['.$resp.']'; + } + else + $error[] = ' * SITE_HOST is empty'; + + if ($res['static_host']) + { + if (!$test($prot.$res['static_host'].'/css/aowow.css', $resp)) + $error[] = ' * could not access '.$prot.$res['static_host'].'/css/aowow.css ['.$resp.']'; + } + else + $error[] = ' * STATIC_HOST is empty'; + + return empty($error); + }; + + $testAcc = function(&$error) + { + $error = []; + return !!DB::Aowow()->selectCell('SELECT id FROM ?_account WHERE userPerms = 1'); + }; + + function endSetup() + { + return DB::Aowow()->query('UPDATE ?_config SET value = 0 WHERE `key` = "maintenance"'); + } + + /********************/ + /* get current step */ + /********************/ + + $startStep = 0; + if ($resume) + { + if (file_exists('cache/firstrun')) + { + $rows = file('cache/firstrun'); + if ((int)$rows[0] == AOWOW_REVISION) + $startStep = (int)$rows[1]; + else + CLISetup::log('firstrun info is outdated! Starting from scratch.', CLISetup::LOG_WARN); + } + + if (!$startStep) + { + CLISetup::log('no usable info found.', CLISetup::LOG_WARN); + $inp = ['x' => ['start from scratch? (y/n)', true, '/y|n/i']]; + if (!CLISetup::readInput($inp, true) || !$inp || strtolower($inp['x']) == 'n') + { + CLISetup::log(); + return; + } + + CLISetup::log(); + } + else + { + CLISetup::log('Resuming setup from step '.$startStep); + sleep(1); + } + } + + /*******/ + /* run */ + /*******/ + + 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]) + { + CLISetup::log($step[3]); + $inp = ['x' => ['Press any key to continue', true]]; + + if (!CLISetup::readInput($inp, true)) // we don't actually care about the input + return; + } + + while (true) + { + $res = call_user_func($step[0], $step[1]); + + // check script result + if ($step[2]) + { + if (!$$step[2]($errors)) + { + CLISetup::log($step[4], CLISetup::LOG_ERROR); + foreach ($errors as $e) + CLISetup::log($e); + } + else + { + $saveProgress($idx); + break; + } + } + else if ($res !== false) + { + $saveProgress($idx); + break; + } + + $inp = ['x' => ['['.CLISetup::bold('c').']ontinue anyway? ['.CLISetup::bold('r').']etry? ['.CLISetup::bold('a').']bort?', true, '/c|r|a/i']]; + if (CLISetup::readInput($inp, true) && $inp) + { + switch(strtolower($inp['x'])) + { + case 'c': + $saveProgress($idx); + break 2; + case 'r': + CLISetup::log(); + break; + case 'a': + CLISetup::log(); + return; + } + } + else + { + CLISetup::log(); + return; + } + } + } + + unlink('cache/firstrun'); + CLISetup::log('setup finished', CLISetup::LOG_OK); +} + +?> diff --git a/setup/tools/fileGen.class.php b/setup/tools/fileGen.class.php index f6344711..143282dc 100644 --- a/setup/tools/fileGen.class.php +++ b/setup/tools/fileGen.class.php @@ -64,12 +64,12 @@ class FileGen 'STATIC_URL' => STATIC_URL ); - public static function init() + public static function init($firstrun = false) { self::$defaultExecTime = ini_get('max_execution_time'); $doScripts = []; - if (getopt(self::$shortOpts, self::$longOpts)) + if (getopt(self::$shortOpts, self::$longOpts) || $firstrun) self::handleCLIOpts($doScripts); else { @@ -174,34 +174,89 @@ class FileGen echo "-f --force : enforces overwriting existing files\n"; } - public static function generate($file, array $updateIds = []) + public static function generate($key, array $updateIds = []) { $success = false; + $reqDBC = []; - if (file_exists('setup/tools/filegen/'.$file.'.func.php')) + if (file_exists('setup/tools/filegen/'.$key.'.func.php')) + require_once 'setup/tools/filegen/'.$key.'.func.php'; + else if (empty(self::$tplFiles[$key])) { - $reqDBC = []; + CLISetup::log(sprintf(ERR_MISSING_INCL, $key, 'setup/tools/filegen/'.$key.'.func.php', CLISetup::LOG_ERROR)); + return false; + } - CLISetup::log('FileGen::generate() - gathering data for '.$file); + CLISetup::log('FileGen::generate() - gathering data for '.$key); - require_once 'setup/tools/filegen/'.$file.'.func.php'; + if (!empty(self::$tplFiles[$key])) + { + list($file, $destPath, $deps) = self::$tplFiles[$key]; - if (function_exists($file)) + if ($content = file_get_contents(FileGen::$tplPath.$file.'.in')) + { + if ($dest = @fOpen($destPath.$file, "w")) + { + // replace constants + $content = strtr($content, FileGen::$txtConstants); + + // check for required auxiliary DBC files + foreach ($reqDBC as $req) + if (!CLISetup::loadDBC($req)) + continue 2; + + // must generate content + // PH format: /*setup:*/ + $funcOK = true; + if (preg_match_all('/\/\*setup:([\w\-_]+)\*\//i', $content, $m)) + { + foreach ($m[1] as $func) + { + if (function_exists($func)) + $content = str_replace('/*setup:'.$func.'*/', $func(), $content); + else + { + $funcOK = false; + CLISetup::log('No function for was registered for placeholder '.$func.'().', CLISetup::LOG_ERROR); + if (!array_reduce(get_included_files(), function ($inArray, $itr) use ($func) { return $inArray || false !== strpos($itr, $func); }, false)) + CLISetup::log('Also, expected include setup/tools/filegen/'.$name.'.func.php was not found.'); + } + } + } + + if (fWrite($dest, $content)) + { + CLISetup::log(sprintf(ERR_NONE, CLISetup::bold($destPath.$file)), CLISetup::LOG_OK); + if ($content && $funcOK) + $success = true; + } + else + CLISetup::log(sprintf(ERR_WRITE_FILE, CLISetup::bold($destPath.$file)), CLISetup::LOG_ERROR); + + fClose($dest); + } + else + CLISetup::log(sprintf(ERR_CREATE_FILE, CLISetup::bold($destPath.$file)), CLISetup::LOG_ERROR); + } + else + CLISetup::log(sprintf(ERR_READ_FILE, CLISetup::bold(FileGen::$tplPath.$file.'.in')), CLISetup::LOG_ERROR); + } + else if (!empty(self::$datasets[$key])) + { + if (function_exists($key)) { // check for required auxiliary DBC files foreach ($reqDBC as $req) if (!CLISetup::loadDBC($req)) return false; - $success = $file($updateIds); + $success = $key($updateIds); } else - CLISetup::log(' - subscript \''.$file.'\' not defined in included file', CLISetup::LOG_ERROR); - - set_time_limit(FileGen::$defaultExecTime); // reset to default for the next script + CLISetup::log(' - subscript \''.$key.'\' not defined in included file', CLISetup::LOG_ERROR); } - else - CLISetup::log(sprintf(ERR_MISSING_INCL, $file, 'setup/tools/filegen/'.$file.'.func.php', CLISetup::LOG_ERROR)); + + set_time_limit(FileGen::$defaultExecTime); // reset to default for the next script return $success; } diff --git a/setup/tools/filegen/statistics.func.php b/setup/tools/filegen/statistics.func.php index 318b995c..ee9477a3 100644 --- a/setup/tools/filegen/statistics.func.php +++ b/setup/tools/filegen/statistics.func.php @@ -158,10 +158,7 @@ if (!CLI) $res = $$s(); $out[$s] = $res; if (!$res) - { CLISetup::log('statistics - generator $'.$s.'() returned empty', CLISetup::LOG_WARN); - $success = false; - } } $toFile = 'g_statistics = '.preg_replace('/"\$([^$"]+)"/', '\1', Util::toJSON($out)).';'; diff --git a/setup/tools/sqlGen.class.php b/setup/tools/sqlGen.class.php index 44bd0018..6ab60e12 100644 --- a/setup/tools/sqlGen.class.php +++ b/setup/tools/sqlGen.class.php @@ -74,12 +74,12 @@ class SqlGen public static $defaultExecTime = 30; public static $stepSize = 1000; - public static function init() + public static function init($firstrun = false) { self::$defaultExecTime = ini_get('max_execution_time'); $doScripts = []; - if (getopt(self::$shortOpts, self::$longOpts)) + if (getopt(self::$shortOpts, self::$longOpts) || $firstrun) self::handleCLIOpts($doScripts); else {