From f3745a2752443a1c63406361319d3328f02aac9e Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 7 Feb 2023 11:41:05 +0100 Subject: [PATCH] Feature/new router (#165) * Remove unneeded escape * Fix guild back buttons (change logo & motd) * small adjustment in news.php * Fix create character when admin (any case is allowed now) * Fix forum table style (boards & thread view) * Small improvement to plugins.enabled check * [WIP] nikic/fast-route implementation I will describe it more in Pull Request * Optimisations & fixes. * Fix path - should not be absolute * Add PLUGINS to Twig path * Don't hide "Install Plugin" Box by default * Update package-lock.json * nothing important, just early exit & fixes Fix creature display * fix premium_ends_at for tfs 1.3+ * Move pages * Move pages tbc * $db->select: make $where parameter optional, allows to get all records * Add some error box to error * fix parse error * Rewriting the router v2 To be more flexible * small fixes * fix & add admin icons * Move mass_* pages to correct folder * fix logout hook 2 * Delete accountmanagement.php * This code wasn't used * Add missing var * Add redirect_from && redirect_to to router options + Also add * for all methods shortcut * Remove comments Not allowed in normal json * Allow admin pages included into plugins dir * block access to some files * Fix admin logout * Fix #178 * feature: mail confirmed reward Suggested by @EPuncker # Conflicts: # system/hooks.php * remove misleading comment * adjust required version according to composer.json * fix duplicated word * Adjustments & fixed to mass actions * Add password confirm, and change text type to password * Add list of Open Source Software MyAAC is using * Fix signature * Show First, Second instead of numbers * fix base dir detection * fix double ACTION define + undefined URI in template * new function> escapeHtml + fix css in admin menus * fix changelog add * fix news adding, rename const to NEWS_* * Add verify to pages, add messages, limits, fix add * fix "Please fill all input" * add required input to admin pages * shorten some expressions with ?? * shorten code + fix conversion (int) * Move account_types to config, account.web_flags to common.php * Update example.json * feature: router aliases * shorten some code + const convert * remove wrong char * fix signature on custom basedir * fix: mass teleport position validation (#214) * fix: mass teleport position validation * fix: max position * Fix execute in CLI * fix warning in reload cache in dev mode * Configurable admin panel folder * feature: plugin require more options with comma * $config_account_salt -> USE_ACCOUNT_SALT * fix forum show_thread * Update show_thread.php --------- Co-authored-by: Gabriel Pedro --- .gitignore | 2 + .htaccess | 2 - admin/index.php | 29 +- .../pages/admin => admin/pages}/accounts.php | 10 +- .../pages/admin => admin/pages}/changelog.php | 25 +- {system/pages/admin => admin/pages}/clmd.php | 0 .../pages/admin => admin/pages}/dashboard.php | 6 +- {system/pages/admin => admin/pages}/data.php | 0 .../pages/admin => admin/pages}/index.html | 0 {system/pages/admin => admin/pages}/login.php | 8 +- {system/pages/admin => admin/pages}/logs.php | 0 .../pages/admin => admin/pages}/mailer.php | 0 .../pages/mass_account.php | 75 +++-- admin/pages/mass_teleport.php | 116 +++++++ {system/pages/admin => admin/pages}/menus.php | 2 +- .../admin => admin/pages}/modules/balance.php | 0 .../admin => admin/pages}/modules/coins.php | 0 .../admin => admin/pages}/modules/created.php | 0 .../admin => admin/pages}/modules/index.html | 0 .../pages}/modules/lastlogin.php | 0 .../admin => admin/pages}/modules/points.php | 0 .../pages}/modules/server_status.php | 0 .../pages}/modules/statistics.php | 0 .../modules/templates/balance.html.twig | 0 .../pages}/modules/templates/coins.html.twig | 0 .../modules/templates/created.html.twig | 0 .../pages}/modules/templates/index.html | 0 .../modules/templates/lastlogin.html.twig | 0 .../pages}/modules/templates/points.html.twig | 0 .../modules/templates/statistics.html.twig | 0 .../pages}/modules/templates/web_status.twig | 0 .../pages}/modules/web_status.php | 0 {system/pages/admin => admin/pages}/news.php | 30 +- .../pages/admin => admin/pages}/notepad.php | 0 .../pages/open_source.php | 12 +- {system/pages/admin => admin/pages}/pages.php | 121 +++++-- .../pages/admin => admin/pages}/phpinfo.php | 0 .../pages/admin => admin/pages}/players.php | 4 +- .../pages/admin => admin/pages}/plugins.php | 0 .../pages/admin => admin/pages}/reports.php | 0 .../admin => admin/pages}/statistics.php | 0 {system/pages/admin => admin/pages}/tools.php | 2 +- .../pages/admin => admin/pages}/version.php | 0 .../pages/admin => admin/pages}/visitors.php | 0 admin/template/menus.php | 34 +- admin/template/template.php | 7 +- common.php | 27 +- composer.json | 3 +- config.php | 23 +- index.php | 216 +------------ install/index.php | 6 +- install/steps/7-finish.php | 7 +- login.php | 3 +- plugins/email-confirmed-reward.json | 17 + plugins/email-confirmed-reward/reward.php | 33 ++ plugins/example.json | 35 +- system/compat/pages.php | 17 +- system/functions.php | 48 ++- system/hooks.php | 5 +- system/init.php | 5 + system/libs/news.php | 10 +- system/libs/plugins.php | 165 +++++++++- system/libs/pot/OTS_Base_DB.php | 33 +- system/locale/de/install.php | 5 +- system/locale/en/install.php | 5 +- system/locale/pl/install.php | 5 +- system/login.php | 233 ++++++-------- system/logout.php | 18 ++ system/pages/405.php | 16 + system/pages/account/base.php | 29 ++ system/pages/account/change_comment.php | 9 +- system/pages/account/change_email.php | 11 +- system/pages/account/change_info.php | 16 +- system/pages/account/change_name.php | 7 + system/pages/account/change_password.php | 19 +- system/pages/account/change_sex.php | 9 +- system/pages/account/confirm_email.php | 12 +- .../{createaccount.php => account/create.php} | 14 +- system/pages/account/create_character.php | 7 + system/pages/account/delete_character.php | 9 +- system/pages/account/logout.php | 22 ++ .../{lostaccount.php => account/lost.php} | 7 +- system/pages/account/manage.php | 97 ++++++ system/pages/account/redirect.php | 17 + system/pages/account/register.php | 11 +- system/pages/account/register_new.php | 17 +- system/pages/accountmanagement.php | 150 --------- system/pages/admin/tools/teleport.php | 100 ------ system/pages/changelog.php | 4 +- system/pages/characters.php | 2 +- system/pages/creatures.php | 99 +++--- system/pages/forum.php | 223 +++---------- system/pages/forum/admin.php | 95 ++++++ system/pages/forum/base.php | 51 +++ system/pages/forum/edit_post.php | 4 +- system/pages/forum/move_thread.php | 4 +- system/pages/forum/new_post.php | 15 +- system/pages/forum/new_thread.php | 4 +- system/pages/forum/remove_post.php | 4 +- system/pages/forum/show_board.php | 2 + system/pages/forum/show_thread.php | 4 +- system/pages/guilds.php | 9 +- system/pages/guilds/accept_invite.php | 2 + system/pages/guilds/add_rank.php | 4 +- system/pages/guilds/base.php | 17 + system/pages/guilds/change_description.php | 2 + system/pages/guilds/change_logo.php | 2 + system/pages/guilds/change_motd.php | 4 +- system/pages/guilds/change_nick.php | 2 + system/pages/guilds/change_rank.php | 2 + system/pages/guilds/cleanup_guilds.php | 4 +- system/pages/guilds/cleanup_players.php | 4 +- system/pages/guilds/create.php | 4 +- system/pages/guilds/delete_by_admin.php | 4 +- system/pages/guilds/delete_guild.php | 4 +- system/pages/guilds/delete_invite.php | 4 +- system/pages/guilds/delete_rank.php | 2 + system/pages/guilds/invite.php | 4 +- system/pages/guilds/kick_player.php | 4 +- .../guilds/{leave_guild.php => leave.php} | 2 + .../guilds/{list_of_guilds.php => list.php} | 2 + system/pages/guilds/manager.php | 4 +- system/pages/guilds/pass_leadership.php | 4 +- system/pages/guilds/save_ranks.php | 2 + system/pages/guilds/show.php | 3 + system/pages/highscores.php | 24 +- system/pages/news.php | 2 - .../{newsarchive.php => news/archive.php} | 3 +- system/pages/online.php | 3 +- system/router.php | 303 ++++++++++++++++++ system/routes.php | 58 ++++ system/templates/account.login.html.twig | 2 +- .../templates/admin.changelog.form.html.twig | 4 +- system/templates/admin.dashboard.html.twig | 0 system/templates/admin.login.html.twig | 2 +- system/templates/admin.news.form.html.twig | 2 +- system/templates/admin.open_source.html.twig | 32 ++ system/templates/admin.pages.form.html.twig | 10 +- system/templates/admin.plugins.form.html.twig | 2 +- .../templates/admin.tools.account.html.twig | 6 +- .../templates/admin.tools.teleport.html.twig | 15 +- system/templates/characters.html.twig | 2 +- system/templates/exception.html.twig | 6 +- system/templates/install.admin.html.twig | 8 +- system/templates/online.html.twig | 8 +- system/twig.php | 2 + templates/tibiacom/index.php | 2 +- 147 files changed, 1943 insertions(+), 1142 deletions(-) rename {system/pages/admin => admin/pages}/accounts.php (98%) rename {system/pages/admin => admin/pages}/changelog.php (82%) rename {system/pages/admin => admin/pages}/clmd.php (100%) rename {system/pages/admin => admin/pages}/dashboard.php (94%) rename {system/pages/admin => admin/pages}/data.php (100%) rename {system/pages/admin => admin/pages}/index.html (100%) rename {system/pages/admin => admin/pages}/login.php (66%) rename {system/pages/admin => admin/pages}/logs.php (100%) rename {system/pages/admin => admin/pages}/mailer.php (100%) rename system/pages/admin/tools/account.php => admin/pages/mass_account.php (64%) create mode 100644 admin/pages/mass_teleport.php rename {system/pages/admin => admin/pages}/menus.php (98%) rename {system/pages/admin => admin/pages}/modules/balance.php (100%) rename {system/pages/admin => admin/pages}/modules/coins.php (100%) rename {system/pages/admin => admin/pages}/modules/created.php (100%) rename {system/pages/admin => admin/pages}/modules/index.html (100%) rename {system/pages/admin => admin/pages}/modules/lastlogin.php (100%) rename {system/pages/admin => admin/pages}/modules/points.php (100%) rename {system/pages/admin => admin/pages}/modules/server_status.php (100%) rename {system/pages/admin => admin/pages}/modules/statistics.php (100%) rename {system/pages/admin => admin/pages}/modules/templates/balance.html.twig (100%) rename {system/pages/admin => admin/pages}/modules/templates/coins.html.twig (100%) rename {system/pages/admin => admin/pages}/modules/templates/created.html.twig (100%) rename {system/pages/admin => admin/pages}/modules/templates/index.html (100%) rename {system/pages/admin => admin/pages}/modules/templates/lastlogin.html.twig (100%) rename {system/pages/admin => admin/pages}/modules/templates/points.html.twig (100%) rename {system/pages/admin => admin/pages}/modules/templates/statistics.html.twig (100%) rename {system/pages/admin => admin/pages}/modules/templates/web_status.twig (100%) rename {system/pages/admin => admin/pages}/modules/web_status.php (100%) rename {system/pages/admin => admin/pages}/news.php (84%) rename {system/pages/admin => admin/pages}/notepad.php (100%) rename system/pages/account.php => admin/pages/open_source.php (51%) rename {system/pages/admin => admin/pages}/pages.php (59%) rename {system/pages/admin => admin/pages}/phpinfo.php (100%) rename {system/pages/admin => admin/pages}/players.php (99%) rename {system/pages/admin => admin/pages}/plugins.php (100%) rename {system/pages/admin => admin/pages}/reports.php (100%) rename {system/pages/admin => admin/pages}/statistics.php (100%) rename {system/pages/admin => admin/pages}/tools.php (89%) rename {system/pages/admin => admin/pages}/version.php (100%) rename {system/pages/admin => admin/pages}/visitors.php (100%) create mode 100644 plugins/email-confirmed-reward.json create mode 100644 plugins/email-confirmed-reward/reward.php create mode 100644 system/logout.php create mode 100644 system/pages/405.php create mode 100644 system/pages/account/base.php rename system/pages/{createaccount.php => account/create.php} (96%) create mode 100644 system/pages/account/logout.php rename system/pages/{lostaccount.php => account/lost.php} (99%) create mode 100644 system/pages/account/manage.php create mode 100644 system/pages/account/redirect.php delete mode 100644 system/pages/accountmanagement.php delete mode 100644 system/pages/admin/tools/teleport.php create mode 100644 system/pages/forum/admin.php create mode 100644 system/pages/forum/base.php create mode 100644 system/pages/guilds/base.php rename system/pages/guilds/{leave_guild.php => leave.php} (98%) rename system/pages/guilds/{list_of_guilds.php => list.php} (97%) rename system/pages/{newsarchive.php => news/archive.php} (86%) create mode 100644 system/router.php create mode 100644 system/routes.php delete mode 100644 system/templates/admin.dashboard.html.twig create mode 100644 system/templates/admin.open_source.html.twig diff --git a/.gitignore b/.gitignore index e24ffb58..1302f62a 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,8 @@ plugins/* !plugins/example.json !plugins/account-create-hint.json !plugins/account-create-hint +!plugins/email-confirmed-reward.json +!plugins/email-confirmed-reward landing # system diff --git a/.htaccess b/.htaccess index 9d8bd781..042cb23a 100644 --- a/.htaccess +++ b/.htaccess @@ -9,8 +9,6 @@ RewriteEngine On - # you can put here your myaac root folder - # path relative to web root #RewriteBase /myaac/ RewriteCond %{REQUEST_FILENAME} !-f diff --git a/admin/index.php b/admin/index.php index c47ac1d6..b6cc401a 100644 --- a/admin/index.php +++ b/admin/index.php @@ -1,9 +1,10 @@ load(); require SYSTEM . 'status.php'; require SYSTEM . 'login.php'; require SYSTEM . 'migrate.php'; -require ADMIN . 'includes/functions.php'; +require __DIR__ . '/includes/functions.php'; $twig->addGlobal('config', $config); $twig->addGlobal('status', $status); +if (ACTION == 'logout') { + require SYSTEM . 'logout.php'; +} + // if we're not logged in - show login box if(!$logged || !admin()) { $page = 'login'; } // include our page -$file = SYSTEM . 'pages/admin/' . $page . '.php'; +$file = __DIR__ . '/pages/' . $page . '.php'; if(!@file_exists($file)) { - $page = '404'; - $file = SYSTEM . 'pages/404.php'; + if (strpos($page, 'plugins/') !== false) { + $file = BASE . $page; + } + else { + $page = '404'; + $file = SYSTEM . 'pages/404.php'; + } } ob_start(); @@ -67,5 +77,4 @@ ob_end_clean(); // template $template_path = 'template/'; -require ADMIN . $template_path . 'template.php'; -?> +require __DIR__ . '/' . $template_path . 'template.php'; diff --git a/system/pages/admin/accounts.php b/admin/pages/accounts.php similarity index 98% rename from system/pages/admin/accounts.php rename to admin/pages/accounts.php index 8ef7de58..e481c782 100644 --- a/system/pages/admin/accounts.php +++ b/admin/pages/accounts.php @@ -31,8 +31,8 @@ if ($config['account_country']) { foreach ($config['countries'] as $code => $c) $countries[$code] = $c; } -$web_acc = array("None", "Admin", "Super Admin", "(Admin + Super Admin)"); -$acc_type = array("None", "Normal", "Tutor", "Senior Tutor", "Gamemaster", "God"); +$web_acc = ACCOUNT_WEB_FLAGS; +$acc_type = config('account_types'); ?> @@ -70,7 +70,6 @@ else if (isset($_REQUEST['search'])) { ?>
0) { $account = new OTS_Account(); $account->load($id); @@ -186,8 +185,7 @@ else if (isset($_REQUEST['search'])) { $account->setCustomField('web_lastlogin', $web_lastlogin); if (isset($password)) { - $config_salt_enabled = $db->hasColumn('accounts', 'salt'); - if ($config_salt_enabled) { + if (USE_ACCOUNT_SALT) { $salt = generateRandomString(10, false, true, true); $password = $salt . $password; $account->setCustomField('salt', $salt); @@ -196,7 +194,7 @@ else if (isset($_REQUEST['search'])) { $password = encrypt($password); $account->setPassword($password); - if ($config_salt_enabled) + if (USE_ACCOUNT_SALT) $account->setCustomField('salt', $salt); } diff --git a/system/pages/admin/changelog.php b/admin/pages/changelog.php similarity index 82% rename from system/pages/admin/changelog.php rename to admin/pages/changelog.php index a6e7d01c..4456344d 100644 --- a/system/pages/admin/changelog.php +++ b/admin/pages/changelog.php @@ -17,18 +17,18 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { $title = 'Changelog'; $use_datatable = true; -define('CL_LIMIT', 600); // maximum changelog body length +const CL_LIMIT = 600; // maximum changelog body length ?> orderBy('group_id', POT::ORDER_DESC); $twig->display('admin.changelog.form.html.twig', array( 'action' => $action, - 'cl_link_form' => constant('ADMIN_URL').'?p=changelog&action=' . ($action == 'edit' ? 'edit' : 'add'), - 'cl_id' => isset($id) ? $id : null, - 'body' => isset($body) ? htmlentities($body, ENT_COMPAT, 'UTF-8') : '', - 'create_date' => isset($create_date) ? $create_date : '', - 'player' => isset($player) && $player->isLoaded() ? $player : null, - 'player_id' => isset($player_id) ? $player_id : null, + 'cl_link_form' => constant('ADMIN_URL').'?p=changelog&action=' . ($action == 'edit' ? 'edit' : 'new'), + 'cl_id' => $id ?? null, + 'body' => isset($body) ? escapeHtml($body) : '', + 'create_date' => $create_date ?? '', + 'player_id' => $player_id ?? null, 'account_players' => $account_players, - 'type' => isset($type) ? $type : 0, - 'where' => isset($where) ? $where : 0, + 'type' => $type ?? 0, + 'where' => $where ?? 0, 'log_type' => $log_type, 'log_where' => $log_where, )); diff --git a/system/pages/admin/clmd.php b/admin/pages/clmd.php similarity index 100% rename from system/pages/admin/clmd.php rename to admin/pages/clmd.php diff --git a/system/pages/admin/dashboard.php b/admin/pages/dashboard.php similarity index 94% rename from system/pages/admin/dashboard.php rename to admin/pages/dashboard.php index ba0ba8a0..53380503 100644 --- a/system/pages/admin/dashboard.php +++ b/admin/pages/dashboard.php @@ -47,10 +47,6 @@ $tmp = ''; if (fetchDatabaseConfig('site_closed_message', $tmp)) $closed_message = $tmp; -echo '
'; -$twig->display('admin.dashboard.html.twig', array()); -echo '
'; - $configAdminPanelModules = config('admin_panel_modules'); if (isset($configAdminPanelModules)) { echo '
'; @@ -63,4 +59,4 @@ if (isset($configAdminPanelModules)) { } } echo '
'; -} \ No newline at end of file +} diff --git a/system/pages/admin/data.php b/admin/pages/data.php similarity index 100% rename from system/pages/admin/data.php rename to admin/pages/data.php diff --git a/system/pages/admin/index.html b/admin/pages/index.html similarity index 100% rename from system/pages/admin/index.html rename to admin/pages/index.html diff --git a/system/pages/admin/login.php b/admin/pages/login.php similarity index 66% rename from system/pages/admin/login.php rename to admin/pages/login.php index 24c1e9b5..76d25d49 100644 --- a/system/pages/admin/login.php +++ b/admin/pages/login.php @@ -10,9 +10,9 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Login'; -$twig->display('admin.login.html.twig', array( - 'logout' => ($action == 'logout' ? 'You have been logged out!' : ''), +$twig->display('admin.login.html.twig', [ + 'logout' => (ACTION == 'logout' ? 'You have been logged out!' : ''), 'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', 'account_login_by' => getAccountLoginByLabel(), - 'errors' => isset($errors)? $errors : '' -)); + 'errors' => $errors ?? '' +]); diff --git a/system/pages/admin/logs.php b/admin/pages/logs.php similarity index 100% rename from system/pages/admin/logs.php rename to admin/pages/logs.php diff --git a/system/pages/admin/mailer.php b/admin/pages/mailer.php similarity index 100% rename from system/pages/admin/mailer.php rename to admin/pages/mailer.php diff --git a/system/pages/admin/tools/account.php b/admin/pages/mass_account.php similarity index 64% rename from system/pages/admin/tools/account.php rename to admin/pages/mass_account.php index 322d3806..507ef877 100644 --- a/system/pages/admin/tools/account.php +++ b/admin/pages/mass_account.php @@ -22,23 +22,23 @@ function admin_give_points($points) global $db, $hasPointsColumn; if (!$hasPointsColumn) { - error('Points not supported.'); + displayMessage('Points not supported.'); return; } $statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points'); if (!$statement) { - error('Failed to prepare query statement.'); + displayMessage('Failed to prepare query statement.'); return; } if (!$statement->execute([ 'points' => $points ])) { - error('Failed to add points.'); + displayMessage('Failed to add points.'); return; } - success($points . ' points added to all accounts.'); + displayMessage($points . ' points added to all accounts.', true); } function admin_give_coins($coins) @@ -46,24 +46,24 @@ function admin_give_coins($coins) global $db, $hasCoinsColumn; if (!$hasCoinsColumn) { - error('Coins not supported.'); + displayMessage('Coins not supported.'); return; } $statement = $db->prepare('UPDATE `accounts` SET `coins` = `coins` + :coins'); if (!$statement) { - error('Failed to prepare query statement.'); + displayMessage('Failed to prepare query statement.'); return; } if (!$statement->execute([ 'coins' => $coins ])) { - error('Failed to add coins.'); + displayMessage('Failed to add coins.'); return; } - success($coins . ' coins added to all accounts.'); + displayMessage($coins . ' coins added to all accounts.', true); } function query_add_premium($column, $value_query, $condition_query = '1=1', $params = []) @@ -72,12 +72,12 @@ function query_add_premium($column, $value_query, $condition_query = '1=1', $par $statement = $db->prepare("UPDATE `accounts` SET `{$column}` = $value_query WHERE $condition_query"); if (!$statement) { - error('Failed to prepare query statement.'); + displayMessage('Failed to prepare query statement.'); return false; } if (!$statement->execute($params)) { - error('Failed to add premium days.'); + displayMessage('Failed to add premium days.'); return false; } @@ -89,7 +89,7 @@ function admin_give_premdays($days) global $db, $freePremium; if ($freePremium) { - error('Premium days not supported. Free Premium enabled.'); + displayMessage('Premium days not supported. Free Premium enabled.'); return; } @@ -101,14 +101,14 @@ function admin_give_premdays($days) if (query_add_premium('premend', '`premend` + :value', '`premend` > :now', ['value' => $value, 'now' => $now])) { // set premend if (query_add_premium('premend', ':value', '`premend` <= :now', ['value' => $now + $value, 'now' => $now])) { - success($days . ' premium days added to all accounts.'); + displayMessage($days . ' premium days added to all accounts.', true); return; } else { - error('Failed to execute set query.'); + displayMessage('Failed to execute set query.'); return; } } else { - error('Failed to execute append query.'); + displayMessage('Failed to execute append query.'); return; } @@ -123,20 +123,20 @@ function admin_give_premdays($days) if (query_add_premium('lastday', '`lastday` + :value', '`lastday` > :now', ['value' => $value, 'now' => $now])) { // set lastday if (query_add_premium('lastday', ':value', '`lastday` <= :now', ['value' => $now + $value, 'now' => $now])) { - success($days . ' premium days added to all accounts.'); + displayMessage($days . ' premium days added to all accounts.', true); return; } else { - error('Failed to execute set query.'); + displayMessage('Failed to execute set query.'); return; } - success($days . ' premium days added to all accounts.'); + return; } else { - error('Failed to execute append query.'); + displayMessage('Failed to execute append query.'); return; } } else { - error('Failed to execute set days query.'); + displayMessage('Failed to execute set days query.'); return; } @@ -149,21 +149,21 @@ function admin_give_premdays($days) if (query_add_premium('premium_ends_at', '`premium_ends_at` + :value', '`premium_ends_at` > :now', ['value' => $value, 'now' => $now])) { // set premium_ends_at if (query_add_premium('premium_ends_at', ':value', '`premium_ends_at` <= :now', ['value' => $now + $value, 'now' => $now])) { - success($days . ' premium days added to all accounts.'); + displayMessage($days . ' premium days added to all accounts.', true); return; } else { - error('Failed to execute set query.'); + displayMessage('Failed to execute set query.'); return; } } else { - error('Failed to execute append query.'); + displayMessage('Failed to execute append query.'); return; } return; } - error('Premium Days not supported.'); + displayMessage('Premium Days not supported.'); } if (isset($_POST['action']) && $_POST['action']) { @@ -171,12 +171,12 @@ if (isset($_POST['action']) && $_POST['action']) { $action = $_POST['action']; if (preg_match("/[^A-z0-9_\-]/", $action)) { - error('Invalid action.'); + displayMessage('Invalid action.'); } else { $value = isset($_POST['value']) ? intval($_POST['value']) : 0; if (!$value) { - error('Please fill all inputs'); + displayMessage('Please fill all inputs'); } else { switch ($action) { case 'give-points': @@ -189,14 +189,27 @@ if (isset($_POST['action']) && $_POST['action']) { admin_give_premdays($value); break; default: - error('Action ' . $action . 'not found.'); + displayMessage('Action ' . $action . 'not found.'); } } } } +else { + $twig->display('admin.tools.account.html.twig', array( + 'hasCoinsColumn' => $hasCoinsColumn, + 'hasPointsColumn' => $hasPointsColumn, + 'freePremium' => $freePremium, + )); +} -$twig->display('admin.tools.account.html.twig', array( - 'hasCoinsColumn' => $hasCoinsColumn, - 'hasPointsColumn' => $hasPointsColumn, - 'freePremium' => $freePremium, -)); +function displayMessage($message, $success = false) { + global $twig, $hasCoinsColumn, $hasPointsColumn, $freePremium; + + $success ? success($message): error($message); + + $twig->display('admin.tools.account.html.twig', array( + 'hasCoinsColumn' => $hasCoinsColumn, + 'hasPointsColumn' => $hasPointsColumn, + 'freePremium' => $freePremium, + )); +} diff --git a/admin/pages/mass_teleport.php b/admin/pages/mass_teleport.php new file mode 100644 index 00000000..972975e2 --- /dev/null +++ b/admin/pages/mass_teleport.php @@ -0,0 +1,116 @@ + + * @author Lee + * @copyright 2020 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +$title = 'Mass Teleport Actions'; + +function admin_teleport_position($x, $y, $z) { + global $db; + $statement = $db->prepare('UPDATE `players` SET `posx` = :x, `posy` = :y, `posz` = :z'); + if (!$statement) { + displayMessage('Failed to prepare query statement.'); + return; + } + + if (!$statement->execute([ + 'x' => $x, 'y' => $y, 'z' => $z + ])) { + displayMessage('Failed to execute query.'); + return; + } + + displayMessage('Player\'s position updated.', true); +} + +function admin_teleport_town($town_id) { + global $db; + $statement = $db->prepare('UPDATE `players` SET `town_id` = :town_id'); + if (!$statement) { + displayMessage('Failed to prepare query statement.'); + return; + } + + if (!$statement->execute([ + 'town_id' => $town_id + ])) { + displayMessage('Failed to execute query.'); + return; + } + + displayMessage('Player\'s town updated.', true); +} + +if (isset($_POST['action']) && $_POST['action']) { + + $action = $_POST['action']; + + if (preg_match("/[^A-z0-9_\-]/", $action)) { + displayMessage('Invalid action.'); + } else { + + $playersOnline = 0; + if($db->hasTable('players_online')) {// tfs 1.0 + $query = $db->query('SELECT count(*) AS `count` FROM `players_online`'); + } else { + $query = $db->query('SELECT count(*) AS `count` FROM `players` WHERE `players`.`online` > 0'); + } + + $playersOnline = $query->fetch(PDO::FETCH_ASSOC); + if ($playersOnline['count'] > 0) { + displayMessage('Please, close the server before execute this action otherwise players will not be affected.'); + return; + } + + $town_id = isset($_POST['town_id']) ? intval($_POST['town_id']) : null; + $posx = isset($_POST['posx']) ? intval($_POST['posx']) : null; + $posy = isset($_POST['posy']) ? intval($_POST['posy']) : null; + $posz = isset($_POST['posz']) ? intval($_POST['posz']) : null; + $to_temple = $_POST['to_temple'] ?? null; + + switch ($action) { + case 'set-town': + if (!$town_id) { + displayMessage('Please fill all inputs'); + return; + } + + if (!isset($config['towns'][$town_id])) { + displayMessage('Specified town does not exist'); + return; + } + + admin_teleport_town($town_id); + break; + case 'set-position': + if (!$to_temple && ($posx < 0 || $posx > 65535 || $posy < 0 || $posy > 65535|| $posz < 0 || $posz > 16)) { + displayMessage('Invalid Position'); + return; + } + + admin_teleport_position($posx, $posy, $posz); + break; + default: + displayMessage('Action ' . $action . 'not found.'); + } + } + +} +else { + $twig->display('admin.tools.teleport.html.twig', array()); +} + + +function displayMessage($message, $success = false) { + global $twig; + + $success ? success($message): error($message); + $twig->display('admin.tools.teleport.html.twig', array()); +} diff --git a/system/pages/admin/menus.php b/admin/pages/menus.php similarity index 98% rename from system/pages/admin/menus.php rename to admin/pages/menus.php index e6b033ea..20045528 100644 --- a/system/pages/admin/menus.php +++ b/admin/pages/menus.php @@ -93,7 +93,7 @@ if (isset($_REQUEST['template'])) { if (isset($menus[$id])) { foreach ($menus[$id] as $i => $menu): ?> -
  • +
  • diff --git a/system/pages/admin/modules/balance.php b/admin/pages/modules/balance.php similarity index 100% rename from system/pages/admin/modules/balance.php rename to admin/pages/modules/balance.php diff --git a/system/pages/admin/modules/coins.php b/admin/pages/modules/coins.php similarity index 100% rename from system/pages/admin/modules/coins.php rename to admin/pages/modules/coins.php diff --git a/system/pages/admin/modules/created.php b/admin/pages/modules/created.php similarity index 100% rename from system/pages/admin/modules/created.php rename to admin/pages/modules/created.php diff --git a/system/pages/admin/modules/index.html b/admin/pages/modules/index.html similarity index 100% rename from system/pages/admin/modules/index.html rename to admin/pages/modules/index.html diff --git a/system/pages/admin/modules/lastlogin.php b/admin/pages/modules/lastlogin.php similarity index 100% rename from system/pages/admin/modules/lastlogin.php rename to admin/pages/modules/lastlogin.php diff --git a/system/pages/admin/modules/points.php b/admin/pages/modules/points.php similarity index 100% rename from system/pages/admin/modules/points.php rename to admin/pages/modules/points.php diff --git a/system/pages/admin/modules/server_status.php b/admin/pages/modules/server_status.php similarity index 100% rename from system/pages/admin/modules/server_status.php rename to admin/pages/modules/server_status.php diff --git a/system/pages/admin/modules/statistics.php b/admin/pages/modules/statistics.php similarity index 100% rename from system/pages/admin/modules/statistics.php rename to admin/pages/modules/statistics.php diff --git a/system/pages/admin/modules/templates/balance.html.twig b/admin/pages/modules/templates/balance.html.twig similarity index 100% rename from system/pages/admin/modules/templates/balance.html.twig rename to admin/pages/modules/templates/balance.html.twig diff --git a/system/pages/admin/modules/templates/coins.html.twig b/admin/pages/modules/templates/coins.html.twig similarity index 100% rename from system/pages/admin/modules/templates/coins.html.twig rename to admin/pages/modules/templates/coins.html.twig diff --git a/system/pages/admin/modules/templates/created.html.twig b/admin/pages/modules/templates/created.html.twig similarity index 100% rename from system/pages/admin/modules/templates/created.html.twig rename to admin/pages/modules/templates/created.html.twig diff --git a/system/pages/admin/modules/templates/index.html b/admin/pages/modules/templates/index.html similarity index 100% rename from system/pages/admin/modules/templates/index.html rename to admin/pages/modules/templates/index.html diff --git a/system/pages/admin/modules/templates/lastlogin.html.twig b/admin/pages/modules/templates/lastlogin.html.twig similarity index 100% rename from system/pages/admin/modules/templates/lastlogin.html.twig rename to admin/pages/modules/templates/lastlogin.html.twig diff --git a/system/pages/admin/modules/templates/points.html.twig b/admin/pages/modules/templates/points.html.twig similarity index 100% rename from system/pages/admin/modules/templates/points.html.twig rename to admin/pages/modules/templates/points.html.twig diff --git a/system/pages/admin/modules/templates/statistics.html.twig b/admin/pages/modules/templates/statistics.html.twig similarity index 100% rename from system/pages/admin/modules/templates/statistics.html.twig rename to admin/pages/modules/templates/statistics.html.twig diff --git a/system/pages/admin/modules/templates/web_status.twig b/admin/pages/modules/templates/web_status.twig similarity index 100% rename from system/pages/admin/modules/templates/web_status.twig rename to admin/pages/modules/templates/web_status.twig diff --git a/system/pages/admin/modules/web_status.php b/admin/pages/modules/web_status.php similarity index 100% rename from system/pages/admin/modules/web_status.php rename to admin/pages/modules/web_status.php diff --git a/system/pages/admin/news.php b/admin/pages/news.php similarity index 84% rename from system/pages/admin/news.php rename to admin/pages/news.php index 46f30c85..66398b09 100644 --- a/system/pages/admin/news.php +++ b/admin/pages/news.php @@ -23,8 +23,8 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { header('X-XSS-Protection:0'); // some constants, used mainly by database (cannot by modified without schema changes) -define('TITLE_LIMIT', 100); -define('BODY_LIMIT', 65535); // maximum news body length +define('NEWS_TITLE_LIMIT', 100); +define('NEWS_BODY_LIMIT', 65535); // maximum news body length define('ARTICLE_TEXT_LIMIT', 300); define('ARTICLE_IMAGE_LIMIT', 100); @@ -43,12 +43,12 @@ if(!empty($action)) $forum_section = isset($_REQUEST['forum_section']) ? $_REQUEST['forum_section'] : null; $errors = array(); - if($action == 'add') { + if($action == 'new') { if(isset($forum_section) && $forum_section != '-1') { $forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors); } - if(News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) { + if(isset($p_title) && News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) { $p_title = $body = $comments = $article_text = $article_image = ''; $type = $category = $player_id = 0; @@ -115,21 +115,21 @@ if($action == 'edit' || $action == 'new') { $twig->display('admin.news.form.html.twig', array( 'action' => $action, 'news_link' => getLink(PAGE), - 'news_link_form' => '?p=news&action=' . ($action == 'edit' ? 'edit' : 'add'), - 'news_id' => isset($id) ? $id : null, - 'title' => isset($p_title) ? $p_title : '', - 'body' => isset($body) ? htmlentities($body, ENT_COMPAT, 'UTF-8') : '', - 'type' => isset($type) ? $type : null, + 'news_link_form' => '?p=news&action=' . ($action == 'edit' ? 'edit' : 'new'), + 'news_id' => $id ?? null, + 'title' => $p_title ?? '', + 'body' => isset($body) ? escapeHtml($body) : '', + 'type' => $type ?? null, 'player' => isset($player) && $player->isLoaded() ? $player : null, - 'player_id' => isset($player_id) ? $player_id : null, + 'player_id' => $player_id ?? null, 'account_players' => $account_players, - 'category' => isset($category) ? $category : 0, + 'category' => $category ?? 0, 'categories' => $categories, 'forum_boards' => getForumBoards(), - 'forum_section' => isset($forum_section) ? $forum_section : null, - 'comments' => isset($comments) ? $comments : null, - 'article_text' => isset($article_text) ? $article_text : null, - 'article_image' => isset($article_image) ? $article_image : null + 'forum_section' => $forum_section ?? null, + 'comments' => $comments ?? null, + 'article_text' => $article_text ?? null, + 'article_image' => $article_image ?? null )); } diff --git a/system/pages/admin/notepad.php b/admin/pages/notepad.php similarity index 100% rename from system/pages/admin/notepad.php rename to admin/pages/notepad.php diff --git a/system/pages/account.php b/admin/pages/open_source.php similarity index 51% rename from system/pages/account.php rename to admin/pages/open_source.php index 31366187..de6e1e01 100644 --- a/system/pages/account.php +++ b/admin/pages/open_source.php @@ -1,16 +1,14 @@ - * @copyright 2019 MyAAC + * @copyright 2023 MyAAC * @link https://my-aac.org */ defined('MYAAC') or die('Direct access not allowed!'); -if($action == 'confirm_email') { - require_once PAGES . 'account/confirm_email.php'; -} -?> +$title = 'Open Source'; + +$twig->display('admin.open_source.html.twig'); diff --git a/system/pages/admin/pages.php b/admin/pages/pages.php similarity index 59% rename from system/pages/admin/pages.php rename to admin/pages/pages.php index d6f1f0ab..8e61224b 100644 --- a/system/pages/admin/pages.php +++ b/admin/pages/pages.php @@ -18,13 +18,18 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { header('X-XSS-Protection:0'); -$name = $p_title = ''; +$name = $p_title = null; $groups = new OTS_Groups_List(); $php = false; $enable_tinymce = true; $access = 0; +// some constants, used mainly by database (cannot by modified without schema changes) +define('PAGE_TITLE_LIMIT', 30); +define('PAGE_NAME_LIMIT', 30); +define('PAGE_BODY_LIMIT', 65535); // maximum page body length + if (!empty($action)) { if ($action == 'delete' || $action == 'edit' || $action == 'hide') $id = $_REQUEST['id']; @@ -50,12 +55,13 @@ if (!empty($action)) { $errors = array(); $player_id = 1; - if ($action == 'add') { - if (Pages::add($name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { + if ($action == 'new') { + if (isset($p_title) && Pages::add($name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { $name = $p_title = $body = ''; $player_id = $access = 0; $php = false; $enable_tinymce = true; + success('Added successful.'); } } else if ($action == 'delete') { if (Pages::delete($id, $errors)) @@ -70,15 +76,18 @@ if (!empty($action)) { $enable_tinymce = $_page['enable_tinymce'] == '1'; $access = $_page['access']; } else { - Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access); - $action = $name = $p_title = $body = ''; - $player_id = 1; - $access = 0; - $php = false; - $enable_tinymce = true; + if(Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access)) { + $action = $name = $p_title = $body = ''; + $player_id = 1; + $access = 0; + $php = false; + $enable_tinymce = true; + success("Updated successful."); + } } } else if ($action == 'hide') { - Pages::toggleHidden($id, $errors); + Pages::toggleHidden($id, $errors, $status); + success(($status == 1 ? 'Show' : 'Hide') . " successful."); } if (!empty($errors)) @@ -106,7 +115,7 @@ $twig->display('admin.pages.form.html.twig', array( 'title' => $p_title, 'php' => $php, 'enable_tinymce' => $enable_tinymce, - 'body' => isset($body) ? htmlentities($body, ENT_COMPAT, 'UTF-8') : '', + 'body' => isset($body) ? escapeHtml($body) : '', 'groups' => $groups->getGroups(), 'access' => $access )); @@ -117,6 +126,44 @@ $twig->display('admin.pages.html.twig', array( class Pages { + static public function verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors) + { + if(!isset($title[0]) || !isset($body[0])) { + $errors[] = 'Please fill all inputs.'; + return false; + } + if(strlen($name) > PAGE_NAME_LIMIT) { + $errors[] = 'Page name cannot be longer than ' . PAGE_NAME_LIMIT . ' characters.'; + return false; + } + if(strlen($title) > PAGE_TITLE_LIMIT) { + $errors[] = 'Page title cannot be longer than ' . PAGE_TITLE_LIMIT . ' characters.'; + return false; + } + if(strlen($body) > PAGE_BODY_LIMIT) { + $errors[] = 'Page content cannot be longer than ' . PAGE_BODY_LIMIT . ' characters.'; + return false; + } + if(!isset($player_id) || $player_id == 0) { + $errors[] = 'Player ID is wrong.'; + return false; + } + if(!isset($php) || ($php != 0 && $php != 1)) { + $errors[] = 'Enable PHP is wrong.'; + return false; + } + if(!isset($enable_tinymce) || ($enable_tinymce != 0 && $enable_tinymce != 1)) { + $errors[] = 'Enable TinyMCE is wrong.'; + return false; + } + if(!isset($access) || $access < 0 || $access > PHP_INT_MAX) { + $errors[] = 'Access is wrong.'; + return false; + } + + return true; + } + static public function get($id) { global $db; @@ -129,31 +176,36 @@ class Pages static public function add($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors) { + if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { + return false; + } + global $db; - if (isset($name[0]) && isset($title[0]) && isset($body[0]) && $player_id != 0) { - $query = $db->select(TABLE_PREFIX . 'pages', array('name' => $name)); - if ($query === false) - $db->insert(TABLE_PREFIX . 'pages', - array( - 'name' => $name, - 'title' => $title, - 'body' => $body, - 'player_id' => $player_id, - 'php' => $php ? '1' : '0', - 'enable_tinymce' => $enable_tinymce ? '1' : '0', - 'access' => $access - ) - ); - else - $errors[] = 'Page with this link already exists.'; - } else - $errors[] = 'Please fill all inputs.'; + $query = $db->select(TABLE_PREFIX . 'pages', array('name' => $name)); + if ($query === false) + $db->insert(TABLE_PREFIX . 'pages', + array( + 'name' => $name, + 'title' => $title, + 'body' => $body, + 'player_id' => $player_id, + 'php' => $php ? '1' : '0', + 'enable_tinymce' => $enable_tinymce ? '1' : '0', + 'access' => $access + ) + ); + else + $errors[] = 'Page with this link already exists.'; return !count($errors); } static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access) { + if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { + return false; + } + global $db; $db->update(TABLE_PREFIX . 'pages', array( @@ -166,6 +218,8 @@ class Pages 'access' => $access ), array('id' => $id)); + + return true; } static public function delete($id, &$errors) @@ -182,15 +236,18 @@ class Pages return !count($errors); } - static public function toggleHidden($id, &$errors) + static public function toggleHidden($id, &$errors, &$status) { global $db; if (isset($id)) { $query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id)); - if ($query !== false) + if ($query !== false) { $db->update(TABLE_PREFIX . 'pages', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id)); - else + $status = $query['hidden']; + } + else { $errors[] = 'Page with id ' . $id . ' does not exists.'; + } } else $errors[] = 'id not set'; diff --git a/system/pages/admin/phpinfo.php b/admin/pages/phpinfo.php similarity index 100% rename from system/pages/admin/phpinfo.php rename to admin/pages/phpinfo.php diff --git a/system/pages/admin/players.php b/admin/pages/players.php similarity index 99% rename from system/pages/admin/players.php rename to admin/pages/players.php index 3b139a79..0ab43f1d 100644 --- a/system/pages/admin/players.php +++ b/admin/pages/players.php @@ -634,9 +634,9 @@ else if (isset($_REQUEST['search'])) { diff --git a/system/pages/admin/plugins.php b/admin/pages/plugins.php similarity index 100% rename from system/pages/admin/plugins.php rename to admin/pages/plugins.php diff --git a/system/pages/admin/reports.php b/admin/pages/reports.php similarity index 100% rename from system/pages/admin/reports.php rename to admin/pages/reports.php diff --git a/system/pages/admin/statistics.php b/admin/pages/statistics.php similarity index 100% rename from system/pages/admin/statistics.php rename to admin/pages/statistics.php diff --git a/system/pages/admin/tools.php b/admin/pages/tools.php similarity index 89% rename from system/pages/admin/tools.php rename to admin/pages/tools.php index 4992b7f9..fa75d750 100644 --- a/system/pages/admin/tools.php +++ b/admin/pages/tools.php @@ -21,7 +21,7 @@ if (preg_match("/[^A-z0-9_\-]/", $tool)) { return; } -$file = SYSTEM . 'pages/admin/tools/' . $tool . '.php'; +$file = ADMIN . 'tools/' . $tool . '.php'; if (@file_exists($file)) { require $file; diff --git a/system/pages/admin/version.php b/admin/pages/version.php similarity index 100% rename from system/pages/admin/version.php rename to admin/pages/version.php diff --git a/system/pages/admin/visitors.php b/admin/pages/visitors.php similarity index 100% rename from system/pages/admin/visitors.php rename to admin/pages/visitors.php diff --git a/admin/template/menus.php b/admin/template/menus.php index e2075d58..460c03dd 100644 --- a/admin/template/menus.php +++ b/admin/template/menus.php @@ -4,23 +4,23 @@ $menus = [ ['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'], ['name' => 'News', 'icon' => 'newspaper', 'order' => 20, 'link' => [ - ['name' => 'View', 'link' => 'news', 'order' => 10], - ['name' => 'Add news', 'link' => 'news&action=new&type=1', 'order' => 20], - ['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'order' => 30], - ['name' => 'Add article', 'link' => 'news&action=new&type=3', 'order' => 40], + ['name' => 'View', 'link' => 'news', 'icon' => 'list', 'order' => 10], + ['name' => 'Add news', 'link' => 'news&action=new&type=1', 'icon' => 'plus', 'order' => 20], + ['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'icon' => 'plus', 'order' => 30], + ['name' => 'Add article', 'link' => 'news&action=new&type=3', 'icon' => 'plus', 'order' => 40], ], ], ['name' => 'Changelogs', 'icon' => 'newspaper', 'order' => 30, 'link' => [ - ['name' => 'View', 'link' => 'changelog', 'order' => 10], - ['name' => 'Add', 'link' => 'changelog&action=new', 'order' => 20], + ['name' => 'View', 'link' => 'changelog', 'icon' => 'list', 'order' => 10], + ['name' => 'Add', 'link' => 'changelog&action=new', 'icon' => 'plus', 'order' => 20], ], ], ['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !config('mail_enabled')], ['name' => 'Pages', 'icon' => 'book', 'order' => 50, 'link' => [ - ['name' => 'View', 'link' => 'pages', 'order' => 10], - ['name' => 'Add', 'link' => 'pages&action=new', 'order' => 20], + ['name' => 'View', 'link' => 'pages', 'icon' => 'list', 'order' => 10], + ['name' => 'Add', 'link' => 'pages&action=new', 'icon' => 'plus', 'order' => 20], ], ], ['name' => 'Menus', 'icon' => 'list', 'order' => 60, 'link' => 'menus'], @@ -28,23 +28,23 @@ $menus = [ ['name' => 'Server Data', 'icon' => 'gavel', 'order' => 80, 'link' => 'data'], ['name' => 'Editor', 'icon' => 'edit', 'order' => 90, 'link' => [ - ['name' => 'Accounts', 'link' => 'accounts', 'order' => 10], - ['name' => 'Players', 'link' => 'players', 'order' => 20], + ['name' => 'Accounts', 'link' => 'accounts', 'icon' => 'users', 'order' => 10], + ['name' => 'Players', 'link' => 'players', 'icon' => 'user-astronaut', 'order' => 20], ], ], ['name' => 'Tools', 'icon' => 'tools', 'order' => 100, 'link' => [ - ['name' => 'Mass Account Actions', 'link' => 'tools&tool=account', 'order' => 10], - ['name' => 'Mass Teleport Actions', 'link' => 'tools&tool=teleport', 'order' => 20], - ['name' => 'Notepad', 'link' => 'notepad', 'order' => 30], - ['name' => 'phpinfo', 'link' => 'phpinfo', 'order' => 40], + ['name' => 'Mass Account Actions', 'link' => 'mass_account', 'icon' => 'globe', 'order' => 10], + ['name' => 'Mass Teleport Actions', 'link' => 'mass_teleport', 'icon' => 'globe', 'order' => 20], + ['name' => 'Notepad', 'link' => 'notepad', 'icon' => 'marker', 'order' => 30], + ['name' => 'phpinfo', 'link' => 'phpinfo', 'icon' => 'server', 'order' => 40], ], ], ['name' => 'Logs', 'icon' => 'bug', 'order' => 110, 'link' => [ - ['name' => 'Logs', 'link' => 'logs', 'order' => 10], - ['name' => 'Reports', 'link' => 'reports', 'order' => 20], - ['name' => 'Visitors', 'icon' => 'user', 'link' => 'visitors', 'order' => 30], + ['name' => 'Logs', 'link' => 'logs', 'icon' => 'book', 'order' => 10], + ['name' => 'Reports', 'link' => 'reports', 'icon' => 'book', 'order' => 20], + ['name' => 'Visitors', 'link' => 'visitors', 'icon' => 'user', 'order' => 30], ], ], ]; diff --git a/admin/template/template.php b/admin/template/template.php index 407fd8ac..76f120c9 100644 --- a/admin/template/template.php +++ b/admin/template/template.php @@ -79,12 +79,12 @@ $nav_construct .= ' active'; $used_menu = true; } - $nav_construct .= '">

    ' . $sub_menu['name'] . '

  • '; + $nav_construct .= '">

    ' . $sub_menu['name'] . '

    '; } ?>
    diff --git a/common.php b/common.php index ab158b6a..dfe6439d 100644 --- a/common.php +++ b/common.php @@ -23,7 +23,7 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ -if (version_compare(phpversion(), '7.1', '<')) die('PHP version 7.1 or higher is required.'); +if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.'); const MYAAC = true; const MYAAC_VERSION = '0.9.0-dev'; @@ -34,8 +34,10 @@ define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS define('IS_CLI', in_array(php_sapi_name(), ['cli', 'phpdb'])); // account flags +const FLAG_NONE = 0; const FLAG_ADMIN = 1; const FLAG_SUPER_ADMIN = 2; +const FLAG_SUPER_BOTH = 3; const FLAG_CONTENT_PAGES = 4; const FLAG_CONTENT_MAILER = 8; const FLAG_CONTENT_NEWS = 16; @@ -49,14 +51,27 @@ const FLAG_CONTENT_FAQ = 2048; const FLAG_CONTENT_MENUS = 4096; const FLAG_CONTENT_PLAYERS = 8192; +// account access types +const ACCOUNT_WEB_FLAGS = [ + FLAG_NONE => 'None', + FLAG_ADMIN =>'Admin', + FLAG_SUPER_ADMIN => 'Super Admin', + FLAG_SUPER_BOTH =>'(Admin + Super Admin)', +]; + // news const NEWS = 1; const TICKER = 2; const ARTICLE = 3; +// here you can change location of admin panel +// you need also to rename folder "admin" +// this may improve security +const ADMIN_PANEL_FOLDER = 'admin'; + // directories const BASE = __DIR__ . '/'; -const ADMIN = BASE . 'admin/'; +const ADMIN = BASE . ADMIN_PANEL_FOLDER . '/'; const SYSTEM = BASE . 'system/'; const CACHE = SYSTEM . 'cache/'; const LOCALE = SYSTEM . 'locale/'; @@ -95,8 +110,10 @@ const TFS_LAST = TFS_03; // other definitions const ACCOUNT_NUMBER_LENGTH = 8; -session_save_path(SESSIONS_DIR); -session_start(); +if (!IS_CLI) { + session_save_path(SESSIONS_DIR); + session_start(); +} // basedir $basedir = ''; @@ -105,7 +122,7 @@ $size = count($tmp) - 1; for($i = 1; $i < $size; $i++) $basedir .= '/' . $tmp[$i]; -$basedir = str_replace(['/admin', '/install', '/tools'], '', $basedir); +$basedir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $basedir); define('BASE_DIR', $basedir); if(!IS_CLI) { diff --git a/composer.json b/composer.json index 167583be..90179c29 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "phpmailer/phpmailer": "^6.1", "composer/semver": "^3.2", "twig/twig": "^2.0", - "erusev/parsedown": "^1.7" + "erusev/parsedown": "^1.7", + "nikic/fast-route": "^1.3" } } diff --git a/config.php b/config.php index 50f42d66..0b6a3c96 100644 --- a/config.php +++ b/config.php @@ -73,7 +73,7 @@ $config = array( 'database_user' => '', 'database_password' => '', 'database_name' => '', - 'database_log' => false, // should database queries be logged and and saved into system/logs/database.log? + 'database_log' => false, // should database queries be logged and saved into system/logs/database.log? 'database_socket' => '', // set if you want to connect to database through socket (example: /var/run/mysqld/mysqld.sock) 'database_persistent' => false, // use database permanent connection (like server), may speed up your site @@ -103,7 +103,14 @@ $config = array( 'account_login_by_email_fallback' => false, // allow also additionally login by Account Name/Number (for users that might forget their email) 'account_create_auto_login' => false, // auto login after creating account? 'account_create_character_create' => true, // allow directly to create character on create account page? - 'account_mail_verify' => false, // force users to confirm their email addresses when registering account + 'account_mail_verify' => false, // force users to confirm their email addresses when registering + 'account_mail_confirmed_reward' => [ // reward users for confirming their E-Mails + // account_mail_verify needs to be enabled too + 'premium_days' => 0, + 'premium_points' => 0, + 'coins' => 0, + 'message' => 'You received %d %s for confirming your E-Mail address.' // example: You received 20 premium points for confirming your E-Mail address. + ], 'account_mail_unique' => true, // email addresses cannot be duplicated? (one account = one email) 'account_mail_block_plus_sign' => true, // block email with '+' signs like test+box@gmail.com (help protect against spamming accounts) 'account_premium_days' => 0, // default premium days on new account @@ -153,6 +160,18 @@ $config = array( 'send_mail_when_change_password' => true, // send e-mail with new password when change password to account 'send_mail_when_generate_reckey' => true, // send e-mail with rec key (key is displayed on page anyway when generate) + // you may need to adjust this for older tfs versions + // by removing Community Manager + 'account_types' => [ + 'None', + 'Normal', + 'Tutor', + 'Senior Tutor', + 'Gamemaster', + 'Community Manager', + 'God', + ], + // genders (aka sex) 'genders' => array( 0 => 'Female', diff --git a/index.php b/index.php index cb273f17..e15abb21 100644 --- a/index.php +++ b/index.php @@ -28,18 +28,22 @@ require_once 'common.php'; require_once SYSTEM . 'functions.php'; $uri = $_SERVER['REQUEST_URI']; +if(false !== strpos($uri, 'index.php')) { + $uri = str_replace_first('/index.php', '', $uri); +} -$tmp = BASE_DIR; -if(!empty($tmp)) - $uri = str_replace(BASE_DIR . '/', '', $uri); -else +if(0 === strpos($uri, '/')) { $uri = str_replace_first('/', '', $uri); +} -$uri = str_replace(array('index.php/', '?'), '', $uri); -define('URI', $uri); +if(preg_match("/^[A-Za-z0-9-_%'+\/]+\.png$/i", $uri)) { + if (!empty(BASE_DIR)) { + $tmp = explode('.', str_replace_first(str_replace_first('/', '', BASE_DIR) . '/', '', $uri)); + } + else { + $tmp = explode('.', $uri); + } -if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) { - $tmp = explode('.', $uri); $_REQUEST['name'] = urldecode($tmp[0]); chdir(TOOLS . 'signature'); @@ -47,7 +51,7 @@ if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) { exit(); } -if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) { +if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) { http_response_code(404); exit; } @@ -74,106 +78,6 @@ if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . throw new RuntimeException('Setup detected that install/ directory exists. Please visit this url to start MyAAC Installation.
    Delete install/ directory if you already installed MyAAC.
    Remember to REFRESH this page when you\'re done!'); } -$found = false; -if(empty($uri) || isset($_REQUEST['template'])) { - $_REQUEST['p'] = 'news'; - $found = true; -} -else { - $tmp = strtolower($uri); - if(!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(SYSTEM . 'pages/' . $tmp . '.php')) { - $_REQUEST['p'] = $uri; - $found = true; - } - else { - $rules = array( - '/^account\/manage\/?$/' => array('subtopic' => 'accountmanagement'), - '/^account\/create\/?$/' => array('subtopic' => 'createaccount'), - '/^account\/lost\/?$/' => array('subtopic' => 'lostaccount'), - '/^account\/logout\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'logout'), - '/^account\/password\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_password'), - '/^account\/register\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register'), - '/^account\/register\/new\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register_new'), - '/^account\/email\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_email'), - '/^account\/info\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_info'), - '/^account\/character\/create\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'create_character'), - '/^account\/character\/name\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_name'), - '/^account\/character\/sex\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_sex'), - '/^account\/character\/delete\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'delete_character'), - '/^account\/character\/comment\/[A-Za-z0-9-_%+\']+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment', 'name' => '$3'), - '/^account\/character\/comment\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment'), - '/^account\/confirm_email\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'confirm_email', 'v' => '$2'), - '/^bans\/[0-9]+\/?$/' => array('subtopic' => 'bans', 'page' => '$1'), - '/^characters\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'characters', 'name' => '$1'), - '/^changelog\/[0-9]+\/?$/' => array('subtopic' => 'changelog', 'page' => '$1'), - '/^commands\/add\/?$/' => array('subtopic' => 'commands', 'action' => 'add'), - '/^commands\/edit\/?$/' => array('subtopic' => 'commands', 'action' => 'edit'), - '/^creatures\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'creatures', 'creature' => '$1'), - '/^faq\/add\/?$/' => array('subtopic' => 'faq', 'action' => 'add'), - '/^faq\/edit\/?$/' => array('subtopic' => 'faq', 'action' => 'edit'), - '/^forum\/add_board\/?$/' => array('subtopic' => 'forum', 'action' => 'add_board'),# - '/^forum\/edit_board\/?$/' => array('subtopic' => 'forum', 'action' => 'edit_board'), - '/^forum\/board\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2'), - '/^forum\/board\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2', 'page' => '$3'), - '/^forum\/thread\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2'), - '/^forum\/thread\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2', 'page' => '$3'), - '/^gallery\/add\/?$/' => array('subtopic' => 'gallery', 'action' => 'add'), - '/^gallery\/edit\/?$/' => array('subtopic' => 'gallery', 'action' => 'edit'), - '/^gallery\/[0-9]+\/?$/' => array('subtopic' => 'gallery', 'image' => '$1'), - '/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'), - '/^guilds\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'guilds', 'action' => 'show', 'guild' => '$1'), - '/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2', 'page' => '$3'), - '/^highscores\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'page' => '$2'), - '/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2'), - '/^highscores\/[A-Za-z0-9-_\']+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1'), - '/^news\/add\/?$/' => array('subtopic' => 'news', 'action' => 'add'), - '/^news\/edit\/?$/' => array('subtopic' => 'news', 'action' => 'edit'), - '/^news\/archive\/?$/' => array('subtopic' => 'newsarchive'), - '/^news\/archive\/[0-9]+\/?$/' => array('subtopic' => 'newsarchive', 'id' => '$2'), - '/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'), - '/^spells\/[A-Za-z0-9-_%]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'spells', 'vocation' => '$1', 'order' => '$2'), - '/^houses\/view\/?$/' => array('subtopic' => 'houses', 'page' => 'view') - ); - - foreach($rules as $rule => $redirect) { - if (preg_match($rule, $uri)) { - $tmp = explode('/', $uri); - /* @var $redirect array */ - foreach($redirect as $key => $value) { - - if(strpos($value, '$') !== false) { - $value = str_replace('$' . $value[1], $tmp[$value[1]], $value); - } - - $_REQUEST[$key] = $value; - $_GET[$key] = $value; - } - - $found = true; - break; - } - } - } -} - -// define page visited, so it can be used within events system -$page = isset($_REQUEST['subtopic']) ? $_REQUEST['subtopic'] : (isset($_REQUEST['p']) ? $_REQUEST['p'] : ''); -if(empty($page) || !preg_match('/^[A-z0-9\_\-]+$/', $page)) { - $tmp = URI; - if(!empty($tmp)) { - $page = $tmp; - } - else { - if(!$found) - $page = '404'; - else - $page = 'news'; - } -} - -$page = strtolower($page); -define('PAGE', $page); - $template_place_holders = array(); require_once SYSTEM . 'init.php'; @@ -194,6 +98,8 @@ require_once SYSTEM . 'status.php'; $twig->addGlobal('config', $config); $twig->addGlobal('status', $status); +require_once SYSTEM . 'router.php'; + require SYSTEM . 'migrate.php'; $hooks->trigger(HOOK_STARTUP); @@ -242,35 +148,6 @@ if($config['visitors_counter']) $visitors = new Visitors($config['visitors_counter_ttl']); } -// page content loading -if(!isset($content[0])) - $content = ''; -$load_it = true; - -// check if site has been closed -$site_closed = false; -if(fetchDatabaseConfig('site_closed', $site_closed)) { - $site_closed = ($site_closed == 1); - if($site_closed) { - if(!admin()) - { - $title = getDatabaseConfig('site_closed_title'); - $content .= '

    ' . getDatabaseConfig('site_closed_message') . '


    '; - $load_it = false; - } - - if(!$logged) - { - ob_start(); - require SYSTEM . 'pages/accountmanagement.php'; - $content .= ob_get_contents(); - ob_end_clean(); - $load_it = false; - } - } -} -define('SITE_CLOSED', $site_closed); - // backward support for gesior if($config['backward_support']) { define('INITIALIZED', true); @@ -279,7 +156,6 @@ if($config['backward_support']) { $layout_name = $template_path; $news_content = ''; $tickers_content = ''; - $subtopic = PAGE; $main_content = ''; $config['access_admin_panel'] = 2; @@ -309,68 +185,6 @@ if($config['backward_support']) { $config['status']['serverStatus_' . $key] = $value; } -if($load_it) -{ - if(SITE_CLOSED && admin()) - $content .= '

    Site is under maintenance (closed mode). Only privileged users can see it.

    '; - - if($config['backward_support']) { - require SYSTEM . 'compat/pages.php'; - require SYSTEM . 'compat/classes.php'; - } - - $ignore = false; - - $logged_access = 1; - if($logged && $account_logged && $account_logged->isLoaded()) { - $logged_access = $account_logged->getAccess(); - } - - $success = false; - $tmp_content = getCustomPage($page, $success); - if($success) { - $content .= $tmp_content; - if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) { - $pageInfo = getCustomPageInfo($page); - $content = $twig->render('admin.pages.links.html.twig', array( - 'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0') - )) . $content; - } - } else { - $file = $template_path . '/pages/' . $page . '.php'; - if(!@file_exists($file)) - { - $file = SYSTEM . 'pages/' . $page . '.php'; - if(!@file_exists($file)) - { - $page = '404'; - $file = SYSTEM . 'pages/404.php'; - } - } - } - - ob_start(); - if($hooks->trigger(HOOK_BEFORE_PAGE)) { - if(!$ignore) - require $file; - } - - if($config['backward_support'] && isset($main_content[0])) - $content .= $main_content; - - $content .= ob_get_contents(); - ob_end_clean(); - $hooks->trigger(HOOK_AFTER_PAGE); -} - -if($config['backward_support']) { - $main_content = $content; - if(!isset($title)) - $title = ucfirst($page); - - $topic = $title; -} - /** * @var OTS_Account $account_logged */ diff --git a/install/index.php b/install/index.php index 1bc0e4ba..4931f8c1 100644 --- a/install/index.php +++ b/install/index.php @@ -70,7 +70,7 @@ if($step == 'database') { $key = str_replace('var_', '', $key); - if(in_array($key, array('account', 'password', 'email', 'player_name'))) { + if(in_array($key, array('account', 'password', 'password_confirm', 'email', 'player_name'))) { continue; } @@ -122,6 +122,7 @@ else if($step == 'admin') { else if($step == 'finish') { $email = $_SESSION['var_email']; $password = $_SESSION['var_password']; + $password_confirm = $_SESSION['var_password_confirm']; $player_name = $_SESSION['var_player_name']; // email check @@ -163,6 +164,9 @@ else if($step == 'finish') { else if(!Validator::password($password)) { $errors[] = $locale['step_admin_password_error_format']; } + else if($password != $password_confirm) { + $errors[] = $locale['step_admin_password_confirm_error_not_same']; + } // player name check if(empty($player_name)) { diff --git a/install/steps/7-finish.php b/install/steps/7-finish.php index f17a7da2..81ace38f 100644 --- a/install/steps/7-finish.php +++ b/install/steps/7-finish.php @@ -15,8 +15,7 @@ else { $password = $_SESSION['var_password']; - $config_salt_enabled = $db->hasColumn('accounts', 'salt'); - if($config_salt_enabled) + if(USE_ACCOUNT_SALT) { $salt = generateRandomString(10, false, true, true); $password = $salt . $password; @@ -75,7 +74,7 @@ else { $account_used = &$new_account; } - if($config_salt_enabled) + if(USE_ACCOUNT_SALT) $account_used->setCustomField('salt', $salt); $account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN); @@ -83,7 +82,7 @@ else { if($db->hasColumn('accounts', 'group_id')) $account_used->setCustomField('group_id', $groups->getHighestId()); if($db->hasColumn('accounts', 'type')) - $account_used->setCustomField('type', 5); + $account_used->setCustomField('type', 6); if(!$player_db->isLoaded()) $player->setAccountId($account_used->getId()); diff --git a/login.php b/login.php index 96acd48d..3ab0b5e9 100644 --- a/login.php +++ b/login.php @@ -127,8 +127,7 @@ switch ($action) { $account->find($inputAccountName); } - $config_salt_enabled = fieldExist('salt', 'accounts'); - $current_password = encrypt(($config_salt_enabled ? $account->getCustomField('salt') : '') . $request->password); + $current_password = encrypt((USE_ACCOUNT_SALT ? $account->getCustomField('salt') : '') . $request->password); if (!$account->isLoaded() || $account->getPassword() != $current_password) { sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.'); diff --git a/plugins/email-confirmed-reward.json b/plugins/email-confirmed-reward.json new file mode 100644 index 00000000..b1ae4cc1 --- /dev/null +++ b/plugins/email-confirmed-reward.json @@ -0,0 +1,17 @@ +{ + "name": "EMail Confirmed Reward", + "description": "Reward users for confirming their E-Mail.", + "version": "1.0", + "author": "MyAAC Authors", + "contact": "www.my-aac.org", + "hooks": { + "mail-confirmed-reward": { + "type": "EMAIL_CONFIRMED", + "file": "plugins/email-confirmed-reward/reward.php" + } + }, + "uninstall": [ + "plugins/email-confirmed-reward.json", + "plugins/email-confirmed-reward" + ] +} diff --git a/plugins/email-confirmed-reward/reward.php b/plugins/email-confirmed-reward/reward.php new file mode 100644 index 00000000..107ab8d7 --- /dev/null +++ b/plugins/email-confirmed-reward/reward.php @@ -0,0 +1,33 @@ +hasColumn('accounts', 'coins'); +if ($reward['coins'] > 0 && $hasCoinsColumn) { + log_append('email_confirm_error.log', 'accounts.coins column does not exist.'); +} + +if (!isset($account) || !$account->isLoaded()) { + log_append('email_confirm_error.log', 'Account not loaded.'); + return; +} + +if ($reward['premium_points'] > 0) { + $account->setCustomField('premium_points', (int)$account->getCustomField('premium_points') + $reward['premium_points']); + + success(sprintf($reward['message'], $reward['premium_points'], 'premium points')); +} + +if ($reward['coins'] > 0 && $hasCoinsColumn) { + $account->setCustomField('coins', (int)$account->getCustomField('coins') + $reward['coins']); + + success(sprintf($reward['message'], $reward['coins'], 'coins')); +} + +if ($reward['premium_days'] > 0) { + $account->setPremDays($account->getPremDays() + $reward['premium_days']); + $account->save(); + + success(sprintf($reward['message'], $reward['premium_days'], 'premium days')); +} diff --git a/plugins/example.json b/plugins/example.json index b3cf2633..6591a333 100644 --- a/plugins/example.json +++ b/plugins/example.json @@ -6,31 +6,38 @@ "author": "nobody", "contact": "nobody@example.org", "require": { - "myaac": "0.4.3", - "myaac_": ">=0.7,<1.0", // support for defining versions like in composer (since 0.8) - "php": "5.2.0", - "php_": ">5.4,<7.0", // support for defining versions like in composer (since 0.8) + "myaac": "0.9.0", + "myaac_": ">=0.9,<1.0", + "php": "7.4", + "php_": ">7.4,<8.0", "database": "21", - "php-ext": "curl", // php extension needs to be installed (since 0.8) - "ext-curl": ">5.0", // php extension with version specifiec (since 0.8) - "table": "accounts", // table need to exist in database (since 0.8) - "column": "players.online" // column need to exist in database (since 0.8) + "php-ext": "curl", + "ext-curl": ">5.0", + "table": "accounts", + "column": "players.online" }, "install": "plugins/example/install.php", "uninstall": [ "plugins/example.json", "plugins/example-directory", "templates/other-directory" - /*** - this is example of multi line comment - 1. list example - 2. something - ****/ ], "hooks": { "Example Hook": { "type": "BEFORE_PAGE", "file": "plugins/example/before.php" } - } + }, + "routes": { + "First Route": { + "pattern": "/YourAwesomePage/{name:string}/{page:int}", + "file": "plugins/your-plugin/your-awesome-page.php", + "method": "GET", + "priority": "130" + }, + "Redirect Example": { + "redirect_from": "/redirectExample", + "redirect_to": "account/manage" + } + } } diff --git a/system/compat/pages.php b/system/compat/pages.php index 1830ecd5..3f5d0a0a 100644 --- a/system/compat/pages.php +++ b/system/compat/pages.php @@ -10,6 +10,18 @@ defined('MYAAC') or die('Direct access not allowed!'); switch($page) { + case 'createaccount': + $page = 'account/create'; + break; + + case 'accountmanagement': + $page = 'account/manage'; + break; + + case 'lostaccount': + $page = 'account/lost'; + break; + case 'whoisonline': $page = 'online'; break; @@ -18,6 +30,10 @@ switch($page) $page = 'news'; break; + case 'newsarchive': + $page = 'news/archive'; + break; + case 'tibiarules': $page = 'rules'; break; @@ -37,4 +53,3 @@ switch($page) default: break; } -?> diff --git a/system/functions.php b/system/functions.php index 669e64c0..db3bfd8f 100644 --- a/system/functions.php +++ b/system/functions.php @@ -62,20 +62,20 @@ function getFullLink($page, $name, $blank = false) { function getLink($page, $action = null) { global $config; - return BASE_URL . ($config['friendly_urls'] ? '' : '?') . $page . ($action ? '/' . $action : ''); + return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . $page . ($action ? '/' . $action : ''); } function internalLayoutLink($page, $action = null) {return getLink($page, $action);} function getForumThreadLink($thread_id, $page = NULL) { global $config; - return BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'forum/thread/' . (int)$thread_id . (isset($page) ? '/' . $page : ''); + return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'forum/thread/' . (int)$thread_id . (isset($page) ? '/' . $page : ''); } function getForumBoardLink($board_id, $page = NULL) { global $config; - return BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'forum/board/' . (int)$board_id . (isset($page) ? '/' . $page : ''); + return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'forum/board/' . (int)$board_id . (isset($page) ? '/' . $page : ''); } function getPlayerLink($name, $generate = true) @@ -90,7 +90,7 @@ function getPlayerLink($name, $generate = true) $name = $player->getName(); } - $url = BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'characters/' . urlencode($name); + $url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'characters/' . urlencode($name); if(!$generate) return $url; return generateLink($url, $name); @@ -100,7 +100,7 @@ function getMonsterLink($name, $generate = true) { global $config; - $url = BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'creatures/' . urlencode($name); + $url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'creatures/' . urlencode($name); if(!$generate) return $url; return generateLink($url, $name); @@ -118,7 +118,7 @@ function getHouseLink($name, $generate = true) $name = $house->fetchColumn(); } - $url = BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'houses/' . urlencode($name); + $url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'houses/' . urlencode($name); if(!$generate) return $url; return generateLink($url, $name); @@ -136,7 +136,7 @@ function getGuildLink($name, $generate = true) $name = $guild->fetchColumn(); } - $url = BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'guilds/' . urlencode($name); + $url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'guilds/' . urlencode($name); if(!$generate) return $url; return generateLink($url, $name); @@ -268,6 +268,13 @@ function getForumBoards() return array(); } +// TODO: +// convert forum threads links from just forum/ID +// INTO: forum/thread-name-id, like in XenForo +//function convertForumThreadTitle($title) { +// return str_replace(' ', '-', strtolower($title)); +//} + /** * Retrieves data from myaac database config. * @@ -1145,6 +1152,12 @@ function clearCache() global $template_name; if ($cache->fetch('template_ini' . $template_name, $tmp)) $cache->delete('template_ini' . $template_name); + + if ($cache->fetch('plugins_hooks', $tmp)) + $cache->delete('plugins_hooks'); + + if ($cache->fetch('plugins_routes', $tmp)) + $cache->delete('plugins_routes'); } deleteDirectory(CACHE . 'signatures', ['index.html'], true); @@ -1152,6 +1165,12 @@ function clearCache() deleteDirectory(CACHE . 'plugins', ['index.html'], true); deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html'], true); + // routes cache + $routeCacheFile = CACHE . 'route.cache'; + if (file_exists($routeCacheFile)) { + unlink($routeCacheFile); + } + return true; } @@ -1510,6 +1529,21 @@ function getAccountLoginByLabel() return $ret; } +function camelCaseToUnderscore($input) +{ + return ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_'); +} + +function removeIfFirstSlash(&$text) { + if(strpos($text, '/') === 0) { + $text = str_replace_first('/', '', $text); + } +}; + +function escapeHtml($html) { + return htmlentities($html, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); +} + // validator functions require_once LIBS . 'validator.php'; require_once SYSTEM . 'compat/base.php'; diff --git a/system/hooks.php b/system/hooks.php index 3e9a738f..3f510d79 100644 --- a/system/hooks.php +++ b/system/hooks.php @@ -50,8 +50,9 @@ define('HOOK_ACCOUNT_CREATE_BEFORE_SUBMIT_BUTTON', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_FORM', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_SUBMIT', ++$i); define('HOOK_ADMIN_MENU', ++$i); +define('HOOK_EMAIL_CONFIRMED', ++$i); define('HOOK_FIRST', HOOK_STARTUP); -define('HOOK_LAST', HOOK_ADMIN_MENU); +define('HOOK_LAST', HOOK_EMAIL_CONFIRMED); require_once LIBS . 'plugins.php'; class Hook @@ -119,5 +120,7 @@ class Hooks foreach(Plugins::getHooks() as $hook) { $this->register($hook['name'], $hook['type'], $hook['file']); } + + Plugins::clearWarnings(); } } diff --git a/system/init.php b/system/init.php index d4c623bf..f2ea9ee2 100644 --- a/system/init.php +++ b/system/init.php @@ -34,6 +34,10 @@ $cache = Cache::getInstance(); // twig require_once SYSTEM . 'twig.php'; +// action, used by many pages +$action = $_REQUEST['action'] ?? ''; +define('ACTION', $action); + // trim values we receive if(isset($_POST)) { @@ -128,6 +132,7 @@ require_once SYSTEM . 'database.php'; define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name')); define('USE_ACCOUNT_NUMBER', $db->hasColumn('accounts', 'number')); +define('USE_ACCOUNT_SALT', $db->hasColumn('accounts', 'salt')); // load vocation names $tmp = ''; diff --git a/system/libs/news.php b/system/libs/news.php index a9131e02..b0f17158 100644 --- a/system/libs/news.php +++ b/system/libs/news.php @@ -8,12 +8,12 @@ class News $errors[] = 'Please fill all inputs.'; return false; } - if(strlen($title) > TITLE_LIMIT) { - $errors[] = 'News title cannot be longer than ' . TITLE_LIMIT . ' characters.'; + if(strlen($title) > NEWS_TITLE_LIMIT) { + $errors[] = 'News title cannot be longer than ' . NEWS_TITLE_LIMIT . ' characters.'; return false; } - if(strlen($body) > BODY_LIMIT) { - $errors[] = 'News content cannot be longer than ' . BODY_LIMIT . ' characters.'; + if(strlen($body) > NEWS_BODY_LIMIT) { + $errors[] = 'News content cannot be longer than ' . NEWS_BODY_LIMIT . ' characters.'; return false; } if(strlen($article_text) > ARTICLE_TEXT_LIMIT) { @@ -138,4 +138,4 @@ class News } } } -} \ No newline at end of file +} diff --git a/system/libs/plugins.php b/system/libs/plugins.php index 57507aae..3d9792b9 100644 --- a/system/libs/plugins.php +++ b/system/libs/plugins.php @@ -45,12 +45,117 @@ class Plugins { private static $error = null; private static $plugin_json = array(); + public static function getRoutes() + { + $cache = Cache::getInstance(); + if ($cache->enabled()) { + $tmp = ''; + if ($cache->fetch('plugins_routes', $tmp)) { + return unserialize($tmp); + } + } + + $routes = []; + foreach(get_plugins() as $filename) { + $string = file_get_contents(PLUGINS . $filename . '.json'); + $string = self::removeComments($string); + $plugin = json_decode($string, true); + self::$plugin_json = $plugin; + if ($plugin == null) { + self::$warnings[] = 'Cannot load ' . $filename . '.json. File might be not a valid json code.'; + continue; + } + + if(isset($plugin['enabled']) && !getBoolean($plugin['enabled'])) { + self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.'; + continue; + } + + $warningPreTitle = 'Plugin: ' . $filename . ' - '; + + if (isset($plugin['routes'])) { + foreach ($plugin['routes'] as $_name => $info) { + // default method: get + $method = $info['method'] ?? ['GET']; + if ($method !== '*') { + $methods = is_string($method) ? explode(',', $info['method']) : $method; + foreach ($methods as $method) { + if (!in_array($method, ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'])) { + self::$warnings[] = $warningPreTitle . 'Not allowed method ' . $method . '... Disabling this route...'; + } + } + } + else { + $methods = '*'; // all available methods + } + + if (!isset($info['priority'])) { + $info['priority'] = 100; // default priority + } + + if (isset($info['redirect_from'])) { + removeIfFirstSlash($info['redirect_from']); + + $info['pattern'] = $info['redirect_from']; + if (!isset($info['redirect_to'])) { + self::$warnings[] = $warningPreTitle . 'redirect set without "redirect_to".'; + } + else { + removeIfFirstSlash($info['redirect_to']); + $info['file'] = '__redirect__/' . $info['redirect_to']; + } + } + + // replace first occurence of / in pattern if found (will be auto-added later) + removeIfFirstSlash($info['pattern']); + + foreach ($routes as $id => &$route) { + if($route[1] == $info['pattern']) { + if($info['priority'] < $route[3]) { + self::$warnings[] = $warningPreTitle . "Duplicated route with lower priority: {$info['pattern']}. Disabling this route..."; + continue 2; + } + else { + self::$warnings[] = $warningPreTitle . "Duplicated route with lower priority: {$route[1]} ({$route[3]}). Disabling this route..."; + unset($routes[$id]); + } + } + } + + $routes[] = [$methods, $info['pattern'], $info['file'], $info['priority']]; + } + } + } +/* + usort($routes, function ($a, $b) + { + // key 3 is priority + if ($a[3] == $b[3]) { + return 0; + } + + return ($a[3] > $b[3]) ? -1 : 1; + }); +*/ + // cleanup before passing back + // priority is not needed anymore + foreach ($routes as &$route) { + unset($route[3]); + } + + if ($cache->enabled()) { + $cache->set('plugins_routes', serialize($routes), 600); + } + + return $routes; + } + public static function getHooks() { $cache = Cache::getInstance(); if ($cache->enabled()) { $tmp = ''; - if ($cache->fetch('hooks', $tmp)) { + if ($cache->fetch('plugins_hooks', $tmp)) { return unserialize($tmp); } } @@ -84,7 +189,7 @@ class Plugins { } if ($cache->enabled()) { - $cache->set('hooks', serialize($hooks), 600); + $cache->set('plugins_hooks', serialize($hooks), 600); } return $hooks; @@ -225,27 +330,59 @@ class Plugins { } if(in_array($req, array('php-ext', 'php-extension'))) { // require php extension - if(!extension_loaded($version)) { - self::$error = "This plugin requires php extension: " . $version . " to be installed."; + $tmpDisplayError = false; + $explode = explode(',', $version); + + foreach ($explode as $item) { + if(!extension_loaded($item)) { + $errors[] = "This plugin requires php extension: " . $item . " to be installed."; + $tmpDisplayError = true; + } + } + + if ($tmpDisplayError) { + self::$error = implode('
    ', $errors); $continue = false; break; } } else if($req == 'table') { - if(!$db->hasTable($version)) { - self::$error = "This plugin requires table: " . $version . " to exist in the database."; + $tmpDisplayError = false; + $explode = explode(',', $version); + foreach ($explode as $item) { + if(!$db->hasTable($item)) { + $errors[] = "This plugin requires table: " . $item . " to exist in the database."; + $tmpDisplayError = true; + } + } + + if ($tmpDisplayError) { + self::$error = implode('
    ', $errors); $continue = false; break; } } else if($req == 'column') { - $tmp = explode('.', $version); - if(count($tmp) == 2) { - if(!$db->hasColumn($tmp[0], $tmp[1])) { - self::$error = "This plugin requires database column: " . $tmp[0] . "." . $tmp[1] . " to exist in database."; - $continue = false; - break; + $tmpDisplayError = false; + $explode = explode(',', $version); + foreach ($explode as $item) { + $tmp = explode('.', $item); + + if(count($tmp) == 2) { + if(!$db->hasColumn($tmp[0], $tmp[1])) { + $errors[] = "This plugin requires database column: " . $tmp[0] . "." . $tmp[1] . " to exist in database."; + $tmpDisplayError = true; + } } + else { + self::$warnings[] = "Invalid plugin require column: " . $item; + } + } + + if ($tmpDisplayError) { + self::$error = implode('
    ', $errors); + $continue = false; + break; } } else if(strpos($req, 'ext-') !== false) { @@ -378,6 +515,10 @@ class Plugins { return self::$warnings; } + public static function clearWarnings() { + self::$warnings = []; + } + public static function getError() { return self::$error; } diff --git a/system/libs/pot/OTS_Base_DB.php b/system/libs/pot/OTS_Base_DB.php index 21902b9c..f97745b4 100644 --- a/system/libs/pot/OTS_Base_DB.php +++ b/system/libs/pot/OTS_Base_DB.php @@ -92,25 +92,38 @@ abstract class OTS_Base_DB extends PDO implements IOTS_DB return $ret; } - public function select($table, $where, $limit = null) + public function select($table, $where = [], $limit = null) { $fields = array_keys($where); $values = array_values($where); - $query = 'SELECT * FROM ' . $this->tableName($table) . ' WHERE ('; + $query = 'SELECT * FROM ' . $this->tableName($table); - $count = count($fields); - for ($i = 0; $i < $count; $i++) - $query.= $this->fieldName($fields[$i]).' = '.$this->quote($values[$i]).' AND '; + if (!empty($where)) { + $query .= ' WHERE ('; + + $count = count($fields); + for ($i = 0; $i < $count; $i++) { + $query .= $this->fieldName($fields[$i]) . ' = ' . $this->quote($values[$i]) . ' AND '; + } + + $query = substr($query, 0, -4); + $query .= ')'; + } - $query = substr($query, 0, -4); if (isset($limit)) - $query .=') LIMIT '.$limit.';'; + $query .=' LIMIT '.$limit.';'; else - $query .=');'; + $query .=';'; $query = $this->query($query); - if($query->rowCount() != 1) return false; - return $query->fetch(); + $rowCount = $query->rowCount(); + if ($rowCount <= 0) return false; + else if ($rowCount == 1) { + return $query->fetch(); + } + + return $query->fetchAll(); + } public function insert($table, $data) diff --git a/system/locale/de/install.php b/system/locale/de/install.php index 0ed461f6..5cb7342e 100644 --- a/system/locale/de/install.php +++ b/system/locale/de/install.php @@ -99,7 +99,10 @@ $locale['step_admin_account_id_error_same'] = 'Das Passwort darf nicht mit der K $locale['step_admin_password'] = 'Administrator Konto Passwort'; $locale['step_admin_password_desc'] = 'Passwort für Ihr Administratorkonto.'; $locale['step_admin_password_error_empty'] = 'Bitte geben Sie das Passwort für Ihr neues Konto ein.'; -$locale['step_admin_password_error_format'] = 'Ungültiges Passwortformat. Verwenden Sie nur a-Z und Ziffern 0-9. Mindestens 8, maximal 30 Zeichen.'; +$locale['step_admin_password_error_format'] = 'Ungültiges Passwortformat. Mindestens eine Buchstabe und eine Ziffer. Mindestens 8, maximal 30 Zeichen.'; +$locale['step_admin_password_confirm'] = 'Password wiederholen'; +$locale['step_admin_password_confirm_desc'] = 'Passwort für dein Konto wiederholen.'; +$locale['step_admin_password_confirm_error_not_same'] = 'Passwörter sind nicht gleich.'; // finish $locale['step_finish_admin_panel'] = 'Admin Bereich'; diff --git a/system/locale/en/install.php b/system/locale/en/install.php index e0cbfbff..f856dcbf 100644 --- a/system/locale/en/install.php +++ b/system/locale/en/install.php @@ -114,7 +114,10 @@ $locale['step_admin_account_id_error_same'] = 'Password may not be the same as a $locale['step_admin_password'] = 'Admin account password'; $locale['step_admin_password_desc'] = 'Password to your admin account.'; $locale['step_admin_password_error_empty'] = 'Please enter the password for your new account.'; -$locale['step_admin_password_error_format'] = 'Invalid password format. Use only a-Z and numbers 0-9. Minimum 8, maximum 30 characters.'; +$locale['step_admin_password_error_format'] = 'Invalid password format. Minimum one letter and one number. Minimum 8, maximum 30 characters.'; +$locale['step_admin_password_confirm'] = 'Password confirm'; +$locale['step_admin_password_confirm_desc'] = 'Repeat password to your account.'; +$locale['step_admin_password_confirm_error_not_same'] = 'Passwords are not same.'; $locale['step_admin_player_name'] = 'Admin player name'; $locale['step_admin_player_name_desc'] = 'Name of your admin character.'; $locale['step_admin_player_name_error_empty'] = 'Please enter the name of your character.'; diff --git a/system/locale/pl/install.php b/system/locale/pl/install.php index 5822a4d2..1afb2ddd 100644 --- a/system/locale/pl/install.php +++ b/system/locale/pl/install.php @@ -113,7 +113,10 @@ $locale['step_admin_account_id_error_same'] = 'Hasło nie może być takie same $locale['step_admin_password'] = 'Hasło Konta Admina'; $locale['step_admin_password_desc'] = 'Hasło do Twojego Konta Admina.'; $locale['step_admin_password_error_empty'] = 'Proszę podać hasło do Twojego nowego konta.'; -$locale['step_admin_password_error_format'] = 'Nieprawidłowy format hasła. Używaj tylko znaków a-Z oraz liczb 0-9. Minimum 8, maksimum 30 znaków.'; +$locale['step_admin_password_error_format'] = 'Nieprawidłowy format hasła. Minimum jeden znak i jedna liczba. Minimum 8, maksimum 30 znaków.'; +$locale['step_admin_password_confirm'] = 'Potwierdź Hasło'; +$locale['step_admin_password_confirm_desc'] = 'Potwierdzenie hasła do Twojego Konta Admina.'; +$locale['step_admin_password_confirm_error_not_same'] = 'Hasła nie są takie same.'; $locale['step_admin_player_name'] = 'Nazwa postaci'; $locale['step_admin_player_name_desc'] = 'Nazwa postaci Konta Admina.'; $locale['step_admin_player_name_error_empty'] = 'Proszę podać nazwę postaci.'; diff --git a/system/login.php b/system/login.php index 87261369..4e372b75 100644 --- a/system/login.php +++ b/system/login.php @@ -11,11 +11,6 @@ defined('MYAAC') or die('Direct access not allowed!'); $logged = false; $logged_flags = 0; -$action = isset($_REQUEST['action']) ? strtolower($_REQUEST['action']) : ''; -if(!defined('ACTION')) { - define('ACTION', $action); -} - // stay-logged with sessions $current_session = getSession('account'); if($current_session !== false) @@ -33,152 +28,130 @@ if($current_session !== false) } } -if(ACTION === 'logout' && !isset($_REQUEST['account_login'])) { - if(isset($account_logged) && $account_logged->isLoaded()) { - if($hooks->trigger(HOOK_LOGOUT,['account_id' => $account_logged->getId()])) { - unsetSession('account'); - unsetSession('password'); - unsetSession('remember_me'); - - $logged = false; - unset($account_logged); - - if(isset($_REQUEST['redirect'])) - { - header('Location: ' . urldecode($_REQUEST['redirect'])); - exit; - } - } - } -} -else +// new login with data from form +if(!$logged && isset($_POST['account_login'], $_POST['password_login'])) { - // new login with data from form - if(!$logged && isset($_POST['account_login'], $_POST['password_login'])) + $login_account = $_POST['account_login']; + $login_password = $_POST['password_login']; + $remember_me = isset($_POST['remember_me']); + if(!empty($login_account) && !empty($login_password)) { - $login_account = $_POST['account_login']; - $login_password = $_POST['password_login']; - $remember_me = isset($_POST['remember_me']); - if(!empty($login_account) && !empty($login_password)) + if($cache->enabled()) { - if($cache->enabled()) + $tmp = ''; + if($cache->fetch('failed_logins', $tmp)) { - $tmp = ''; - if($cache->fetch('failed_logins', $tmp)) + $tmp = unserialize($tmp); + $to_remove = array(); + foreach($tmp as $ip => $t) { - $tmp = unserialize($tmp); - $to_remove = array(); - foreach($tmp as $ip => $t) - { - if(time() - $t['last'] >= 5 * 60) - $to_remove[] = $ip; - } - - foreach($to_remove as $ip) - unset($tmp[$ip]); - } - else - $tmp = array(); - - $ip = $_SERVER['REMOTE_ADDR']; - $t = isset($tmp[$ip]) ? $tmp[$ip] : NULL; - } - - if(config('recaptcha_enabled') && !config('account_create_auto_login')) - { - require_once LIBS . 'GoogleReCAPTCHA.php'; - if (!GoogleReCAPTCHA::verify('login')) { - $errors[] = GoogleReCAPTCHA::getErrorMessage(); - } - } - - $account_logged = new OTS_Account(); - if (config('account_login_by_email')) { - $account_logged->findByEMail($login_account); - } - - if (!config('account_login_by_email') || config('account_login_by_email_fallback')) { - if(USE_ACCOUNT_NAME) { - $account_logged->find($login_account); - } else { - $account_logged->load($login_account, true); - } - } - - $config_salt_enabled = $db->hasColumn('accounts', 'salt'); - if($account_logged->isLoaded() && encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword() - && (!isset($t) || $t['attempts'] < 5) - ) - { - setSession('account', $account_logged->getNumber()); - setSession('password', encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password)); - if($remember_me) { - setSession('remember_me', true); + if(time() - $t['last'] >= 5 * 60) + $to_remove[] = $ip; } - $logged = true; - $logged_flags = $account_logged->getWebFlags(); - - if(isset($_POST['admin']) && !admin()) { - $errors[] = 'This account has no admin privileges.'; - unsetSession('account'); - unsetSession('password'); - unsetSession('remember_me'); - $logged = false; - } - else { - $account_logged->setCustomField('web_lastlogin', time()); - } - - $hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me)); + foreach($to_remove as $ip) + unset($tmp[$ip]); } else - { - $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); + $tmp = array(); - $errorMessage = getAccountLoginByLabel() . ' or password is not correct.'; + $ip = $_SERVER['REMOTE_ADDR']; + $t = $tmp[$ip] ?? null; + } - // temporary solution for blocking failed login attempts - if($cache->enabled()) - { - if(isset($t)) - { - $t['attempts']++; - $t['last'] = time(); - - if($t['attempts'] >= 5) - $errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.'; - else - $errors[] = $errorMessage; - } - else - { - $t = array('attempts' => 1, 'last' => time()); - $errors[] = $errorMessage; - } - - $tmp[$ip] = $t; - $cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour - } - else { - $errors[] = $errorMessage; - } + if(config('recaptcha_enabled') && !config('account_create_auto_login')) + { + require_once LIBS . 'GoogleReCAPTCHA.php'; + if (!GoogleReCAPTCHA::verify('login')) { + $errors[] = GoogleReCAPTCHA::getErrorMessage(); } } - else { - $errors[] = 'Please enter your ' . getAccountLoginByLabel() . ' and password.'; + $account_logged = new OTS_Account(); + if (config('account_login_by_email')) { + $account_logged->findByEMail($login_account); + } + + if (!config('account_login_by_email') || config('account_login_by_email_fallback')) { + if(USE_ACCOUNT_NAME) { + $account_logged->find($login_account); + } else { + $account_logged->load($login_account, true); + } + } + + if($account_logged->isLoaded() && encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword() + && (!isset($t) || $t['attempts'] < 5) + ) + { + setSession('account', $account_logged->getNumber()); + setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password)); + if($remember_me) { + setSession('remember_me', true); + } + + $logged = true; + $logged_flags = $account_logged->getWebFlags(); + + if(isset($_POST['admin']) && !admin()) { + $errors[] = 'This account has no admin privileges.'; + unsetSession('account'); + unsetSession('password'); + unsetSession('remember_me'); + $logged = false; + } + else { + $account_logged->setCustomField('web_lastlogin', time()); + } + + $hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me)); + } + else + { $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); + + $errorMessage = getAccountLoginByLabel() . ' or password is not correct.'; + + // temporary solution for blocking failed login attempts + if($cache->enabled()) + { + if(isset($t)) + { + $t['attempts']++; + $t['last'] = time(); + + if($t['attempts'] >= 5) + $errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.'; + else + $errors[] = $errorMessage; + } + else + { + $t = array('attempts' => 1, 'last' => time()); + $errors[] = $errorMessage; + } + + $tmp[$ip] = $t; + $cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour + } + else { + $errors[] = $errorMessage; + } } } + else { + $errors[] = 'Please enter your ' . getAccountLoginByLabel() . ' and password.'; - if($logged) { - $logged_flags = $account_logged->getWebFlags(); - $twig->addGlobal('logged', true); - $twig->addGlobal('account_logged', $account_logged); + $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); } } +if($logged) { + $logged_flags = $account_logged->getWebFlags(); + $twig->addGlobal('logged', true); + $twig->addGlobal('account_logged', $account_logged); +} + setSession('last_visit', time()); if(defined('PAGE')) { setSession('last_page', PAGE); diff --git a/system/logout.php b/system/logout.php new file mode 100644 index 00000000..a7f5d8fd --- /dev/null +++ b/system/logout.php @@ -0,0 +1,18 @@ +isLoaded()) { + if($hooks->trigger(HOOK_LOGOUT, ['account_id' => $account_logged->getId()])) { + unsetSession('account'); + unsetSession('password'); + unsetSession('remember_me'); + + $logged = false; + unset($account_logged); + + if(isset($_REQUEST['redirect'])) + { + header('Location: ' . urldecode($_REQUEST['redirect'])); + exit; + } + } +} diff --git a/system/pages/405.php b/system/pages/405.php new file mode 100644 index 00000000..3d585f59 --- /dev/null +++ b/system/pages/405.php @@ -0,0 +1,16 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); +$title = '405 Method Not Allowed'; + +header('HTTP/1.0 405 Method Not Allowed'); +?> +

    Method not allowed

    +

    The requested method: for URL was not found on this server.

    diff --git a/system/pages/account/base.php b/system/pages/account/base.php new file mode 100644 index 00000000..75b1cc77 --- /dev/null +++ b/system/pages/account/base.php @@ -0,0 +1,29 @@ + + * @copyright 2019 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +if(!$logged) +{ + if(!empty($errors)) + $twig->display('error_box.html.twig', array('errors' => $errors)); + + $twig->display('account.login.html.twig', array( + 'redirect' => $_REQUEST['redirect'] ?? null, + 'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', + 'account_login_by' => getAccountLoginByLabel(), + 'error' => $errors[0] ?? null + )); + + return; +} +else { + $show_form = true; +} diff --git a/system/pages/account/change_comment.php b/system/pages/account/change_comment.php index 43cfd0ca..0f0bc2f1 100644 --- a/system/pages/account/change_comment.php +++ b/system/pages/account/change_comment.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Comment'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $player_name = isset($_REQUEST['name']) ? stripslashes(urldecode($_REQUEST['name'])) : null; $new_comment = isset($_POST['comment']) ? htmlspecialchars(stripslashes(substr($_POST['comment'],0,2000))) : NULL; $new_hideacc = isset($_POST['accountvisible']) ? (int)$_POST['accountvisible'] : NULL; @@ -56,4 +63,4 @@ if($show_form) { )); } } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_email.php b/system/pages/account/change_email.php index 0bd668a5..2368a284 100644 --- a/system/pages/account/change_email.php +++ b/system/pages/account/change_email.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change E-Mail'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $email_new_time = $account_logged->getCustomField("email_new_time"); if($email_new_time > 10) { @@ -29,7 +36,7 @@ if($email_new_time < 10) { $errors[] = 'Please enter password to your account.'; } else { - $post_password = encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $post_password); + $post_password = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $post_password); if($post_password != $account_logged->getPassword()) { $errors[] = 'Wrong password to account.'; } @@ -159,4 +166,4 @@ if(isset($_POST['emailchangecancel']) && $_POST['emailchangecancel'] == 1) { 'custom_buttons' => $custom_buttons )); } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_info.php b/system/pages/account/change_info.php index df2a52f6..753f4ce5 100644 --- a/system/pages/account/change_info.php +++ b/system/pages/account/change_info.php @@ -10,6 +10,16 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Info'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + +if($config['account_country']) + require SYSTEM . 'countries.conf.php'; + $show_form = true; $new_rlname = isset($_POST['info_rlname']) ? htmlspecialchars(stripslashes($_POST['info_rlname'])) : NULL; $new_location = isset($_POST['info_location']) ? htmlspecialchars(stripslashes($_POST['info_location'])) : NULL; @@ -53,10 +63,10 @@ if($show_form) { } $twig->display('account.change_info.html.twig', array( - 'countries' => isset($countries) ? $countries : [], + 'countries' => $countries ?? [], 'account_rlname' => $account_rlname, 'account_location' => $account_location, - 'account_country' => isset($account_country) ? $account_country : '' + 'account_country' => $account_country ?? '' )); } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_name.php b/system/pages/account/change_name.php index 077b2060..ab7bd326 100644 --- a/system/pages/account/change_name.php +++ b/system/pages/account/change_name.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Name'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : NULL; $name = isset($_POST['name']) ? stripslashes(ucwords(strtolower($_POST['name']))) : NULL; if((!$config['account_change_character_name'])) diff --git a/system/pages/account/change_password.php b/system/pages/account/change_password.php index bd63c46d..9b8c3e8a 100644 --- a/system/pages/account/change_password.php +++ b/system/pages/account/change_password.php @@ -10,9 +10,16 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -$new_password = isset($_POST['newpassword']) ? $_POST['newpassword'] : NULL; -$new_password2 = isset($_POST['newpassword2']) ? $_POST['newpassword2'] : NULL; -$old_password = isset($_POST['oldpassword']) ? $_POST['oldpassword'] : NULL; +$title = 'Change Password'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + +$new_password = $_POST['newpassword'] ?? NULL; +$new_password2 = $_POST['newpassword2'] ?? NULL; +$old_password = $_POST['oldpassword'] ?? NULL; if(empty($new_password) && empty($new_password2) && empty($old_password)) { $twig->display('account.change_password.html.twig'); } @@ -32,7 +39,7 @@ else } /** @var OTS_Account $account_logged */ - $old_password = encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $old_password); + $old_password = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $old_password); if($old_password != $account_logged->getPassword()) { $errors[] = "Current password is incorrect!"; } @@ -48,7 +55,7 @@ else { $org_pass = $new_password; - if($config_salt_enabled) + if(USE_ACCOUNT_SALT) { $salt = generateRandomString(10, false, true, true); $new_password = $salt . $new_password; @@ -82,4 +89,4 @@ else } } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_sex.php b/system/pages/account/change_sex.php index f3eb8299..c67ac608 100644 --- a/system/pages/account/change_sex.php +++ b/system/pages/account/change_sex.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Sex'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $sex_changed = false; $player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : NULL; $new_sex = isset($_POST['new_sex']) ? (int)$_POST['new_sex'] : NULL; @@ -85,4 +92,4 @@ else } } -?> \ No newline at end of file +?> diff --git a/system/pages/account/confirm_email.php b/system/pages/account/confirm_email.php index 078ba324..233c5533 100644 --- a/system/pages/account/confirm_email.php +++ b/system/pages/account/confirm_email.php @@ -11,7 +11,7 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Confirm Email'; -$hash = isset($_GET['v']) ? $_GET['v'] : ''; +$hash = $_GET['hash'] ?? ''; if(empty($hash)) { warning('Please enter email hash code.
    If you copied the link, please try again with full link.'); return; @@ -23,6 +23,16 @@ if(!$res->rowCount()) { } else { + $query = $db->query('SELECT id FROM accounts WHERE email_hash = ' . $db->quote($hash) . ' AND email_verified = 0'); + if ($query->rowCount() == 1) { + $query = $query->fetch(PDO::FETCH_ASSOC); + $account = new OTS_Account(); + $account->load($query['id']); + if ($account->isLoaded()) { + $hooks->trigger(HOOK_EMAIL_CONFIRMED, ['account' => $account]); + } + } + $db->update('accounts', array('email_verified' => '1'), array('email_hash' => $hash)); success('You have now verified your e-mail, this will increase the security of your account. Thank you for doing this.'); } diff --git a/system/pages/createaccount.php b/system/pages/account/create.php similarity index 96% rename from system/pages/createaccount.php rename to system/pages/account/create.php index a118972f..4b927eb6 100644 --- a/system/pages/createaccount.php +++ b/system/pages/account/create.php @@ -173,8 +173,7 @@ if($save) $new_account->create(NULL, $account_id); } - $config_salt_enabled = $db->hasColumn('accounts', 'salt'); - if($config_salt_enabled) + if(USE_ACCOUNT_SALT) { $salt = generateRandomString(10, false, true, true); $password = $salt . $password; @@ -185,7 +184,7 @@ if($save) $new_account->unblock(); $new_account->save(); - if($config_salt_enabled) + if(USE_ACCOUNT_SALT) $new_account->setCustomField('salt', $salt); $new_account->setCustomField('created', time()); @@ -200,8 +199,13 @@ if($save) $new_account->setCustomField('premend', time() + $config['account_premium_days'] * 86400); } else { // rest - $new_account->setCustomField('premdays', $config['account_premium_days']); - $new_account->setCustomField('lastday', time()); + if ($db->hasColumn('accounts', 'premium_ends_at')) { // TFS 1.4+ + $new_account->setCustomField('premium_ends_at', time() + $config['account_premium_days'] * (60 * 60 * 24)); + } + else { + $new_account->setCustomField('premdays', $config['account_premium_days']); + $new_account->setCustomField('lastday', time()); + } } } diff --git a/system/pages/account/create_character.php b/system/pages/account/create_character.php index 7c148966..3216a71a 100644 --- a/system/pages/account/create_character.php +++ b/system/pages/account/create_character.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Create Character'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $character_name = isset($_POST['name']) ? stripslashes($_POST['name']) : null; $character_sex = isset($_POST['sex']) ? (int)$_POST['sex'] : null; $character_vocation = isset($_POST['vocation']) ? (int)$_POST['vocation'] : null; diff --git a/system/pages/account/delete_character.php b/system/pages/account/delete_character.php index 2c2bb341..f5894c77 100644 --- a/system/pages/account/delete_character.php +++ b/system/pages/account/delete_character.php @@ -10,9 +10,16 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Delete Character'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $player_name = isset($_POST['delete_name']) ? stripslashes($_POST['delete_name']) : null; $password_verify = isset($_POST['delete_password']) ? $_POST['delete_password'] : null; -$password_verify = encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $password_verify); +$password_verify = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $password_verify); if(isset($_POST['deletecharactersave']) && $_POST['deletecharactersave'] == 1) { if(empty($player_name) || empty($password_verify)) { $errors[] = 'Character name or/and password is empty. Please fill in form.'; diff --git a/system/pages/account/logout.php b/system/pages/account/logout.php new file mode 100644 index 00000000..55e15585 --- /dev/null +++ b/system/pages/account/logout.php @@ -0,0 +1,22 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +$title = 'Logout'; + +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + +require SYSTEM . 'logout.php'; + +$twig->display('account.logout.html.twig'); diff --git a/system/pages/lostaccount.php b/system/pages/account/lost.php similarity index 99% rename from system/pages/lostaccount.php rename to system/pages/account/lost.php index e27b7b5d..f09aa0fa 100644 --- a/system/pages/lostaccount.php +++ b/system/pages/account/lost.php @@ -17,7 +17,6 @@ if(!$config['mail_enabled']) return; } -$config_salt_enabled = $db->hasColumn('accounts', 'salt'); $action_type = isset($_REQUEST['action_type']) ? $_REQUEST['action_type'] : ''; if($action == '') { @@ -292,7 +291,7 @@ elseif($action == 'step3') $account->setEMail($new_email); $tmp_new_pass = $new_pass; - if($config_salt_enabled) + if(USE_ACCOUNT_SALT) { $salt = generateRandomString(10, false, true, true); $tmp_new_pass = $salt . $new_pass; @@ -301,7 +300,7 @@ elseif($action == 'step3') $account->setPassword(encrypt($tmp_new_pass)); $account->save(); - if($config_salt_enabled) + if(USE_ACCOUNT_SALT) $account->setCustomField('salt', $salt); echo 'Your account name, new password and new e-mail.
    @@ -481,7 +480,7 @@ elseif($action == 'setnewpassword') if(Validator::password($newpassword)) { $tmp_new_pass = $newpassword; - if($config_salt_enabled) + if(USE_ACCOUNT_SALT) { $salt = generateRandomString(10, false, true, true); $tmp_new_pass = $salt . $newpassword; diff --git a/system/pages/account/manage.php b/system/pages/account/manage.php new file mode 100644 index 00000000..10aea0ce --- /dev/null +++ b/system/pages/account/manage.php @@ -0,0 +1,97 @@ + + * @author Slawkens + * @copyright 2019 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +$title = 'Account Management'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + +$groups = new OTS_Groups_List(); + +$freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS; +$dayOrDays = $account_logged->getPremDays() == 1 ? 'day' : 'days'; +/** + * @var OTS_Account $account_logged + */ +if(!$account_logged->isPremium()) + $account_status = 'Free Account'; +else + $account_status = '' . ($freePremium ? 'Gratis Premium Account' : 'Premium Account, ' . $account_logged->getPremDays() . ' '.$dayOrDays.' left') . ''; + +$recovery_key = $account_logged->getCustomField('key'); +if(empty($recovery_key)) + $account_registered = 'No'; +else +{ + if($config['generate_new_reckey'] && $config['mail_enabled']) + $account_registered = 'Yes ( Buy new Recovery Key )'; + else + $account_registered = 'Yes'; +} + +$account_created = $account_logged->getCreated(); +$account_email = $account_logged->getEMail(); +$email_new_time = $account_logged->getCustomField("email_new_time"); +if($email_new_time > 1) + $email_new = $account_logged->getCustomField("email_new"); +$account_rlname = $account_logged->getRLName(); +$account_location = $account_logged->getLocation(); +if($account_logged->isBanned()) + if($account_logged->getBanTime() > 0) + $welcome_message = 'Your account is banished until '.date("j F Y, G:i:s", $account_logged->getBanTime()).'!'; + else + $welcome_message = 'Your account is banished FOREVER!'; +else + $welcome_message = 'Welcome to your account!'; + +$email_change = ''; +$email_request = false; +if($email_new_time > 1) +{ + if($email_new_time < time()) + $email_change = '
    (You can accept '.$email_new.' as a new email.)'; + else + { + $email_change = '
    You can accept new e-mail after '.date("j F Y", $email_new_time)."."; + $email_request = true; + } +} + +$actions = array(); +foreach($account_logged->getActionsLog(0, 1000) as $action) { + $actions[] = array('action' => $action['action'], 'date' => $action['date'], 'ip' => $action['ip'] != 0 ? long2ip($action['ip']) : inet_ntop($action['ipv6'])); +} + +$players = array(); +/** @var OTS_Players_List $account_players */ +$account_players = $account_logged->getPlayersList(); +$account_players->orderBy('id'); + +$twig->display('account.management.html.twig', array( + 'welcome_message' => $welcome_message, + 'recovery_key' => $recovery_key, + 'email_change' => $email_change, + 'email_request' => $email_request, + 'email_new_time' => $email_new_time, + 'email_new' => isset($email_new) ? $email_new : '', + 'account' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId(), + 'account_email' => $account_email, + 'account_created' => $account_created, + 'account_status' => $account_status, + 'account_registered' => $account_registered, + 'account_rlname' => $account_rlname, + 'account_location' => $account_location, + 'actions' => $actions, + 'players' => $account_players +)); diff --git a/system/pages/account/redirect.php b/system/pages/account/redirect.php new file mode 100644 index 00000000..8abff630 --- /dev/null +++ b/system/pages/account/redirect.php @@ -0,0 +1,17 @@ + + * @author Slawkens + * @copyright 2019 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +$redirect = urldecode($_REQUEST['redirect']); + +$twig->display('account.redirect.html.twig', array( + 'redirect' => $redirect +)); diff --git a/system/pages/account/register.php b/system/pages/account/register.php index a10eb76f..1d16d905 100644 --- a/system/pages/account/register.php +++ b/system/pages/account/register.php @@ -10,8 +10,15 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -$_POST['reg_password'] = isset($_POST['reg_password']) ? $_POST['reg_password'] : ''; -$reg_password = encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $_POST['reg_password']); +$title = 'Register Account'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + +$_POST['reg_password'] = $_POST['reg_password'] ?? ''; +$reg_password = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $_POST['reg_password']); $old_key = $account_logged->getCustomField("key"); if(isset($_POST['registeraccountsave']) && $_POST['registeraccountsave'] == "1") { diff --git a/system/pages/account/register_new.php b/system/pages/account/register_new.php index 93a14745..fb2e8ea3 100644 --- a/system/pages/account/register_new.php +++ b/system/pages/account/register_new.php @@ -10,12 +10,21 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Register Account'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + if(isset($_POST['reg_password'])) - $reg_password = encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $_POST['reg_password']); + $reg_password = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $_POST['reg_password']); $reckey = $account_logged->getCustomField('key'); -if((!$config['generate_new_reckey'] || !$config['mail_enabled']) || empty($reckey)) - echo 'You cant get new rec key'; +if((!$config['generate_new_reckey'] || !$config['mail_enabled']) || empty($reckey)) { + $errors[] = 'You cant get new recovery key.'; + $twig->display('error_box.html.twig', array('errors' => $errors)); +} else { $points = $account_logged->getCustomField('premium_points'); @@ -67,5 +76,3 @@ else )); } } - -?> \ No newline at end of file diff --git a/system/pages/accountmanagement.php b/system/pages/accountmanagement.php deleted file mode 100644 index 6364d1ff..00000000 --- a/system/pages/accountmanagement.php +++ /dev/null @@ -1,150 +0,0 @@ - - * @author Slawkens - * @copyright 2019 MyAAC - * @link https://my-aac.org - */ -defined('MYAAC') or die('Direct access not allowed!'); -$title = 'Account Management'; - -if($config['account_country']) - require SYSTEM . 'countries.conf.php'; - -$groups = new OTS_Groups_List(); - -$show_form = true; -$config_salt_enabled = $db->hasColumn('accounts', 'salt'); - -if(ACTION == "logout" && !isset($_REQUEST['account_login'])) { - if(!defined('HOOK_LOGOUT_DISPLAY') || HOOK_LOGOUT_DISPLAY) { // plugin will take care of this message - $twig->display('account.logout.html.twig'); - } - - return; -} - -if(!$logged) -{ - if(ACTION == 'confirm_email') { - require PAGES . 'account/' . ACTION . '.php'; - return; - } - - if(!empty($errors)) - $twig->display('error_box.html.twig', array('errors' => $errors)); - - $twig->display('account.login.html.twig', array( - 'redirect' => isset($_REQUEST['redirect']) ? $_REQUEST['redirect'] : null, - 'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', - 'account_login_by' => getAccountLoginByLabel(), - 'error' => isset($errors[0]) ? $errors[0] : null - )); - - return; -} - -$errors = array(); - - if(isset($_REQUEST['redirect'])) - { - $redirect = urldecode($_REQUEST['redirect']); - - $twig->display('account.redirect.html.twig', array( - 'redirect' => $redirect - )); - return; - } - - if($action == '') { - $freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS; - $dayOrDays = $account_logged->getPremDays() == 1 ? 'day' : 'days'; - /** - * @var OTS_Account $account_logged - */ - if(!$account_logged->isPremium()) - $account_status = 'Free Account'; - else - $account_status = '' . ($freePremium ? 'Gratis Premium Account' : 'Premium Account, ' . $account_logged->getPremDays() . ' '.$dayOrDays.' left') . ''; - - $recovery_key = $account_logged->getCustomField('key'); - if(empty($recovery_key)) { - $account_registered = 'No'; - } else { - if($config['generate_new_reckey'] && $config['mail_enabled']) - $account_registered = 'Yes ( Buy new Recovery Key )'; - else - $account_registered = 'Yes'; - } - - $account_created = $account_logged->getCreated(); - $account_email = $account_logged->getEMail(); - $email_new_time = $account_logged->getCustomField("email_new_time"); - if($email_new_time > 1) - $email_new = $account_logged->getCustomField("email_new"); - $account_rlname = $account_logged->getRLName(); - $account_location = $account_logged->getLocation(); - if($account_logged->isBanned()) - if($account_logged->getBanTime() > 0) - $welcome_message = 'Your account is banished until '.date("j F Y, G:i:s", $account_logged->getBanTime()).'!'; - else - $welcome_message = 'Your account is banished FOREVER!'; - else - $welcome_message = 'Welcome to your account!'; - - $email_change = ''; - $email_request = false; - if($email_new_time > 1) - { - if($email_new_time < time()) - $email_change = '
    (You can accept '.$email_new.' as a new email.)'; - else - { - $email_change = '
    You can accept new e-mail after '.date("j F Y", $email_new_time)."."; - $email_request = true; - } - } - - $actions = array(); - foreach($account_logged->getActionsLog(0, 1000) as $action) { - $actions[] = array('action' => $action['action'], 'date' => $action['date'], 'ip' => $action['ip'] != 0 ? long2ip($action['ip']) : inet_ntop($action['ipv6'])); - } - - $players = array(); - /** @var OTS_Players_List $account_players */ - $account_players = $account_logged->getPlayersList(); - $account_players->orderBy('id'); - - $twig->display('account.management.html.twig', array( - 'welcome_message' => $welcome_message, - 'recovery_key' => $recovery_key, - 'email_change' => $email_change, - 'email_request' => $email_request, - 'email_new_time' => $email_new_time, - 'email_new' => isset($email_new) ? $email_new : '', - 'account' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getNumber(), - 'account_email' => $account_email, - 'account_created' => $account_created, - 'account_status' => $account_status, - 'account_registered' => $account_registered, - 'account_rlname' => $account_rlname, - 'account_location' => $account_location, - 'actions' => $actions, - 'players' => $account_players - )); - } - else { - if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { - error('Error: Action contains illegal characters.'); - } - else if(file_exists(PAGES . 'account/' . $action . '.php')) { - require PAGES . 'account/' . $action . '.php'; - } - else { - error('This page does not exists.'); - } - } -?> diff --git a/system/pages/admin/tools/teleport.php b/system/pages/admin/tools/teleport.php deleted file mode 100644 index 842d4abe..00000000 --- a/system/pages/admin/tools/teleport.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @author Lee - * @copyright 2020 MyAAC - * @link https://my-aac.org - */ -defined('MYAAC') or die('Direct access not allowed!'); - -$title = 'Mass Teleport Actions'; - -function admin_teleport_position($x, $y, $z) { - global $db; - $statement = $db->prepare('UPDATE `players` SET `posx` = :x, `posy` = :y, `posz` = :z'); - if (!$statement) { - error('Failed to prepare query statement.'); - return; - } - - if (!$statement->execute([ - 'x' => $x, 'y' => $y, 'z' => $z - ])) { - error('Failed to execute query.'); - return; - } - - success('Player\'s position updated.'); -} - -function admin_teleport_town($town_id) { - global $db; - $statement = $db->prepare('UPDATE `players` SET `town_id` = :town_id'); - if (!$statement) { - error('Failed to prepare query statement.'); - return; - } - - if (!$statement->execute([ - 'town_id' => $town_id - ])) { - error('Failed to execute query.'); - return; - } - - success('Player\'s town updated.'); -} - -if (isset($_POST['action']) && $_POST['action']) { - - $action = $_POST['action']; - - if (preg_match("/[^A-z0-9_\-]/", $action)) { - error('Invalid action.'); - } else { - - $playersOnline = 0; - if($db->hasTable('players_online')) {// tfs 1.0 - $playersOnline = $db->query('SELECT count(*) FROM `players_online`'); - } else { - $playersOnline = $db->query('SELECT count(*) FROM `players` WHERE `players`.`online` > 0'); - } - - if ($playersOnline > 0) { - error('Please, close the server before execute this action otherwise players will not be affected.'); - return; - } - - $town_id = isset($_POST['town_id']) ? intval($_POST['town_id']) : 0; - $posx = isset($_POST['posx']) ? intval($_POST['posx']) : 0; - $posy = isset($_POST['posy']) ? intval($_POST['posy']) : 0; - $posz = isset($_POST['posz']) ? intval($_POST['posz']) : 0; - - switch ($action) { - case 'set-town': - if (!isset($config['towns'][$town_id])) { - error('Please fill all inputs'); - return; - } - - admin_teleport_town($value); - break; - case 'set-position': - if (!$posx || !$posy || !$posz) { - error('Please fill all inputs'); - return; - } - - admin_teleport_position($posx, $posy, $posz); - break; - default: - error('Action ' . $action . 'not found.'); - } - } - -} - -$twig->display('admin.tools.teleport.html.twig', array()); diff --git a/system/pages/changelog.php b/system/pages/changelog.php index 541f9088..2e44c24b 100644 --- a/system/pages/changelog.php +++ b/system/pages/changelog.php @@ -10,8 +10,7 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Changelog'; -$_page = isset($_GET['page']) ? $_GET['page'] : 0; -$id = isset($_GET['id']) ? $_GET['id'] : 0; +$_page = (int)$_GET['page'] ?? 0; $limit = 30; $offset = $_page * $limit; $next_page = false; @@ -43,4 +42,3 @@ $twig->display('changelog.html.twig', array( 'next_page' => $next_page, 'canEdit' => $canEdit, )); -?> diff --git a/system/pages/characters.php b/system/pages/characters.php index 84c5fd63..678e1875 100644 --- a/system/pages/characters.php +++ b/system/pages/characters.php @@ -342,7 +342,7 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil // signature if($config['signature_enabled']) { - $signature_url = BASE_URL . ($config['friendly_urls'] ? '' : '?') . urlencode($player->getName()) . '.png'; + $signature_url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . urlencode($player->getName()) . '.png'; } $hidden = $player->isHidden(); diff --git a/system/pages/creatures.php b/system/pages/creatures.php index c019fbe2..f87b6f28 100644 --- a/system/pages/creatures.php +++ b/system/pages/creatures.php @@ -10,9 +10,10 @@ * @link https://my-aac.org */ defined('MYAAC') or die('Direct access not allowed!'); -$title = "Creatures"; +$title = 'Creatures'; -if (empty($_REQUEST['creature'])) { +if (empty($_REQUEST['name'])) { + // display list of monsters $preview = config('creatures_images_preview'); $creatures = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'monsters` WHERE `hidden` != 1 '.(empty($_REQUEST['boss']) ? '': 'AND `rewardboss` = 1').' ORDER BY name asc')->fetchAll(); @@ -28,55 +29,55 @@ if (empty($_REQUEST['creature'])) { 'preview' => $preview )); -} else { - $creature_name = urldecode(stripslashes(ucwords(strtolower($_REQUEST['creature'])))); - $prep = $db->prepare('SELECT * FROM `' . TABLE_PREFIX . 'monsters` WHERE `hidden` != 1 AND `name` = ? LIMIT 1;'); - $prep->execute([$creature_name]); - $creature = $prep->fetch(); + return; +} - if (isset($creature['name'])) { - function sort_by_chance($a, $b) - { - if ($a['chance'] == $b['chance']) { - return 0; - } - return ($a['chance'] > $b['chance']) ? -1 : 1; +// display monster +$creature_name = urldecode(stripslashes(ucwords(strtolower($_REQUEST['name'])))); +$prep = $db->prepare('SELECT * FROM `' . TABLE_PREFIX . 'monsters` WHERE `hidden` != 1 AND `name` = ? LIMIT 1;'); +$prep->execute([$creature_name]); +$creature = $prep->fetch(); + +if (isset($creature['name'])) { + function sort_by_chance($a, $b) + { + if ($a['chance'] == $b['chance']) { + return 0; } - - $title = $creature['name'] . " - Creatures"; - - $creature['img_link']= getCreatureImgPath($creature_name); - - $voices = json_decode($creature['voices'], true); - $summons = json_decode($creature['summons'], true); - $elements = json_decode($creature['elements'], true); - $immunities = json_decode($creature['immunities'], true); - $loot = json_decode($creature['loot'], true); - usort($loot, 'sort_by_chance'); - - foreach ($loot as &$item) { - $item['name'] = getItemNameById($item['id']); - $item['rarity_chance'] = round($item['chance'] / 1000, 2); - $item['rarity'] = getItemRarity($item['chance']); - $item['tooltip'] = ucfirst($item['name']) . '
    Chance: ' . $item['rarity'] . (config('creatures_loot_percentage') ? ' ('. $item['rarity_chance'] .'%)' : '') . '
    Max count: ' . $item['count']; - } - - $creature['loot'] = isset($loot) ? $loot : null; - $creature['voices'] = isset($voices) ? $voices : null; - $creature['summons'] = isset($summons) ? $summons : null; - $creature['elements'] = isset($elements) ? $elements : null; - $creature['immunities'] = isset($immunities) ? $immunities : null; - - $twig->display('creature.html.twig', array( - 'creature' => $creature, - )); - - } else { - echo "Creature with name " . $creature_name . " doesn't exist."; + return ($a['chance'] > $b['chance']) ? -1 : 1; } -//back button - $twig->display('creatures.back_button.html.twig'); -} -?> + $title = $creature['name'] . " - Creatures"; + $creature['img_link']= getCreatureImgPath($creature_name); + + $voices = json_decode($creature['voices'], true); + $summons = json_decode($creature['summons'], true); + $elements = json_decode($creature['elements'], true); + $immunities = json_decode($creature['immunities'], true); + $loot = json_decode($creature['loot'], true); + usort($loot, 'sort_by_chance'); + + foreach ($loot as &$item) { + $item['name'] = getItemNameById($item['id']); + $item['rarity_chance'] = round($item['chance'] / 1000, 2); + $item['rarity'] = getItemRarity($item['chance']); + $item['tooltip'] = ucfirst($item['name']) . '
    Chance: ' . $item['rarity'] . (config('creatures_loot_percentage') ? ' ('. $item['rarity_chance'] .'%)' : '') . '
    Max count: ' . $item['count']; + } + + $creature['loot'] = isset($loot) ? $loot : null; + $creature['voices'] = isset($voices) ? $voices : null; + $creature['summons'] = isset($summons) ? $summons : null; + $creature['elements'] = isset($elements) ? $elements : null; + $creature['immunities'] = isset($immunities) ? $immunities : null; + + $twig->display('creature.html.twig', array( + 'creature' => $creature, + )); + +} else { + echo "Creature with name " . $creature_name . " doesn't exist."; +} + +// back button +$twig->display('creatures.back_button.html.twig'); diff --git a/system/pages/forum.php b/system/pages/forum.php index 12ec64e0..85456f2e 100644 --- a/system/pages/forum.php +++ b/system/pages/forum.php @@ -5,198 +5,59 @@ * @package MyAAC * @author Gesior * @author Slawkens - * @copyright 2019 MyAAC + * @copyright 2021 MyAAC * @link https://my-aac.org */ -defined('MYAAC') or die('Direct access not allowed!'); -$title = 'Forum'; +defined('MYAAC') or exit; -if(strtolower($config['forum']) != 'site') +require __DIR__ . '/forum/base.php'; +require __DIR__ . '/forum/admin.php'; + +$errors = []; +if(!empty($action)) { - if($config['forum'] != '') - { - header('Location: ' . $config['forum']); - exit; + if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { + error('Error: Action contains illegal characters.'); } - - echo 'Forum is disabled on this site.'; - return; -} - -if(!$logged) - echo 'You are not logged in. Log in to post on the forum.

    '; - -require_once LIBS . 'forum.php'; - -$canEdit = Forum::isModerator(); -if($canEdit) -{ - $groups = new OTS_Groups_List(); - - if(!empty($action)) - { - if($action == 'delete_board' || $action == 'edit_board' || $action == 'hide_board' || $action == 'moveup_board' || $action == 'movedown_board') - $id = $_REQUEST['id']; - - if(isset($_REQUEST['access'])) - $access = $_REQUEST['access']; - - if(isset($_REQUEST['guild'])) - $guild = $_REQUEST['guild']; - - if(isset($_REQUEST['name'])) - $name = $_REQUEST['name']; - - if(isset($_REQUEST['description'])) - $description = stripslashes($_REQUEST['description']); - - $errors = array(); - - if($action == 'add_board') { - if(Forum::add_board($name, $description, $access, $guild, $errors)) - $action = $name = $description = ''; - } - else if($action == 'delete_board') { - Forum::delete_board($id, $errors); - $action = ''; - } - else if($action == 'edit_board') - { - if(isset($id) && !isset($name)) { - $board = Forum::get_board($id); - $name = $board['name']; - $access = $board['access']; - $guild = $board['guild']; - $description = $board['description']; - } - else { - Forum::update_board($id, $name, $access, $guild, $description); - $action = $name = $description = ''; - $access = $guild = 0; - } - } - else if($action == 'hide_board') { - Forum::toggleHidden_board($id, $errors); - $action = ''; - } - else if($action == 'moveup_board') { - Forum::move_board($id, -1, $errors); - $action = ''; - } - else if($action == 'movedown_board') { - Forum::move_board($id, 1, $errors); - $action = ''; - } - - if(!empty($errors)) { - $twig->display('error_box.html.twig', array('errors' => $errors)); - $action = ''; - } - } - - if(empty($action) || $action == 'edit_board') { - $guilds = $db->query('SELECT `id`, `name` FROM `guilds`')->fetchAll(); - $twig->display('forum.add_board.html.twig', array( - 'link' => getLink('forum', ($action == 'edit_board' ? 'edit_board' : 'add_board')), - 'action' => $action, - 'id' => isset($id) ? $id : null, - 'name' => isset($name) ? $name : null, - 'description' => isset($description) ? $description : null, - 'access' => isset($access) ? $access : 0, - 'guild' => isset($guild) ? $guild : null, - 'groups' => $groups, - 'guilds' => $guilds - )); - - if($action == 'edit_board') - $action = ''; - } -} - -$sections = array(); -foreach(getForumBoards() as $section) -{ - $sections[$section['id']] = array( - 'id' => $section['id'], - 'name' => $section['name'], - 'description' => $section['description'], - 'closed' => $section['closed'] == '1', - 'guild' => $section['guild'], - 'access' => $section['access'] - ); - - if($canEdit) { - $sections[$section['id']]['hidden'] = $section['hidden']; + else if(file_exists(PAGES . 'forum/' . $action . '.php')) { + require PAGES . 'forum/' . $action . '.php'; + return; } else { - $sections[$section['id']]['hidden'] = 0; + error('This page does not exists.'); } } -$number_of_rows = 0; -if(empty($action)) -{ - $info = $db->query("SELECT `section`, COUNT(`id`) AS 'threads', SUM(`replies`) AS 'replies' FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `first_post` = `id` GROUP BY `section`")->fetchAll(); +$info = $db->query("SELECT `section`, COUNT(`id`) AS 'threads', SUM(`replies`) AS 'replies' FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `first_post` = `id` GROUP BY `section`")->fetchAll(); - $boards = array(); - foreach($info as $data) - $counters[$data['section']] = array('threads' => $data['threads'], 'posts' => $data['replies'] + $data['threads']); - foreach($sections as $id => $section) - { - $show = true; - if(Forum::hasAccess($id)) { - $last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".(int) $id." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch(); - $boards[] = array( - 'id' => $id, - 'link' => getForumBoardLink($id), - 'name' => $section['name'], - 'description' => $section['description'], - 'hidden' => $section['hidden'], - 'posts' => isset($counters[$id]['posts']) ? $counters[$id]['posts'] : 0, - 'threads' => isset($counters[$id]['threads']) ? $counters[$id]['threads'] : 0, - 'last_post' => array( - 'name' => isset($last_post['name']) ? $last_post['name'] : null, - 'date' => isset($last_post['post_date']) ? $last_post['post_date'] : null, - 'player_link' => isset($last_post['name']) ? getPlayerLink($last_post['name']) : null, - ) - ); - } +$boards = array(); +foreach($info as $data) + $counters[$data['section']] = array('threads' => $data['threads'], 'posts' => $data['replies'] + $data['threads']); + +foreach($sections as $id => $section) +{ + $show = true; + if(Forum::hasAccess($id)) { + $last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".(int) $id." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch(); + $boards[] = array( + 'id' => $id, + 'link' => getForumBoardLink($id), + 'name' => $section['name'], + 'description' => $section['description'], + 'hidden' => $section['hidden'], + 'posts' => isset($counters[$id]['posts']) ? $counters[$id]['posts'] : 0, + 'threads' => isset($counters[$id]['threads']) ? $counters[$id]['threads'] : 0, + 'last_post' => array( + 'name' => isset($last_post['name']) ? $last_post['name'] : null, + 'date' => isset($last_post['post_date']) ? $last_post['post_date'] : null, + 'player_link' => isset($last_post['name']) ? getPlayerLink($last_post['name']) : null, + ) + ); } - - $twig->display('forum.boards.html.twig', array( - 'boards' => $boards, - 'canEdit' => $canEdit, - 'last' => count($sections) - )); - - return; } -$errors = array(); -if($action == 'show_board' || $action == 'show_thread') -{ - require PAGES . 'forum/' . $action . '.php'; - return; -} - -if(!$logged) -{ - $extra_url = ''; - if($action == 'new_post' && isset($_GET['thread_id'])) { - $extra_url = '&action=new_post&thread_id=' . $_GET['thread_id']; - } - - header('Location: ' . BASE_URL . '?subtopic=accountmanagement&redirect=' . BASE_URL . urlencode('?subtopic=forum' . $extra_url)); - return; -} - -if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { - error('Error: Action contains illegal characters.'); -} -else if(file_exists(PAGES . 'forum/' . $action . '.php')) { - require PAGES . 'forum/' . $action . '.php'; -} -else { - error('This page does not exists.'); -} -?> +$twig->display('forum.boards.html.twig', array( + 'boards' => $boards, + 'canEdit' => $canEdit, + 'last' => count($sections) +)); diff --git a/system/pages/forum/admin.php b/system/pages/forum/admin.php new file mode 100644 index 00000000..136c627a --- /dev/null +++ b/system/pages/forum/admin.php @@ -0,0 +1,95 @@ + + * @author Slawkens + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or exit('Direct access not allowed!'); + +$canEdit = Forum::isModerator(); +if($canEdit) { + $groups = new OTS_Groups_List(); + + if(!empty($action)) + { + if($action == 'delete_board' || $action == 'edit_board' || $action == 'hide_board' || $action == 'moveup_board' || $action == 'movedown_board') + $id = $_REQUEST['id']; + + if(isset($_REQUEST['access'])) + $access = $_REQUEST['access']; + + if(isset($_REQUEST['guild'])) + $guild = $_REQUEST['guild']; + + if(isset($_REQUEST['name'])) + $name = $_REQUEST['name']; + + if(isset($_REQUEST['description'])) + $description = stripslashes($_REQUEST['description']); + + $errors = array(); + + if($action == 'add_board') { + if(Forum::add_board($name, $description, $access, $guild, $errors)) + $action = $name = $description = ''; + } + else if($action == 'delete_board') { + Forum::delete_board($id, $errors); + $action = ''; + } + else if($action == 'edit_board') + { + if(isset($id) && !isset($name)) { + $board = Forum::get_board($id); + $name = $board['name']; + $access = $board['access']; + $guild = $board['guild']; + $description = $board['description']; + } + else { + Forum::update_board($id, $name, $access, $guild, $description); + $action = $name = $description = ''; + $access = $guild = 0; + } + } + else if($action == 'hide_board') { + Forum::toggleHidden_board($id, $errors); + $action = ''; + } + else if($action == 'moveup_board') { + Forum::move_board($id, -1, $errors); + $action = ''; + } + else if($action == 'movedown_board') { + Forum::move_board($id, 1, $errors); + $action = ''; + } + + if(!empty($errors)) { + $twig->display('error_box.html.twig', array('errors' => $errors)); + $action = ''; + } + } + + if(empty($action) || $action == 'edit_board') { + $guilds = $db->query('SELECT `id`, `name` FROM `guilds`')->fetchAll(); + $twig->display('forum.add_board.html.twig', array( + 'link' => getLink('forum', ($action == 'edit_board' ? 'edit_board' : 'add_board')), + 'action' => $action, + 'id' => isset($id) ? $id : null, + 'name' => isset($name) ? $name : null, + 'description' => isset($description) ? $description : null, + 'access' => isset($access) ? $access : 0, + 'guild' => isset($guild) ? $guild : null, + 'groups' => $groups, + 'guilds' => $guilds + )); + + if($action == 'edit_board') + $action = ''; + } +} diff --git a/system/pages/forum/base.php b/system/pages/forum/base.php new file mode 100644 index 00000000..fa207ca0 --- /dev/null +++ b/system/pages/forum/base.php @@ -0,0 +1,51 @@ + + * @author Slawkens + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Forum'; + +if(strtolower($config['forum']) != 'site') +{ + if($config['forum'] != '') + { + header('Location: ' . $config['forum']); + exit; + } + + echo 'Forum is disabled on this site.'; + return; +} + +if(!$logged) + echo 'You are not logged in. Log in to post on the forum.

    '; + +require_once LIBS . 'forum.php'; + +$sections = array(); +foreach(getForumBoards() as $section) +{ + $sections[$section['id']] = array( + 'id' => $section['id'], + 'name' => $section['name'], + 'description' => $section['description'], + 'closed' => $section['closed'] == '1', + 'guild' => $section['guild'], + 'access' => $section['access'] + ); + + if($canEdit) { + $sections[$section['id']]['hidden'] = $section['hidden']; + } + else { + $sections[$section['id']]['hidden'] = 0; + } +} + +$number_of_rows = 0; diff --git a/system/pages/forum/edit_post.php b/system/pages/forum/edit_post.php index f522c5e6..45fd675b 100644 --- a/system/pages/forum/edit_post.php +++ b/system/pages/forum/edit_post.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(Forum::canPost($account_logged)) { $post_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : false; @@ -113,4 +115,4 @@ if(Forum::canPost($account_logged)) else echo "
    Your account is banned, deleted or you don't have any player with level " . $config['forum_level_required'] . " on your account. You can't post."; -?> \ No newline at end of file +?> diff --git a/system/pages/forum/move_thread.php b/system/pages/forum/move_thread.php index 48fb08f0..8fcb98fb 100644 --- a/system/pages/forum/move_thread.php +++ b/system/pages/forum/move_thread.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!Forum::isModerator()) { echo 'You are not logged in or you are not moderator.'; } @@ -61,4 +63,4 @@ else { else echo 'Post with ID ' . $post_id . ' does not exist.'; } -?> \ No newline at end of file +?> diff --git a/system/pages/forum/new_post.php b/system/pages/forum/new_post.php index 436e162d..a3e68dff 100644 --- a/system/pages/forum/new_post.php +++ b/system/pages/forum/new_post.php @@ -10,6 +10,19 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + +if(!$logged) +{ + $extra_url = ''; + if(isset($_GET['thread_id'])) { + $extra_url = '&action=new_post&thread_id=' . $_GET['thread_id']; + } + + header('Location: ' . BASE_URL . '?subtopic=accountmanagement&redirect=' . BASE_URL . urlencode('?subtopic=forum' . $extra_url)); + return; +} + if(Forum::canPost($account_logged)) { $players_from_account = $db->query("SELECT `players`.`name`, `players`.`id` FROM `players` WHERE `players`.`account_id` = ".(int) $account_logged->getId())->fetchAll(); @@ -116,4 +129,4 @@ if(Forum::canPost($account_logged)) else echo "Your account is banned, deleted or you don't have any player with level " . $config['forum_level_required'] . " on your account. You can't post."; -$twig->display('forum.fullscreen.html.twig'); \ No newline at end of file +$twig->display('forum.fullscreen.html.twig'); diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index 489ea2d3..4db06c63 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(Forum::canPost($account_logged)) { $players_from_account = $db->query('SELECT `players`.`name`, `players`.`id` FROM `players` WHERE `players`.`account_id` = '.(int) $account_logged->getId())->fetchAll(); @@ -102,4 +104,4 @@ if(Forum::canPost($account_logged)) else echo 'Your account is banned, deleted or you don\'t have any player with level '.$config['forum_level_required'].' on your account. You can\'t post.'; -?> \ No newline at end of file +?> diff --git a/system/pages/forum/remove_post.php b/system/pages/forum/remove_post.php index caef6a03..bd1e75a4 100644 --- a/system/pages/forum/remove_post.php +++ b/system/pages/forum/remove_post.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(Forum::isModerator()) { $id = (int) $_REQUEST['id']; @@ -33,4 +35,4 @@ if(Forum::isModerator()) echo 'Post with ID ' . $id . ' does not exist.'; } else - echo 'You are not logged in or you are not moderator.'; \ No newline at end of file + echo 'You are not logged in or you are not moderator.'; diff --git a/system/pages/forum/show_board.php b/system/pages/forum/show_board.php index 79b0d9b7..36251d8e 100644 --- a/system/pages/forum/show_board.php +++ b/system/pages/forum/show_board.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $links_to_pages = ''; $section_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : null; diff --git a/system/pages/forum/show_thread.php b/system/pages/forum/show_thread.php index bf6cda75..e6c8f926 100644 --- a/system/pages/forum/show_thread.php +++ b/system/pages/forum/show_thread.php @@ -10,9 +10,11 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $links_to_pages = ''; $thread_id = (int) $_REQUEST['id']; -$_page = (int) (isset($_REQUEST['page']) ? $_REQUEST['page'] : 0); +$_page = (int) ($_REQUEST['page'] ?? 0); $thread_starter = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`first_post` AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` LIMIT 1")->fetch(); if(empty($thread_starter['name'])) { diff --git a/system/pages/guilds.php b/system/pages/guilds.php index 0688a4c7..cf834210 100644 --- a/system/pages/guilds.php +++ b/system/pages/guilds.php @@ -11,16 +11,9 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Guilds'; -if($db->hasTable('guild_members')) - define('GUILD_MEMBERS_TABLE', 'guild_members'); -else - define('GUILD_MEMBERS_TABLE', 'guild_membership'); - -define('MOTD_EXISTS', $db->hasColumn('guilds', 'motd')); - //show list of guilds if(empty($action)) { - require PAGES . 'guilds/list_of_guilds.php'; + require PAGES . 'guilds/list.php'; } else { if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { diff --git a/system/pages/guilds/accept_invite.php b/system/pages/guilds/accept_invite.php index 59431fb6..7b013a2c 100644 --- a/system/pages/guilds/accept_invite.php +++ b/system/pages/guilds/accept_invite.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + //set rights in guild $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : null; diff --git a/system/pages/guilds/add_rank.php b/system/pages/guilds/add_rank.php index 56b20949..acb65aea 100644 --- a/system/pages/guilds/add_rank.php +++ b/system/pages/guilds/add_rank.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $rank_name = isset($_REQUEST['rank_name']) ? $_REQUEST['rank_name'] : null; if(!Validator::guildName($guild_name)) { @@ -74,4 +76,4 @@ else } } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/base.php b/system/pages/guilds/base.php new file mode 100644 index 00000000..07fc432d --- /dev/null +++ b/system/pages/guilds/base.php @@ -0,0 +1,17 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +if($db->hasTable('guild_members')) + define('GUILD_MEMBERS_TABLE', 'guild_members'); +else + define('GUILD_MEMBERS_TABLE', 'guild_membership'); + +define('MOTD_EXISTS', $db->hasColumn('guilds', 'motd')); diff --git a/system/pages/guilds/change_description.php b/system/pages/guilds/change_description.php index 8d803af5..b4e787ee 100644 --- a/system/pages/guilds/change_description.php +++ b/system/pages/guilds/change_description.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); diff --git a/system/pages/guilds/change_logo.php b/system/pages/guilds/change_logo.php index 109b2379..fea3005f 100644 --- a/system/pages/guilds/change_logo.php +++ b/system/pages/guilds/change_logo.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); diff --git a/system/pages/guilds/change_motd.php b/system/pages/guilds/change_motd.php index 490fea5f..c777548d 100644 --- a/system/pages/guilds/change_motd.php +++ b/system/pages/guilds/change_motd.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!MOTD_EXISTS) return; @@ -74,4 +76,4 @@ if(!empty($errors)) { )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/change_nick.php b/system/pages/guilds/change_nick.php index 5e900a33..bf773124 100644 --- a/system/pages/guilds/change_nick.php +++ b/system/pages/guilds/change_nick.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!$logged) { $errors[] = "You are not logged in. You can't change nick."; $twig->display('error_box.html.twig', array('errors' => $errors)); diff --git a/system/pages/guilds/change_rank.php b/system/pages/guilds/change_rank.php index a4fb7b17..4341db16 100644 --- a/system/pages/guilds/change_rank.php +++ b/system/pages/guilds/change_rank.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!$logged) { $errors[] = "You are not logged in. You can't change rank."; } diff --git a/system/pages/guilds/cleanup_guilds.php b/system/pages/guilds/cleanup_guilds.php index e5e3804e..ebc41ee3 100644 --- a/system/pages/guilds/cleanup_guilds.php +++ b/system/pages/guilds/cleanup_guilds.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!$logged) { echo "You are not logged in."; @@ -64,4 +66,4 @@ else echo "0 guilds found."; $twig->display('guilds.back_button.html.twig'); -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/cleanup_players.php b/system/pages/guilds/cleanup_players.php index b22746b1..30b1e8af 100644 --- a/system/pages/guilds/cleanup_players.php +++ b/system/pages/guilds/cleanup_players.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!$logged) { echo "You are not logged in."; @@ -66,4 +68,4 @@ else echo "0 players found."; $twig->display('guilds.back_button.html.twig'); -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/create.php b/system/pages/guilds/create.php index 12a75d0b..9814ade0 100644 --- a/system/pages/guilds/create.php +++ b/system/pages/guilds/create.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : NULL; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : NULL; $todo = isset($_REQUEST['todo']) ? $_REQUEST['todo'] : NULL; @@ -131,4 +133,4 @@ else { )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/delete_by_admin.php b/system/pages/guilds/delete_by_admin.php index fd9beafb..3e083c8a 100644 --- a/system/pages/guilds/delete_by_admin.php +++ b/system/pages/guilds/delete_by_admin.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); @@ -65,4 +67,4 @@ if(!empty($errors)) { )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/delete_guild.php b/system/pages/guilds/delete_guild.php index cfc87c65..978ac513 100644 --- a/system/pages/guilds/delete_guild.php +++ b/system/pages/guilds/delete_guild.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); @@ -77,4 +79,4 @@ if(!empty($errors)) { )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/delete_invite.php b/system/pages/guilds/delete_invite.php index 8a58f323..1bf5f730 100644 --- a/system/pages/guilds/delete_invite.php +++ b/system/pages/guilds/delete_invite.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $name = stripslashes($_REQUEST['name']); @@ -113,4 +115,4 @@ else 'guild_name' => $guild->getName() )); } -} \ No newline at end of file +} diff --git a/system/pages/guilds/delete_rank.php b/system/pages/guilds/delete_rank.php index 4e52d60e..6a8f642c 100644 --- a/system/pages/guilds/delete_rank.php +++ b/system/pages/guilds/delete_rank.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $rank_to_delete = isset($_REQUEST['rankid']) ? (int) $_REQUEST['rankid'] : null; diff --git a/system/pages/guilds/invite.php b/system/pages/guilds/invite.php index 57eda6cf..09957d2d 100644 --- a/system/pages/guilds/invite.php +++ b/system/pages/guilds/invite.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + //set rights in guild $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : NULL; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : NULL; @@ -122,4 +124,4 @@ if($show) { $twig->display('guilds.back_button.html.twig', array( 'action' => getLink('guilds') . '/' . $guild_name -)); \ No newline at end of file +)); diff --git a/system/pages/guilds/kick_player.php b/system/pages/guilds/kick_player.php index f121ecfc..5ce79187 100644 --- a/system/pages/guilds/kick_player.php +++ b/system/pages/guilds/kick_player.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + //set rights in guild $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : null; @@ -118,4 +120,4 @@ else )); } } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/leave_guild.php b/system/pages/guilds/leave.php similarity index 98% rename from system/pages/guilds/leave_guild.php rename to system/pages/guilds/leave.php index 2ce49c8a..892deb89 100644 --- a/system/pages/guilds/leave_guild.php +++ b/system/pages/guilds/leave.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + //set rights in guild $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : NULL; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : NULL; diff --git a/system/pages/guilds/list_of_guilds.php b/system/pages/guilds/list.php similarity index 97% rename from system/pages/guilds/list_of_guilds.php rename to system/pages/guilds/list.php index c20825cc..6296db72 100644 --- a/system/pages/guilds/list_of_guilds.php +++ b/system/pages/guilds/list.php @@ -11,6 +11,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guilds_list = new OTS_Guilds_List(); $guilds_list->orderBy("name"); diff --git a/system/pages/guilds/manager.php b/system/pages/guilds/manager.php index c3cabdc8..4d59c22e 100644 --- a/system/pages/guilds/manager.php +++ b/system/pages/guilds/manager.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); @@ -56,5 +58,3 @@ if(empty($errors)) { if(!empty($errors)) { $twig->display('error_box.html.twig', array('errors' => $errors)); } - -?> \ No newline at end of file diff --git a/system/pages/guilds/pass_leadership.php b/system/pages/guilds/pass_leadership.php index ddb3b4a3..462ac9ec 100644 --- a/system/pages/guilds/pass_leadership.php +++ b/system/pages/guilds/pass_leadership.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : NULL; $pass_to = isset($_REQUEST['player']) ? stripslashes($_REQUEST['player']) : NULL; if(!Validator::guildName($guild_name)) { @@ -116,4 +118,4 @@ if(!empty($guild_errors)) { echo '
    ' . $twig->render('buttons.back.html.twig') . '
    '; } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/save_ranks.php b/system/pages/guilds/save_ranks.php index fc1ed87a..65e047bb 100644 --- a/system/pages/guilds/save_ranks.php +++ b/system/pages/guilds/save_ranks.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); diff --git a/system/pages/guilds/show.php b/system/pages/guilds/show.php index 10a8eeef..dc10480c 100644 --- a/system/pages/guilds/show.php +++ b/system/pages/guilds/show.php @@ -12,6 +12,9 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Guilds'; + +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) $errors[] = Validator::getLastError(); diff --git a/system/pages/highscores.php b/system/pages/highscores.php index 4988443b..95647893 100644 --- a/system/pages/highscores.php +++ b/system/pages/highscores.php @@ -15,12 +15,12 @@ $configHighscoresCountryBox = config('highscores_country_box'); if(config('account_country') && $configHighscoresCountryBox) require SYSTEM . 'countries.conf.php'; -$list = isset($_GET['list']) ? $_GET['list'] : 'experience'; -$_page = isset($_GET['page']) ? $_GET['page'] : 1; -$vocation = isset($_GET['vocation']) ? $_GET['vocation'] : 'all'; +$list = $_GET['list'] ?? 'experience'; +$page = $_GET['page'] ?? 1; +$vocation = $_GET['vocation'] ?? 'all'; -if(!is_numeric($_page) || $_page < 1 || $_page > PHP_INT_MAX) { - $_page = 1; +if(!is_numeric($page) || $page < 1 || $page > PHP_INT_MAX) { + $page = 1; } $add_sql = ''; @@ -47,8 +47,8 @@ if($configHighscoresVocationBox && $vocation !== 'all') } } -define('SKILL_FRAGS', -1); -define('SKILL_BALANCE', -2); +const SKILL_FRAGS = -1; +const SKILL_BALANCE = -2; $skill = POT::SKILL__LEVEL; if(is_numeric($list)) @@ -139,7 +139,7 @@ $configHighscoresPerPage = config('highscores_per_page'); $limit = $configHighscoresPerPage + 1; $needReCache = true; -$cacheKey = 'highscores_' . $skill . '_' . $vocation . '_' . $_page . '_' . $configHighscoresPerPage; +$cacheKey = 'highscores_' . $skill . '_' . $vocation . '_' . $page . '_' . $configHighscoresPerPage; $cache = Cache::getInstance(); if ($cache->enabled()) { @@ -150,7 +150,7 @@ if ($cache->enabled()) { } } -$offset = ($_page - 1) * $configHighscoresPerPage; +$offset = ($page - 1) * $configHighscoresPerPage; if (!isset($highscores) || empty($highscores)) { if ($skill >= POT::SKILL_FIRST && $skill <= POT::SKILL_LAST) { // skills if ($db->hasColumn('players', 'skill_fist')) {// tfs 1.0 @@ -280,14 +280,14 @@ foreach($highscores as $id => &$player) //link to previous page if actual page is not first $linkPreviousPage = ''; -if($_page > 1) { - $linkPreviousPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($_page - 1); +if($page > 1) { + $linkPreviousPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($page - 1); } //link to next page if any result will be on next page $linkNextPage = ''; if($show_link_to_next_page) { - $linkNextPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($_page + 1); + $linkNextPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($page + 1); } $types = array( diff --git a/system/pages/news.php b/system/pages/news.php index 30e00b54..92d2e7ab 100644 --- a/system/pages/news.php +++ b/system/pages/news.php @@ -64,7 +64,6 @@ if(isset($_GET['archive'])) 'icon' => $categories[$news['category']]['icon_id'], 'author' => $config['news_author'] ? $author : '', 'comments' => $news['comments'] != 0 ? getForumThreadLink($news['comments']) : null, - 'news_date_format' => $config['news_date_format'] )); } else @@ -214,7 +213,6 @@ if(!$news_cached) 'icon' => $categories[$news['category']]['icon_id'], 'author' => $config['news_author'] ? $author : '', 'comments' => $news['comments'] != 0 ? getForumThreadLink($news['comments']) : null, - 'news_date_format' => $config['news_date_format'], 'hidden'=> $news['hidden'] )); } diff --git a/system/pages/newsarchive.php b/system/pages/news/archive.php similarity index 86% rename from system/pages/newsarchive.php rename to system/pages/news/archive.php index aefa0fa9..fbcbe2fd 100644 --- a/system/pages/newsarchive.php +++ b/system/pages/news/archive.php @@ -9,5 +9,4 @@ * @link https://my-aac.org */ $_GET['archive'] = true; -require 'news.php'; -?> +require __DIR__ . '/../news.php'; diff --git a/system/pages/online.php b/system/pages/online.php index 02863858..ca629a3b 100644 --- a/system/pages/online.php +++ b/system/pages/online.php @@ -17,7 +17,8 @@ if($config['account_country']) $promotion = ''; if($db->hasColumn('players', 'promotion')) $promotion = '`promotion`,'; -$order = isset($_GET['order']) ? $_GET['order'] : 'name'; + +$order = $_GET['order'] ?? 'name'; if(!in_array($order, array('country', 'name', 'level', 'vocation'))) $order = $db->fieldName('name'); else if($order == 'country') diff --git a/system/router.php b/system/router.php new file mode 100644 index 00000000..ff8c7d3d --- /dev/null +++ b/system/router.php @@ -0,0 +1,303 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ + +if(!isset($content[0])) + $content = ''; + +// check if site has been closed +$load_it = true; +$site_closed = false; +if(fetchDatabaseConfig('site_closed', $site_closed)) { + $site_closed = ($site_closed == 1); + if($site_closed) { + if(!admin()) + { + $title = getDatabaseConfig('site_closed_title'); + $content .= '

    ' . getDatabaseConfig('site_closed_message') . '


    '; + $load_it = false; + } + + if(!$logged) + { + ob_start(); + require SYSTEM . 'pages/account/manage.php'; + $content .= ob_get_contents(); + ob_end_clean(); + $load_it = false; + } + } +} +define('SITE_CLOSED', $site_closed); + +// Strip query string (?foo=bar) and decode URI +/** @var string $uri */ +if (false !== $pos = strpos($uri, '?')) { + if ($pos !== 1) { + $uri = substr($uri, 0, $pos); + } + else { + $uri = str_replace_first('?', '', $uri); + } +} + +$uri = rawurldecode($uri); +if (BASE_DIR !== '') { + $tmp = str_replace_first('/', '', BASE_DIR); + $uri = str_replace_first($tmp . '/', '', $uri); +} + +define('URI', $uri); + +/** @var boolean $load_it */ +if(!$load_it) { + // ignore warnings in some functions/plugins + // page is not loaded anyways + define('PAGE', ''); + + return; +} + +/** @var string $content */ +if(SITE_CLOSED && admin()) + $content .= '

    Site is under maintenance (closed mode). Only privileged users can see it.

    '; + +$ignore = false; + +/** @var boolean $logged */ +/** @var OTS_Account $account_logged */ +$logged_access = 1; +if($logged && $account_logged && $account_logged->isLoaded()) { + $logged_access = $account_logged->getAccess(); +} + +/** + * Routes loading + */ +$dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) { + $routes = require SYSTEM . 'routes.php'; + + $isAlreadyDefined = []; + + $routesTmp = []; + foreach(getDatabasePages() as $page) { + $isAlreadyDefined[$page] = true; + $routesTmp[] = ['*', $page, '__database__/' . $page, true]; + } + + Plugins::clearWarnings(); + foreach (Plugins::getRoutes() as $route) { + if(!isset($isAlreadyDefined[$route[1]])) { + $isAlreadyDefined[$route[1]] = true; + $routesTmp[] = [$route[0], $route[1], $route[2]]; + } + } + + foreach ($routes as $route) { + if(!isset($isAlreadyDefined[$route[1]])) { + if (strpos($route[2], '__redirect__') === false && strpos($route[2], '__database__') === false) { + $routesTmp[] = [$route[0], $route[1], 'system/pages/' . $route[2]]; + } + else { + $routesTmp[] = [$route[0], $route[1], $route[2]]; + } + } + } + + //var_dump($routesTmp); + foreach ($routesTmp as $route) { + if ($route[0] === '*') { + $route[0] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD']; + } + + $aliases = [ + [':int', ':string', ':alphanum'], + [':\d+', ':[A-Za-z0-9-_%+\']+}', ':[A-Za-z0-9]+'], + ]; + + // apply aliases + $route[1] = str_replace($aliases[0], $aliases[1], $route[1]); + + $r->addRoute($route[0], $route[1], $route[2]); + } + + if (config('env') === 'dev') { + foreach(Plugins::getWarnings() as $warning) { + log_append('router.log', $warning); + } + } +}, + [ + 'cacheFile' => CACHE . 'route.cache', + 'cacheDisabled' => config('env') === 'dev', + ] +); + +// Fetch method and URI +$httpMethod = $_SERVER['REQUEST_METHOD']; + +$found = true; + +// old support for pages like /?subtopic=accountmanagement +$page = $_REQUEST['p'] ?? ($_REQUEST['subtopic'] ?? ''); +if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) { + if (config('backward_support')) { + require SYSTEM . 'compat/pages.php'; + } + + $file = loadPageFromFileSystem($page, $found); + if(!$found) { + $file = false; + } +} +else { + $routeInfo = $dispatcher->dispatch($httpMethod, $uri); + switch ($routeInfo[0]) { + case FastRoute\Dispatcher::NOT_FOUND: + // ... 404 Not Found + //var_dump('not found'); + /** + * Fallback to load page from templates/ or system/pages/ directory + */ + $page = $uri; + if (preg_match('/^[A-z0-9\/\-]+$/', $page)) { + $file = loadPageFromFileSystem($page, $found); + } else { + $found = false; + } + + break; + + case FastRoute\Dispatcher::METHOD_NOT_ALLOWED: + // ... 405 Method Not Allowed + $page = '405'; + $allowedMethods = $routeInfo[1]; + $file = SYSTEM . 'pages/405.php'; + break; + + case FastRoute\Dispatcher::FOUND: + $path = $routeInfo[1]; + $vars = $routeInfo[2]; + + $_REQUEST = array_merge($_REQUEST, $vars); + $_GET = array_merge($_GET, $vars); + + if (strpos($path, '__database__/') !== false) { + $pageName = str_replace('__database__/', '', $path); + + $success = false; + $tmp_content = getCustomPage($pageName, $success); + if ($success) { + $content .= $tmp_content; + if (hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) { + $pageInfo = getCustomPageInfo($pageName); + $content = $twig->render('admin.pages.links.html.twig', array( + 'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0') + )) . $content; + } + + $page = $pageName; + $file = false; + } + } else if (strpos($path, '__redirect__/') !== false) { + $path = str_replace('__redirect__/', '', $path); + header('Location: ' . BASE_URL . $path); + exit; + } else { + // parse for define PAGE + $tmp = BASE_DIR; + $uri = $_SERVER['REQUEST_URI']; + if (!empty($tmp)) { + $uri = str_replace(BASE_DIR . '/', '', $uri); + } + + if (false !== $pos = strpos($uri, '?')) { + $uri = substr($uri, 0, $pos); + } + if (0 === strpos($uri, '/')) { + $uri = str_replace_first('/', '', $uri); + } + + $page = $uri; + $file = BASE . $path; + } + + unset($tmp, $uri); + break; + } +} + +if (!$found) { + $page = '404'; + $file = SYSTEM . 'pages/404.php'; +} + +define('PAGE', $page); + +ob_start(); +if($hooks->trigger(HOOK_BEFORE_PAGE)) { + if(!$ignore && $file !== false) + require $file; +} + +unset($file); + +if(config('backward_support') && isset($main_content[0])) + $content .= $main_content; + +$content .= ob_get_contents(); +ob_end_clean(); +$hooks->trigger(HOOK_AFTER_PAGE); + +if(!isset($title)) { + $title = ucfirst($page); +} + +if(config('backward_support')) { + $main_content = $content; + $topic = $title; +} + +unset($page); + +function getDatabasePages() { + global $db; + $pages = $db->query('SELECT `name` FROM ' . TABLE_PREFIX . 'pages'); + $ret = []; + + if ($pages->rowCount() < 1) { + return $ret; + } + + foreach($pages->fetchAll() as $page) { + $ret [] = $page['name']; + } + + return $ret; +} + +function loadPageFromFileSystem($page, &$found) { + $file = SYSTEM . 'pages/' . $page . '.php'; + if (!is_file($file)) { + // feature: convert camelCase to snake_case + // so instead of forum/move_thread + // we can write: forum/moveThread + $file = SYSTEM . 'pages/' . camelCaseToUnderscore($page) . '.php'; + if (!is_file($file)) { + // feature: load pages from templates/ dir + global $template_path; + $file = $template_path . '/pages/' . $page . '.php'; + if (!is_file($file)) { + $found = false; + } + } + } + + return $file; +} diff --git a/system/routes.php b/system/routes.php new file mode 100644 index 00000000..a7ddd295 --- /dev/null +++ b/system/routes.php @@ -0,0 +1,58 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ + +return [ + ['GET', '', '__redirect__/news'], // redirect empty URL to news + ['GET', 'news/archive/{id:int}[/]', 'news/archive.php'], + + // block access to some files + ['*', 'account/base[/]', '404.php'], // this is to block account/base.php + ['*', 'forum/base[/]', '404.php'], + ['*', 'guilds/base[/]', '404.php'], + + [['GET', 'POST'], 'account/password[/]', 'account/change_password.php'], + [['GET', 'POST'], 'account/register/new[/]', 'account/register_new.php'], + [['GET', 'POST'], 'account/email[/]', 'account/change_email.php'], + [['GET', 'POST'], 'account/info[/]', 'account/change_info.php'], + [['GET', 'POST'], 'account/character/create[/]', 'account/create_character.php'], + [['GET', 'POST'], 'account/character/name[/]', 'account/change_name.php'], + [['GET', 'POST'], 'account/character/sex[/]', 'account/change_sex.php'], + [['GET', 'POST'], 'account/character/delete[/]', 'account/delete_character.php'], + [['GET', 'POST'], 'account/character/comment[/{name:[A-Za-z0-9-_%+\']+}]', 'account/change_comment.php'], + ['GET', 'account/confirm_email/{hash:[A-Za-z0-9-_]+}[/]', 'account/confirm_email.php'], + + ['GET', 'bans/{page:\d+}[/]', 'bans.php'], + [['GET', 'POST'], 'characters[/{name:string]', 'characters.php'], + ['GET', 'changelog[/{page:int}]', 'changelog.php'], + ['GET', 'creatures[/{name:string}]', 'creatures.php'], + + ['GET', 'faq[/{action:string}]', 'faq.php'], + + [['GET', 'POST'], 'forum/{action:string}[/]', 'forum.php'], + ['GET', 'forum/board/{id:int}[/]', 'forum/show_board.php'], + ['GET', 'forum/board/{id:int}/{page:[0-9]+}[/]', 'forum/show_board.php'], + ['GET', 'forum/thread/{id:int}[/]', 'forum/show_thread.php'], + ['GET', 'forum/thread/{id:int}/{page:int}[/]', 'forum/show_thread.php'], + + ['GET', 'gallery/{image:int}[/]', 'gallery.php'], + [['GET', 'POST'], 'gallery/{action:string}[/]', 'gallery.php'], + + [['GET', 'POST'], 'guilds/{guild:string}[/]', 'guilds/show.php'], + + ['GET', 'highscores/{list:alphanum}/{vocation:alphanum}/{page:int}[/]', 'highscores.php'], + ['GET', 'highscores/{list:alphanum}/{page:int}[/]', 'highscores.php'], + ['GET', 'highscores/{list:alphanum}/{vocation:alphanum}[/]', 'highscores.php'], + ['GET', 'highscores/{list:alphanum}[/]', 'highscores.php'], +/* + '/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'), + '/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'), + '/^spells\/[A-Za-z0-9-_%]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'spells', 'vocation' => '$1', 'order' => '$2'), + '/^houses\/view\/?$/' => array('subtopic' => 'houses', 'page' => 'view')*/ +]; diff --git a/system/templates/account.login.html.twig b/system/templates/account.login.html.twig index 5edaec75..4005202b 100644 --- a/system/templates/account.login.html.twig +++ b/system/templates/account.login.html.twig @@ -1,4 +1,4 @@ -Please enter your account {{ account|lower }} and your password.
    Create an account if you do not have one yet.

    +Please enter your account {{ account|lower }} and your password.
    Create an account if you do not have one yet.

    {% if redirect is not null %} diff --git a/system/templates/admin.changelog.form.html.twig b/system/templates/admin.changelog.form.html.twig index e3ca5dab..99b90f7a 100644 --- a/system/templates/admin.changelog.form.html.twig +++ b/system/templates/admin.changelog.form.html.twig @@ -11,12 +11,12 @@
    - +
    - +
    diff --git a/system/templates/admin.dashboard.html.twig b/system/templates/admin.dashboard.html.twig deleted file mode 100644 index e69de29b..00000000 diff --git a/system/templates/admin.login.html.twig b/system/templates/admin.login.html.twig index aed34a5b..2abc4eb1 100644 --- a/system/templates/admin.login.html.twig +++ b/system/templates/admin.login.html.twig @@ -18,7 +18,7 @@
    - +
    diff --git a/system/templates/admin.news.form.html.twig b/system/templates/admin.news.form.html.twig index 7c2c317e..ddad9dd9 100644 --- a/system/templates/admin.news.form.html.twig +++ b/system/templates/admin.news.form.html.twig @@ -11,7 +11,7 @@
    - +
    diff --git a/system/templates/admin.open_source.html.twig b/system/templates/admin.open_source.html.twig new file mode 100644 index 00000000..f469a65a --- /dev/null +++ b/system/templates/admin.open_source.html.twig @@ -0,0 +1,32 @@ +
    +
    +
    Open Source Software
    +
    +
    + MyAAC uses following Open Source libraries:

    + HTML/Javascript/CSS: + + PHP: + +
    +
    diff --git a/system/templates/admin.pages.form.html.twig b/system/templates/admin.pages.form.html.twig index cd96f13d..ae666294 100644 --- a/system/templates/admin.pages.form.html.twig +++ b/system/templates/admin.pages.form.html.twig @@ -3,22 +3,18 @@
    {% if action == 'edit' %}Edit{% else %}Add{% endif %} page
    - + {% if action == 'edit' %} {% endif %}
    - +
    - +
    diff --git a/system/templates/admin.plugins.form.html.twig b/system/templates/admin.plugins.form.html.twig index d68203f1..8f43b908 100644 --- a/system/templates/admin.plugins.form.html.twig +++ b/system/templates/admin.plugins.form.html.twig @@ -1,4 +1,4 @@ -
    +
    Install plugin
    diff --git a/system/templates/admin.tools.account.html.twig b/system/templates/admin.tools.account.html.twig index 97eaa944..ee32fc99 100644 --- a/system/templates/admin.tools.account.html.twig +++ b/system/templates/admin.tools.account.html.twig @@ -5,7 +5,7 @@
    Give Premium Points
    - +
    @@ -27,7 +27,7 @@
    Give Coins
    - +
    @@ -49,7 +49,7 @@
    Give Premium Days
    - +
    diff --git a/system/templates/admin.tools.teleport.html.twig b/system/templates/admin.tools.teleport.html.twig index e81cada9..68cc3404 100644 --- a/system/templates/admin.tools.teleport.html.twig +++ b/system/templates/admin.tools.teleport.html.twig @@ -4,11 +4,11 @@
    Set Town
    - +
    - {% if config.towns|length > 0 %} {% for town_id, town_name in config.towns %} @@ -31,25 +31,25 @@
    Set Position
    - +
    - +
    - +
    - +
    @@ -66,12 +66,13 @@
    Teleport to Temple
    - + diff --git a/system/templates/characters.html.twig b/system/templates/characters.html.twig index 6faacdd9..aad31aa8 100644 --- a/system/templates/characters.html.twig +++ b/system/templates/characters.html.twig @@ -7,7 +7,7 @@ {% set rows = 0 %} - +
    {{ hook(constant('HOOK_CHARACTERS_BEFORE_INFORMATIONS')) }} {% if canEdit %} diff --git a/system/templates/exception.html.twig b/system/templates/exception.html.twig index 6f505245..7a31b4bb 100644 --- a/system/templates/exception.html.twig +++ b/system/templates/exception.html.twig @@ -8,8 +8,8 @@ - - + + diff --git a/system/templates/install.admin.html.twig b/system/templates/install.admin.html.twig index 26786d4d..a3a306a8 100644 --- a/system/templates/install.admin.html.twig +++ b/system/templates/install.admin.html.twig @@ -8,12 +8,12 @@
    - - {% for value in ['email', account, 'password', 'player_name'] %} - + + {% for value in ['email', 'account', 'password', 'password_confirm', 'player_name'] %} +
    - + {{ locale['step_admin_' ~ value ~ '_desc']|raw }}
    diff --git a/system/templates/online.html.twig b/system/templates/online.html.twig index 04e0b651..b7c9d916 100644 --- a/system/templates/online.html.twig +++ b/system/templates/online.html.twig @@ -85,14 +85,14 @@ {% if config.account_country %} - + {% endif %} {% if config.online_outfit %} {% endif %} - - - + + + {% set i = 0 %} {% for player in players %} diff --git a/system/twig.php b/system/twig.php index da4dc448..5b912875 100644 --- a/system/twig.php +++ b/system/twig.php @@ -14,6 +14,8 @@ $twig = new Twig_Environment($twig_loader, array( 'debug' => $dev_mode )); +$twig_loader->addPath(PLUGINS); + if($dev_mode) { $twig->addExtension(new Twig_DebugExtension()); } diff --git a/templates/tibiacom/index.php b/templates/tibiacom/index.php index 46cafb26..8ebbd5b6 100644 --- a/templates/tibiacom/index.php +++ b/templates/tibiacom/index.php @@ -388,7 +388,7 @@ foreach($config['menu_categories'] as $id => $cat) { -
    +
    ##OutfitNameLevelVocationNameLevelVocation