From 33ee358e0c9215eef61f09f290a38363aaab5afa Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Sun, 9 Jun 2024 00:54:53 +0200 Subject: [PATCH] Setup/DBconfig * test for known world db formats and throw appropriate errors * test for imported aowow db and throw error if missing * make DB connection reloadable --- README.md | 2 +- includes/database.class.php | 5 +- includes/defines.php | 3 + setup/tools/clisetup/dbconfig.func.php | 105 +++++++++++++++++++------ setup/tools/clisetup/setup.func.php | 19 ++++- 5 files changed, 107 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index e1daf8d0..08baf362 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Also, this project is not meant to be used for commercial puposes of any kind! + [File Information](https://www.php.net/manual/en/book.fileinfo.php) + [GNU Multiple Precision](https://www.php.net/manual/en/book.gmp.php) (When using TrinityCore as auth source) + MySQL ≥ 5.7.0 OR MariaDB ≥ 10.6.4 OR similar -+ [TDB 335.21101](https://github.com/TrinityCore/TrinityCore/releases/tag/TDB335.21101) ++ [TDB 335.21101](https://github.com/TrinityCore/TrinityCore/releases/tag/TDB335.21101) (no other other providers are supported at this time) + WIN: php.exe needs to be added to the `PATH` system variable, if it isn't already. + Tools require cmake: Please refer to the individual repositories for detailed information + [MPQExtractor](https://github.com/Sarjuuk/MPQExtractor) / [FFmpeg](https://ffmpeg.org/download.html) / (optional: [BLPConverter](https://github.com/Sarjuuk/BLPConverter)) diff --git a/includes/database.class.php b/includes/database.class.php index 7ecda53b..9ca5c4c4 100644 --- a/includes/database.class.php +++ b/includes/database.class.php @@ -24,7 +24,10 @@ class DB public static function connect($idx) { if (self::isConnected($idx)) - return; + { + self::$interfaceCache[$idx]->link->close(); + self::$interfaceCache[$idx] = null; + } $options = &self::$optionsCache[$idx]; $interface = DbSimple_Generic::connect(self::createConnectSyntax($options)); diff --git a/includes/defines.php b/includes/defines.php index a44422bc..3c5ab820 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -11,6 +11,9 @@ define('E_AOWOW', E_ALL & ~(E_DEPRECATED | E_USER_DEPRECATED | E define('JSON_AOWOW_POWER', JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); define('FILTER_FLAG_STRIP_AOWOW', FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK); +define('TDB_WORLD_MINIMUM_VER', 21101); +define('TDB_WORLD_EXPECTED_VER', 24041); + // as of 01.01.2024 https://www.wowhead.com/wotlk/de/spell=40120/{seo} // https://www.wowhead.com/wotlk/es/search=vuelo define('WOWHEAD_LINK', 'https://www.wowhead.com/wotlk/%s/%s=%s'); diff --git a/setup/tools/clisetup/dbconfig.func.php b/setup/tools/clisetup/dbconfig.func.php index 89817ac0..7ff15a16 100644 --- a/setup/tools/clisetup/dbconfig.func.php +++ b/setup/tools/clisetup/dbconfig.func.php @@ -16,7 +16,7 @@ function dbconfig() : void $databases = ['aowow', 'world', 'auth', 'characters']; $AoWoWconf = []; $dbFields = array( - 'host' => ['Server Host', false], + 'host' => ['Hostname / IP', false], 'user' => ['User', false], 'pass' => ['Password', true ], 'db' => ['Database Name', false], @@ -28,12 +28,71 @@ function dbconfig() : void if ($dbInfo['host']) { - DB::test($dbInfo, $errStr); + $result = CLI::green('OK'); + $note = ''; - $buff[] = $errStr ? CLI::red('ERR') : CLI::green('OK'); + if (DB::test($dbInfo, $note)) + { + DB::load($idx, $dbInfo); + + $ok = false; + switch ($idx) + { + case DB_AOWOW: + if (DB::Aowow()->selectCell('SHOW TABLES LIKE ?', 'aowow_dbversion')) + { + if ($date = DB::Aowow()->selectCell('SELECT `date` FROM ?_dbversion')) + { + $note = 'AoWoW DB version @ ' . date(Util::$dateFormatInternal, $date); + $ok = true; + } + else + $note = CLI::yellow('AoWoW DB version empty! Import of DB dump failed?'); + } + else + $note = CLI::yellow('DB test failed to find dbversion table. setup/db_structure.sql not yet imported?'); + break; + case DB_WORLD: + if (DB::World()->selectCell('SHOW TABLES LIKE ?', 'version')) + { + [$vString, $vNo] = DB::World()->selectRow('SELECT `db_version` AS "0", `cache_id` AS "1" FROM `version`'); + if (strpos($vString, 'TDB') === 0) + { + if ($vNo < TDB_WORLD_MINIMUM_VER) + $note = CLI::yellow('DB test found TrinityDB version older than rev. ').CLI::bold(TDB_WORLD_MINIMUM_VER).CLI::yellow('. Please update to at least rev. ').CLI::bold(TDB_WORLD_MINIMUM_VER); + else if ($vNo > TDB_WORLD_EXPECTED_VER) + $note = CLI::yellow('DB test found TrinityDB version newer than rev. ').CLI::bold(TDB_WORLD_EXPECTED_VER).CLI::yellow('. Be advised! DB structure may diverge!'); + else + { + $note = 'TrinityDB version @ ' . $vString; + $ok = true; + } + } + else if (strpos($vString, 'ACDB') === 0) + $note = CLI::yellow('DB test found AzerothCore DB version. AzerothCore DB structure is not supported!'); + else + $note = CLI::yellow('DB test found unexpected vendor in expected version table. Uhh.. Good Luck..!?'); + } + else if (DB::World()->selectCell('SHOW TABLES LIKE ?', 'db_version')) + $note = CLI::yellow('DB test found MaNGOS styled version table. MaNGOS DB structure is not supported!'); + else + $note = CLI::yellow('DB test failed to find version table. TrinityDB world not yet imported?'); + break; + default: + $ok = true; // no tests right now + } + + if (!$ok) + $result = CLI::yellow('WARN'); + } + else + $result = CLI::red('ERR'); + + $buff[] = $result; $buff[] = 'mysqli://'.$dbInfo['user'].':'.($dbInfo['pass'] ? '**********' : '').'@'.$dbInfo['host'].'/'.$dbInfo['db']; $buff[] = $dbInfo['prefix'] ? 'table prefix: '.$dbInfo['prefix'] : ''; - $buff[] = $errStr; + $buff[] = $note; + } else $buff[] = CLI::bold(''); @@ -50,65 +109,65 @@ function dbconfig() : void while (true) { - CLI::write("select a numerical index to use the corresponding entry"); + CLI::write('select an index to use the corresponding entry'); $nCharDBs = 0; $tblRows = []; foreach ($databases as $idx => $name) { - if ($idx != 3) + if ($idx != DB_CHARACTERS) $tblRows[] = $testDB($idx, $name, $AoWoWconf[$name]); else if (!empty($AoWoWconf[$name])) foreach ($AoWoWconf[$name] as $charIdx => $dbInfo) $tblRows[] = $testDB($idx + $nCharDBs++, $name.' ['.$charIdx.']', $AoWoWconf[$name][$charIdx]); } - $tblRows[] = ['['.CLI::bold(3 + $nCharDBs).']', 'add new character DB']; + $tblRows[] = ['['.CLI::bold('N').']', 'new characters DB']; + $tblRows[] = ['['.CLI::bold('R').']', 'retest / reload DBs']; CLI::writeTable($tblRows, true); while (true) { - $inp = ['idx' => ['', true, '/\d/']]; + $inp = ['idx' => ['', true, '/\d|R|N/i']]; if (CLI::read($inp, true) && $inp) { - if ($inp['idx'] >= 0 && $inp['idx'] <= (3 + $nCharDBs)) + if (strtoupper($inp['idx']) == 'R') + continue 2; + else if (($inp['idx'] >= DB_AOWOW && $inp['idx'] < (DB_CHARACTERS + $nCharDBs)) || strtoupper($inp['idx']) == 'N') { $curFields = $inp['idx'] ? $dbFields : array_slice($dbFields, 0, 4); - if ($inp['idx'] == 3 + $nCharDBs) // add new realmDB - $curFields['realmId'] = ['Realm Id', false, '/[1-9][0-9]*/']; + if (strtoupper($inp['idx']) == 'N') // add new characters DB + $curFields['realmId'] = ['Realm Id', false, '/\d{1,3}/']; if (CLI::read($curFields)) { - if ($inp['idx'] == 0 && $curFields) + if ($inp['idx'] == DB_AOWOW && $curFields) $curFields['prefix'] = 'aowow_'; - // auth, world or aowow - if ($inp['idx'] < 3) - $AoWoWconf[$databases[$inp['idx']]] = $curFields ?: array_combine(array_keys($dbFields), ['', '', '', '', '']); - // new char DB - else if ($inp['idx'] == 3 + $nCharDBs) + if (strtoupper($inp['idx']) == 'N') // new char DB { if ($curFields) { $_ = $curFields['realmId']; unset($curFields['realmId']); - $AoWoWconf[$databases[3]][$_] = $curFields; + $AoWoWconf[$databases[DB_CHARACTERS]][$_] = $curFields; } } - // existing char DB - else + else if ($inp['idx'] < DB_CHARACTERS) // auth, world or aowow + $AoWoWconf[$databases[$inp['idx']]] = $curFields ?: array_combine(array_keys($dbFields), ['', '', '', '', '']); + else // existing char DB { $i = 0; - foreach ($AoWoWconf[$databases[3]] as $realmId => &$dbInfo) + foreach ($AoWoWconf[$databases[DB_CHARACTERS]] as $realmId => &$dbInfo) { - if ($inp['idx'] - 3 != $i++) + if ($inp['idx'] - DB_CHARACTERS != $i++) continue; if ($curFields) $dbInfo = $curFields; else - unset($AoWoWconf[$databases[3]][$realmId]); + unset($AoWoWconf[$databases[DB_CHARACTERS]][$realmId]); } } diff --git a/setup/tools/clisetup/setup.func.php b/setup/tools/clisetup/setup.func.php index 50d3a3ef..793e4bf7 100644 --- a/setup/tools/clisetup/setup.func.php +++ b/setup/tools/clisetup/setup.func.php @@ -132,8 +132,23 @@ function setup() : void if (DB::test($AoWoWconf[$what], $err)) { DB::load($idx, $AoWoWconf[$what]); - if ($idx == DB_AOWOW) - Cfg::load(); // first time load after successful db setup + 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::Aowow()->selectCell('SHOW TABLES LIKE ?', 'version')) + $error[] = ' * '.$what.': doesn\'t seem to contain TrinityCore world tables!'; + else if (DB::Aowow()->selectCell('SELECT `cache_id` FROM `version`') < TDB_WORLD_MINIMUM_VER) + $error[] = ' * '.$what.': TCDB 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;