!extension_loaded($x))) $error .= 'Required Extension '.implode(', ', $ext)." was not found. Please check if it should exist, using \"php -m\"\n\n"; if ($ext = array_filter($badExt, fn($x) => extension_loaded($x))) $error .= 'Loaded Extension '.implode(', ', $ext)." is incompatible and must be disabled.\n\n"; if (version_compare(PHP_VERSION, '8.2.0') < 0) $error .= 'PHP Version 8.2 or higher required! Your version is '.PHP_VERSION.".\nCore functions are unavailable!\n"; if ($error) die(CLI ? strip_tags($error) : $error); require_once 'includes/defines.php'; require_once 'includes/locale.class.php'; require_once 'localization/lang.class.php'; require_once 'includes/libs/DbSimple/Generic.php'; // Libraray: http://en.dklab.ru/lib/DbSimple (using variant: https://github.com/ivan1986/DbSimple/tree/master) require_once 'includes/database.class.php'; // wrap DBSimple require_once 'includes/utilities.php'; // helper functions require_once 'includes/type.class.php'; // DB types storage and factory require_once 'includes/cfg.class.php'; // Config holder require_once 'includes/user.class.php'; // Session handling (could be skipped for CLI context except for username and password validation used in account creation) require_once 'includes/game/misc.php'; // Misc game related data & functions // game client data interfaces spl_autoload_register(function ($class) { if ($i = strrpos($class, '\\')) $class = substr($class, $i + 1); if (preg_match('/[^\w]/i', $class)) return; if ($class == 'Stats' || $class == 'StatsContainer') // entity statistics conversion require_once 'includes/game/chrstatistics.php'; else if (file_exists('includes/game/'.strtolower($class).'.class.php')) require_once 'includes/game/'.strtolower($class).'.class.php'; }); // our site components spl_autoload_register(function ($class) { if ($i = strrpos($class, '\\')) $class = substr($class, $i + 1); if (preg_match('/[^\w]/i', $class)) return; if (file_exists('includes/components/'.strtolower($class).'.class.php')) require_once 'includes/components/'.strtolower($class).'.class.php'; }); // TC systems in components spl_autoload_register(function ($class) { switch ($class) { case __NAMESPACE__.'\SmartAI': case __NAMESPACE__.'\SmartEvent': case __NAMESPACE__.'\SmartAction': case __NAMESPACE__.'\SmartTarget': require_once 'includes/components/SmartAI/SmartAI.class.php'; require_once 'includes/components/SmartAI/SmartEvent.class.php'; require_once 'includes/components/SmartAI/SmartAction.class.php'; require_once 'includes/components/SmartAI/SmartTarget.class.php'; break; case __NAMESPACE__.'\Conditions': require_once 'includes/components/Conditions/Conditions.class.php'; break; } }); // autoload List-classes, associated filters spl_autoload_register(function ($class) { if ($i = strrpos($class, '\\')) $class = substr($class, $i + 1); if (preg_match('/[^\w]/i', $class)) return; if (!stripos($class, 'list')) return; $class = strtolower(str_replace('ListFilter', 'List', $class)); $cl = match ($class) { 'localprofilelist', 'remoteprofilelist' => 'profile', 'localarenateamlist', 'remotearenateamlist' => 'arenateam', 'localguildlist', 'remoteguildlist' => 'guild', default => strtr($class, ['list' => '']) }; if (file_exists('includes/types/'.$cl.'.class.php')) { require_once 'includes/types/basetype.class.php'; require_once 'includes/types/'.$cl.'.class.php'; } else throw new \Exception('could not register type class: '.$cl); }); // endpoint loader spl_autoload_register(function ($class) { if ($i = strrpos($class, '\\')) $class = substr($class, $i + 1); if (preg_match('/[^\w]/i', $class)) return; $class = strtolower($class); if (stripos($class, 'ajax') === 0) // handles ajax and jsonp requests { if (file_exists('includes/ajaxHandler/'.strtr($class, ['ajax' => '']).'.class.php')) { require_once 'includes/ajaxHandler/ajaxHandler.class.php'; require_once 'includes/ajaxHandler/'.strtr($class, ['ajax' => '']).'.class.php'; } else throw new \Exception('could not register ajaxHandler class: '.$class); return; } else if (stripos($class, 'page')) // handles templated pages { if (file_exists('pages/'.strtr($class, ['page' => '']).'.php')) { require_once 'pages/genericPage.class.php'; require_once 'pages/'.strtr($class, ['page' => '']).'.php'; } else if ($class == 'genericpage') // may be called directly in fatal error case require_once 'pages/genericPage.class.php'; } }); set_error_handler(function($errNo, $errStr, $errFile, $errLine) { // either from test function or handled separately if (strstr($errStr, 'mysqli_connect') && $errNo == E_WARNING) return true; // we do not log deprecation notices if ($errNo & (E_DEPRECATED | E_USER_DEPRECATED)) return true; $logLevel = match($errNo) { E_RECOVERABLE_ERROR, E_USER_ERROR => LOG_LEVEL_ERROR, E_WARNING, E_USER_WARNING => LOG_LEVEL_WARN, E_NOTICE, E_USER_NOTICE => LOG_LEVEL_INFO, default => 0 }; $errName = match($errNo) { E_RECOVERABLE_ERROR => 'RECOVERABLE_ERROR', E_USER_ERROR => 'USER_ERROR', E_USER_WARNING, E_WARNING => 'WARNING', E_USER_NOTICE, E_NOTICE => 'NOTICE', default => 'UNKNOWN_ERROR' // errors not in this list can not be handled by set_error_handler (as per documentation) or are ignored }; if (DB::isConnected(DB_AOWOW)) DB::Aowow()->query('INSERT INTO ?_errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), ?d, ?d, ?, ?d, ?, ?, ?d, ?) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', AOWOW_REVISION, $errNo, $errFile, $errLine, CLI ? 'CLI' : ($_SERVER['QUERY_STRING'] ?? ''), empty($_POST) ? '' : http_build_query($_POST), User::$groups, $errStr ); if (CLI) CLI::write($errName.' - '.$errStr.' @ '.$errFile. ':'.$errLine, $logLevel); else if (Cfg::get('DEBUG') >= $logLevel) Util::addNote($errName.' - '.$errStr.' @ '.$errFile. ':'.$errLine, U_GROUP_EMPLOYEE, $logLevel); return true; }, E_ALL); // handle exceptions set_exception_handler(function ($e) { if (DB::isConnected(DB_AOWOW)) DB::Aowow()->query('INSERT INTO ?_errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), ?d, ?d, ?, ?d, ?, ?, ?d, ?) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', AOWOW_REVISION, $e->getCode(), $e->getFile(), $e->getLine(), CLI ? 'CLI' : ($_SERVER['QUERY_STRING'] ?? ''), empty($_POST) ? '' : http_build_query($_POST), User::$groups, $e->getMessage() ); if (CLI) fwrite(STDERR, "\nException - ".$e->getMessage()."\n ".$e->getFile(). '('.$e->getLine().")\n".$e->getTraceAsString()."\n\n"); else { Util::addNote('Exception - '.$e->getMessage().' @ '.$e->getFile(). ':'.$e->getLine()."\n".$e->getTraceAsString(), U_GROUP_EMPLOYEE, LOG_LEVEL_ERROR); (new GenericPage())->error(); } }); // handle fatal errors register_shutdown_function(function() { if ($e = error_get_last()) { if (DB::isConnected(DB_AOWOW)) DB::Aowow()->query('INSERT INTO ?_errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), ?d, ?d, ?, ?d, ?, ?, ?d, ?) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', AOWOW_REVISION, $e['type'], $e['file'], $e['line'], CLI ? 'CLI' : ($_SERVER['QUERY_STRING'] ?? ''), empty($_POST) ? '' : http_build_query($_POST), User::$groups, $e['message'] ); if (CLI) fwrite(STDERR, "\nFatal Error - ".$e['message'].' @ '.$e['file']. ':'.$e['line']."\n\n"); else if (User::isInGroup(U_GROUP_EMPLOYEE)) echo "\nFatal Error - ".$e['message'].' @ '.$e['file']. ':'.$e['line']."\n\n"; } }); // Setup DB-Wrapper if (file_exists('config/config.php')) require_once 'config/config.php'; else $AoWoWconf = []; if (!empty($AoWoWconf['aowow']['db'])) DB::load(DB_AOWOW, $AoWoWconf['aowow']); if (!empty($AoWoWconf['world']['db'])) DB::load(DB_WORLD, $AoWoWconf['world']); if (!empty($AoWoWconf['auth']['db'])) DB::load(DB_AUTH, $AoWoWconf['auth']); if (!empty($AoWoWconf['characters'])) foreach ($AoWoWconf['characters'] as $realm => $charDBInfo) if (!empty($charDBInfo)) DB::load(DB_CHARACTERS . $realm, $charDBInfo); $AoWoWconf = null; // empty auths // load config from DB Cfg::load(); // handle non-fatal errors and notices error_reporting(E_ALL); if (!CLI) { // not displaying the brb gnomes as static_host is missing, but eh... if (!DB::isConnected(DB_AOWOW) || !DB::isConnected(DB_WORLD) || !Cfg::get('HOST_URL') || !Cfg::get('STATIC_URL')) { Lang::load(Locale::EN); (new GenericPage())->maintenance(); } // Setup Session $cacheDir = Cfg::get('SESSION_CACHE_DIR'); if ($cacheDir && Util::writeDir($cacheDir)) session_save_path(getcwd().'/'.$cacheDir); session_set_cookie_params(15 * YEAR, '/', '', (($_SERVER['HTTPS'] ?? 'off') != 'off') || Cfg::get('FORCE_SSL'), true); session_cache_limiter('private'); if (!session_start()) { trigger_error('failed to start session', E_USER_ERROR); (new GenericPage())->error(); } if (User::init()) User::save(); // save user-variables in session // hard override locale for this call (should this be here..?) if (isset($_GET['locale']) && ($loc = Locale::tryFrom((int)$_GET['locale']))) Lang::load($loc); else Lang::load(User::$preferedLoc); // set up some logging (~10 queries will execute before we init the user and load the config) if (Cfg::get('DEBUG') >= LOG_LEVEL_INFO && User::isInGroup(U_GROUP_DEV | U_GROUP_ADMIN)) { DB::Aowow()->setLogger(DB::profiler(...)); DB::World()->setLogger(DB::profiler(...)); if (DB::isConnected(DB_AUTH)) DB::Auth()->setLogger(DB::profiler(...)); if (!empty($AoWoWconf['characters'])) foreach ($AoWoWconf['characters'] as $idx => $__) if (DB::isConnected(DB_CHARACTERS . $idx)) DB::Characters($idx)->setLogger(DB::profiler(...)); } // parse page-parameters .. sanitize before use! $str = explode('&', $_SERVER['QUERY_STRING'] ?? '', 2)[0]; $_ = explode('=', $str, 2); $pageCall = mb_strtolower($_[0]); $pageParam = $_[1] ?? ''; } else if (DB::isConnected(DB_AOWOW)) Lang::load(Locale::EN); ?>