* automatically set and unset maintenance mode when data is being edited (either sql or files)
 * added more verbose help prompts. They should now always appear when -h is used.
 * added --setup as more intuitive command for --firstrun. --firstrun is now considered deprecated and will be removed in due time.
 * unfuck order of indizes in --siteconfig
 * fixed some typos
 * convert echo use to CLI::write
 * move scattered command line argument checks to CLISetup
This commit is contained in:
Sarjuuk
2020-07-29 17:01:20 +02:00
parent c65bd88867
commit 59f58f8506
40 changed files with 523 additions and 304 deletions

View File

@@ -14,8 +14,6 @@ class CLISetup
public static $srcDir = 'setup/mpqdata/';
public static $tmpDBC = false;
private static $mpqFiles = [];
public static $expectedPaths = array( // update paths [yes, you can have en empty string as key]
'' => LOCALE_EN, 'enGB' => LOCALE_EN, 'enUS' => LOCALE_EN,
@@ -26,31 +24,96 @@ class CLISetup
'ruRU' => LOCALE_RU
);
public static function init()
private const ARGV_REQUIRED = 0x01;
private const ARGV_OPTIONAL = 0x02;
private const ARGV_ARRAY = 0x10;
private static $opts = [];
private static $optGroups = ['AoWoW Setup', 'Utility Functions', 'Additional Options', 'Additional arguments specific to --build=simpleImg', 'Additional arguments specific to --build=complexImg'];
private static $optDefs = array( // cmd => [groupId, aliasses[], flags, description, appendix]
'setup' => [0, ['s', 'firstrun'], 0x00, 'Step by step initial setup. Resumes if interrupted.', '' ],
'update' => [0, ['u'], 0x00, 'Apply new sql updates fetched from Github and run --sync as needed.', '' ],
'dbconfig' => [1, [], 0x00, 'Set up DB connection.', '' ],
'siteconfig' => [1, [], 0x00, 'Set up site variables.', '' ],
'account' => [1, [], 0x00, 'Create an account with admin privileges.', '' ],
'sql' => [1, [], 0x12, 'Generate DB content from your world tables.', '=<subScriptList,>' ],
'build' => [1, [], 0x12, 'Compile image files and data dumps.', '=<subScriptList,>' ],
'sync' => [1, [], 0x12, 'Regenerate tables/files that depend on given world DB table.', '=<worldTableList,>'],
'dbc' => [1, [], 0x11, 'Extract dbc files from mpqDataDir into sql table. Structure must be defined in setup/dbc.class.php.', '=<dbcfileList,>' ],
'delete' => [2, ['d'], 0x00, 'Delete dbc_* tables generated by this prompt when done.', '' ],
'log' => [2, [], 0x01, 'Write CLI ouput to file.', '=logfile' ],
'help' => [2, ['h'], 0x00, 'Display contextual help, if available.', '' ],
'force' => [2, ['f'], 0x00, 'Force existing files to be overwritten.', '' ],
'locales' => [2, [], 0x12, 'Limit setup to enUS, frFR, deDE, zhCN, esES and/or ruRU. (does not override config settings)', '=<regionCodes,>' ],
'mpqDataDir' => [2, [], 0x02, 'Manually point to directory with extracted mpq files. This is limited to setup/ (default: setup/mpqData/)', '=path/' ],
'icons' => [3, ['1'], 0x00, 'Generate icons for spells, items, classes, races, ect.', '' ],
'glyphs' => [3, ['2'], 0x00, 'Generate decorative glyph symbols displayed on related item and spell pages.', '' ],
'pagetexts' => [3, ['3'], 0x00, 'Generate images contained in text on readable items and gameobjects.', '' ],
'loadingscreens' => [3, ['4'], 0x00, 'Generate loading screen images (not used on page; skipped by default)', '' ],
'talentbgs' => [4, ['1'], 0x00, 'Generate backgrounds for the talent calculator.', '' ],
'maps' => [4, ['2'], 0x00, 'Generate zone and continental maps.', '' ],
'spawn-maps' => [4, ['3'], 0x00, 'Fallback to generate alpha masks for each zone to match creature and gameobject spawn points.', '' ],
'artwork' => [4, ['4'], 0x00, 'Generate images from /glues/credits (not used on page; skipped by default))', '' ],
'area-maps' => [4, ['5'], 0x00, 'Generate additional area maps with highlighting for subzones (optional; skipped by default)', '' ]
);
/**************************/
/* command line arguments */
/**************************/
public static function init() : void
{
if ($_ = getopt('d', ['log::', 'locales::', 'mpqDataDir::', 'delete']))
$short = '';
$long = [];
$alias = [];
foreach (self::$optDefs as $opt => [$idx, $aliasses, $flags, , ])
{
// optional logging
if (!empty($_['log']))
CLI::initLogFile(trim($_['log']));
if ($flags & self::ARGV_REQUIRED)
$opt .= ':';
else if ($flags & self::ARGV_OPTIONAL)
$opt .= '::';
// alternative data source (no quotes, use forward slash)
if (!empty($_['mpqDataDir']))
self::$srcDir = CLI::nicePath($_['mpqDataDir']);
// optional limit handled locales
if (!empty($_['locales']))
$long[] = $opt;
foreach ($aliasses as $a)
{
// engb and enus are identical for all intents and purposes
$from = ['engb', 'esmx', 'encn'];
$to = ['enus', 'eses', 'zhcn'];
$_['locales'] = str_ireplace($from, $to, strtolower($_['locales']));
if ($flags & self::ARGV_REQUIRED) // neither should be set with shortOpts
$_a = $a.':';
else if ($flags & self::ARGV_OPTIONAL)
$_a = $a.'::';
else
$_a = $a;
self::$locales = array_intersect(Util::$localeStrings, explode(',', $_['locales']));
$alias[$a] = $opt;
if (strlen($a) == 1)
$short .= $_a;
else
$long[] = $_a;
}
}
if (isset($_['d']) || isset($_['delete']))
self::$tmpDBC = true;
if ($opts = getopt($short, $long))
foreach ($opts as $o => $v)
self::$opts[$alias[$o] ?? $o] = (self::$optDefs[$alias[$o] ?? $o][2] & self::ARGV_ARRAY) ? ($v ? explode(',', $v) : []) : ($v ?: true);
// optional logging
if (self::$opts['log'])
CLI::initLogFile(trim(self::$opts['log']));
// alternative data source (no quotes, use forward slash)
if (self::$opts['mpqDataDir'])
self::$srcDir = CLI::nicePath($self::$opts['mpqDataDir']);
// optional limit handled locales
if (self::$opts['locales'])
{
// engb and enus are identical for all intents and purposes
$from = ['engb', 'esmx', 'encn'];
$to = ['enus', 'eses', 'zhcn'];
$_['locales'] = str_ireplace($from, $to, strtolower($_['locales']));
self::$locales = array_intersect(Util::$localeStrings, explode(',', $_['locales']));
}
if (!self::$locales)
@@ -62,6 +125,62 @@ class CLISetup
self::$localeIds[] = $idx;
}
public static function getOpt(...$args)
{
if (!$args)
return false;
$result = [];
// groupMask case
if (is_int($args[0]))
{
foreach (self::$optDefs as $o => [$group, , , , ])
if (((1 << $group) & $args[0]) && isset(self::$opts[$o]))
$result[] = $o;
return $result;
}
// single key case
if (count($args) == 1)
return self::$opts[$args[0]] ?? false;
// multiple keys case
foreach ($args as $a)
if (isset(self::$optDefs[$a]))
$result[$a] = self::$opts[$a] ?? false;
return $result;
}
public static function optHelp(int $groupMask = 0x0) : void
{
$lines = [];
foreach (self::$optGroups as $idx => $og)
{
if ($groupMask && !($groupMask & (1 << $idx)))
continue;
$lines[] = [$og, ''];
foreach (self::$optDefs as $opt => [$group, $alias, , $desc, $app])
{
if ($group != $idx)
continue;
$cmd = ' --'.$opt;
foreach ($alias as $a)
$cmd .= ' | '.(strlen($a) == 1 ? '-'.$a : '--'.$a);
$lines[] = [$cmd.$app, $desc];
}
}
CLI::writeTable($lines);
}
/*******************/
/* MPQ-file access */
@@ -73,10 +192,10 @@ class CLISetup
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()
private static function buildFileList() : bool
{
CLI::write();
CLI::write('reading MPQdata from '.self::$srcDir.' to list for first time use...');
CLI::write('indexing game data from '.self::$srcDir.' for first time use...');
$setupDirs = glob('setup/*');
foreach ($setupDirs as $sd)
@@ -195,7 +314,7 @@ class CLISetup
if (DB::Aowow()->selectCell('SHOW TABLES LIKE ?', 'dbc_'.$name) && DB::Aowow()->selectCell('SELECT count(1) FROM ?#', 'dbc_'.$name))
return true;
$dbc = new DBC($name, ['temporary' => self::$tmpDBC]);
$dbc = new DBC($name, ['temporary' => self::getOpt('delete')]);
if ($dbc->error)
{
CLI::write('CLISetup::loadDBC() - required DBC '.$name.'.dbc not found!', CLI::LOG_ERROR);