From 3c1210fefa1fedc1d3001c110f65929e2787f11d Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 3 Mar 2025 20:07:54 +0100 Subject: [PATCH 001/148] Nothing important, just better code style --- system/functions.php | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/system/functions.php b/system/functions.php index 7aa43935..947dd5bd 100644 --- a/system/functions.php +++ b/system/functions.php @@ -982,31 +982,29 @@ function load_config_lua($filename) continue; } $tmp_exp = explode('=', $line, 2); - if(strpos($line, 'dofile') !== false) - { + if(str_contains($line, 'dofile')) { $delimiter = '"'; - if(strpos($line, $delimiter) === false) + if(!str_contains($line, $delimiter)) { $delimiter = "'"; + } $tmp = explode($delimiter, $line); $result = array_merge($result, load_config_lua($config['server_path'] . $tmp[1])); } - else if(count($tmp_exp) >= 2) - { + else if(count($tmp_exp) >= 2) { $key = trim($tmp_exp[0]); - if(0 !== strpos($key, '--')) - { + if(!str_starts_with($key, '--')) { $value = trim($tmp_exp[1]); - if(strpos($value, '--') !== false) {// found some deep comment + if(str_contains($value, '--')) {// found some deep comment $value = preg_replace('/--.*$/i', '', $value); } if(is_numeric($value)) $result[$key] = (float) $value; elseif(in_array(@$value[0], array("'", '"')) && in_array(@$value[strlen($value) - 1], array("'", '"'))) - $result[$key] = (string) substr(substr($value, 1), 0, -1); + $result[$key] = substr(substr($value, 1), 0, -1); elseif(in_array($value, array('true', 'false'))) - $result[$key] = ($value === 'true') ? true : false; + $result[$key] = $value === 'true'; elseif(@$value[0] === '{') { // arrays are not supported yet // just ignore the error @@ -1014,7 +1012,7 @@ function load_config_lua($filename) } else { - foreach($result as $tmp_key => $tmp_value) // load values definied by other keys, like: dailyFragsToBlackSkull = dailyFragsToRedSkull + foreach($result as $tmp_key => $tmp_value) // load values defined by other keys, like: dailyFragsToBlackSkull = dailyFragsToRedSkull $value = str_replace($tmp_key, $tmp_value, $value); $ret = @eval("return $value;"); if((string) $ret == '' && trim($value) !== '""') // = parser error @@ -1028,8 +1026,7 @@ function load_config_lua($filename) } } - $result = array_merge($result, isset($config['lua']) ? $config['lua'] : array()); - return $result; + return array_merge($result, $config['lua'] ?? []); } function str_replace_first($search,$replace, $subject) { From 7312383f73c6d053ff7891a4366c1e44f8a140f1 Mon Sep 17 00:00:00 2001 From: Slawomir Boczek Date: Sun, 9 Mar 2025 21:18:12 +0100 Subject: [PATCH 002/148] Account actions rework on ip (Use single column for IP - VARCHAR(45)) (#289) * Account actions rework on ip (Use single column for IP - VARCHAR(45)) * No foreach needed here --- admin/pages/accounts.php | 4 ++-- common.php | 2 +- install/includes/schema.sql | 6 +++--- system/libs/pot/OTS_Account.php | 28 ++++++++++------------------ system/migrations/44.php | 27 +++++++++++++++++++++++++++ system/pages/account/manage.php | 6 +----- system/src/Models/AccountAction.php | 2 +- 7 files changed, 45 insertions(+), 30 deletions(-) create mode 100644 system/migrations/44.php diff --git a/admin/pages/accounts.php b/admin/pages/accounts.php index c2154299..67381b5e 100644 --- a/admin/pages/accounts.php +++ b/admin/pages/accounts.php @@ -9,6 +9,7 @@ */ use MyAAC\Models\Account as AccountModel; +use MyAAC\Models\AccountAction; use MyAAC\Models\Player; defined('MYAAC') or die('Direct access not allowed!'); @@ -466,9 +467,8 @@ else if (isset($_REQUEST['search'])) { getId())->orderByDesc('date')->get(); + $accountActions = AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get(); foreach ($accountActions as $i => $log): - $log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6)); ?> diff --git a/common.php b/common.php index 0c390ac7..99593401 100644 --- a/common.php +++ b/common.php @@ -27,7 +27,7 @@ if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is const MYAAC = true; const MYAAC_VERSION = '1.2'; -const DATABASE_VERSION = 43; +const DATABASE_VERSION = 44; const TABLE_PREFIX = 'myaac_'; define('START_TIME', microtime(true)); define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); diff --git a/install/includes/schema.sql b/install/includes/schema.sql index 21409c00..8b557324 100644 --- a/install/includes/schema.sql +++ b/install/includes/schema.sql @@ -2,12 +2,12 @@ SET @myaac_database_version = 43; CREATE TABLE `myaac_account_actions` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, `account_id` INT(11) NOT NULL, - `ip` INT(10) UNSIGNED NOT NULL DEFAULT 0, - `ipv6` BINARY(16) NOT NULL DEFAULT 0, + `ip` VARCHAR(45) NOT NULL DEFAULT '', `date` INT(11) NOT NULL DEFAULT 0, `action` VARCHAR(255) NOT NULL DEFAULT '', - KEY (`account_id`) + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; CREATE TABLE `myaac_admin_menu` diff --git a/system/libs/pot/OTS_Account.php b/system/libs/pot/OTS_Account.php index 07f31c82..0de49ccc 100644 --- a/system/libs/pot/OTS_Account.php +++ b/system/libs/pot/OTS_Account.php @@ -12,6 +12,8 @@ * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 */ +use MyAAC\Models\AccountAction; + /** * OTServ account abstraction. * @@ -1010,26 +1012,16 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable public function logAction($action) { - $ip = get_browser_real_ip(); - if(!str_contains($ip, ":")) { - $ipv6 = '0'; - } - else { - $ipv6 = $ip; - $ip = ''; - } - - return $this->db->exec('INSERT INTO `' . TABLE_PREFIX . 'account_actions` (`account_id`, `ip`, `ipv6`, `date`, `action`) VALUES (' . $this->db->quote($this->getId()).', ' . ($ip == '' ? '0' : $this->db->quote(ip2long($ip))) . ', (' . ($ipv6 == '0' ? $this->db->quote('') : $this->db->quote(inet_pton($ipv6))) . '), UNIX_TIMESTAMP(NOW()), ' . $this->db->quote($action).')'); + AccountAction::create([ + 'account_id' => $this->getId(), + 'ip' => get_browser_real_ip(), + 'date' => time(), + 'action' => $action, + ]); } - public function getActionsLog($limit1, $limit2) - { - $actions = array(); - - foreach($this->db->query('SELECT `ip`, `ipv6`, `date`, `action` FROM `' . TABLE_PREFIX . 'account_actions` WHERE `account_id` = ' . $this->data['id'] . ' ORDER by `date` DESC LIMIT ' . $limit1 . ', ' . $limit2 . '')->fetchAll() as $a) - $actions[] = array('ip' => $a['ip'], 'ipv6' => $a['ipv6'], 'date' => $a['date'], 'action' => $a['action']); - - return $actions; + public function getActionsLog($limit) { + return AccountAction::where('account_id', $this->data['id'])->orderByDesc('date')->limit($limit)->get()->toArray(); } /** * Returns players iterator. diff --git a/system/migrations/44.php b/system/migrations/44.php new file mode 100644 index 00000000..ea98d6f2 --- /dev/null +++ b/system/migrations/44.php @@ -0,0 +1,27 @@ +query("ALTER TABLE `myaac_account_actions` DROP KEY `account_id`;"); + $db->query("ALTER TABLE `myaac_account_actions` ADD COLUMN `id` INT(11) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`);"); + + $db->modifyColumn(TABLE_PREFIX . 'account_actions', 'ip', "VARCHAR(45) NOT NULL DEFAULT ''"); + $db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET_NTOA(`ip`) WHERE `ip` != '0';"); + $db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET6_NTOA(`ipv6`) WHERE `ip` = '0';"); + $db->dropColumn(TABLE_PREFIX . 'account_actions', 'ipv6'); +}; + +$down = function () use ($db) { + $db->query("ALTER TABLE `" . TABLE_PREFIX . "account_actions` DROP `id`;"); + $db->query("ALTER TABLE `" . TABLE_PREFIX . "account_actions` ADD KEY (`account_id`);"); + + $db->addColumn(TABLE_PREFIX . 'account_actions', 'ipv6', "BINARY(16) NOT NULL DEFAULT 0x00000000000000000000000000000000 AFTER ip"); + $db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ipv6` = INET6_ATON(ip) WHERE NOT IS_IPV4(`ip`);"); + $db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET_ATON(`ip`) WHERE IS_IPV4(`ip`);"); + $db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = 0 WHERE `ipv6` != 0x00000000000000000000000000000000;"); + $db->modifyColumn(TABLE_PREFIX . 'account_actions', 'ip', "INT(11) UNSIGNED NOT NULL DEFAULT 0;"); +}; diff --git a/system/pages/account/manage.php b/system/pages/account/manage.php index eff71c78..3b3dc288 100644 --- a/system/pages/account/manage.php +++ b/system/pages/account/manage.php @@ -85,12 +85,8 @@ if($email_new_time > 1) } } -$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'])); -} +$actions = $account_logged->getActionsLog(1000); -$players = array(); /** @var OTS_Players_List $account_players */ $account_players = $account_logged->getPlayersList(); $account_players->orderBy('id'); diff --git a/system/src/Models/AccountAction.php b/system/src/Models/AccountAction.php index d5cd531b..3ccdab84 100644 --- a/system/src/Models/AccountAction.php +++ b/system/src/Models/AccountAction.php @@ -9,6 +9,6 @@ class AccountAction extends Model { public $timestamps = false; - protected $fillable = ['account_id', 'ip', 'ipv6', 'date', 'action']; + protected $fillable = ['account_id', 'ip', 'date', 'action']; } From 4adb0758c567d8c6c136d949d23fc1e68bd13813 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 9 Mar 2025 21:26:24 +0100 Subject: [PATCH 003/148] Set version to 2.0-dev --- common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.php b/common.php index 99593401..66f3135b 100644 --- a/common.php +++ b/common.php @@ -26,7 +26,7 @@ if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); const MYAAC = true; -const MYAAC_VERSION = '1.2'; +const MYAAC_VERSION = '2.0-dev'; const DATABASE_VERSION = 44; const TABLE_PREFIX = 'myaac_'; define('START_TIME', microtime(true)); From cb6e9a6a883c3dd08ea2d2adb47ee3138da8df46 Mon Sep 17 00:00:00 2001 From: Slawomir Boczek Date: Sun, 9 Mar 2025 21:39:37 +0100 Subject: [PATCH 004/148] Feature/twig hooks filters (#258) * feat: Hooks filters * Cleanup --- system/functions.php | 22 ++++++++++++-------- system/src/Hook.php | 5 +++++ system/src/Hooks.php | 29 +++++++++++++++++++-------- system/src/Twig/EnvironmentBridge.php | 28 ++++++++++++++++++++++++++ system/src/global.php | 5 +++++ system/twig.php | 5 ++--- 6 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 system/src/Twig/EnvironmentBridge.php diff --git a/system/functions.php b/system/functions.php index 947dd5bd..5076b054 100644 --- a/system/functions.php +++ b/system/functions.php @@ -545,33 +545,39 @@ function template_header($is_admin = false): string */ function template_footer(): string { - global $views_counter; - $ret = ''; + $footer = []; + if(admin()) { - $ret .= generateLink(ADMIN_URL, 'Admin Panel', true); + $footer[] = generateLink(ADMIN_URL, 'Admin Panel', true); } if(setting('core.visitors_counter')) { global $visitors; $amount = $visitors->getAmountVisitors(); - $ret .= '
Currently there ' . ($amount > 1 ? 'are' : 'is') . ' ' . $amount . ' visitor' . ($amount > 1 ? 's' : '') . '.'; + $footer[] = 'Currently there ' . ($amount > 1 ? 'are' : 'is') . ' ' . $amount . ' visitor' . ($amount > 1 ? 's' : '') . '.'; } if(setting('core.views_counter')) { - $ret .= '
Page has been viewed ' . $views_counter . ' times.'; + global $views_counter; + $footer[] = 'Page has been viewed ' . $views_counter . ' times.'; } if(setting('core.footer_load_time')) { - $ret .= '
Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.'; + $footer[] = 'Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.'; } $settingFooter = setting('core.footer'); if(isset($settingFooter[0])) { - $ret .= '
' . $settingFooter; + $footer[] = '' . $settingFooter; } // please respect my work and help spreading the word, thanks! - return $ret . '
' . base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); + $footer[] = base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); + + global $hooks; + $footer = $hooks->triggerFilter(HOOK_FILTER_THEME_FOOTER, $footer); + + return implode('
', $footer); } function template_ga_code() diff --git a/system/src/Hook.php b/system/src/Hook.php index 73e378fd..9f4b7978 100644 --- a/system/src/Hook.php +++ b/system/src/Hook.php @@ -37,6 +37,11 @@ class Hook return !isset($ret) || $ret == 1 || $ret; } + public function executeFilter(...$args) { + return include BASE . $this->_file; + } + public function name() {return $this->_name;} public function type() {return $this->_type;} + public function file() {return $this->_file;} } diff --git a/system/src/Hooks.php b/system/src/Hooks.php index ee9f3b76..084d5e1a 100644 --- a/system/src/Hooks.php +++ b/system/src/Hooks.php @@ -4,22 +4,23 @@ namespace MyAAC; class Hooks { - private static $_hooks = array(); + private static array $_hooks = []; - public function register($hook, $type = '', $file = null) { + public function register($hook, $type = '', $file = null): void + { if(!($hook instanceof Hook)) $hook = new Hook($hook, $type, $file); self::$_hooks[$hook->type()][] = $hook; } - public function trigger($type, $params = array()) + public function trigger($type, $params = []): bool { $ret = true; - if(isset(self::$_hooks[$type])) - { + + if(isset(self::$_hooks[$type])) { foreach(self::$_hooks[$type] as $name => $hook) { - /** @var $hook Hook */ + /** @var Hook $hook */ if (!$hook->execute($params)) { $ret = false; } @@ -29,11 +30,23 @@ class Hooks return $ret; } - public function exist($type) { + public function triggerFilter($type, $args = []) + { + if(isset(self::$_hooks[$type])) { + foreach(self::$_hooks[$type] as $hook) { + /** @var Hook $hook */ + $args = $hook->executeFilter(...$args); + } + } + + return $args; + } + + public function exist($type): bool { return isset(self::$_hooks[$type]); } - public function load() + public function load(): void { foreach(Plugins::getHooks() as $hook) { $this->register($hook['name'], $hook['type'], $hook['file']); diff --git a/system/src/Twig/EnvironmentBridge.php b/system/src/Twig/EnvironmentBridge.php new file mode 100644 index 00000000..ab54bd25 --- /dev/null +++ b/system/src/Twig/EnvironmentBridge.php @@ -0,0 +1,28 @@ +triggerFilter(HOOK_FILTER_TWIG_DISPLAY, $context); + + parent::display($name, $context); + } + + public function render($name, array $context = []): string + { + global $hooks; + + $context['viewName'] = $name; + $context = $hooks->triggerFilter(HOOK_FILTER_TWIG_RENDER, $context); + + return parent::render($name, $context); + } +} diff --git a/system/src/global.php b/system/src/global.php index 61b887b5..ed9df203 100644 --- a/system/src/global.php +++ b/system/src/global.php @@ -97,6 +97,11 @@ define('HOOK_CACHE_CLEAR', ++$i); define('HOOK_INSTALL_FINISH', ++$i); define('HOOK_INSTALL_FINISH_END', ++$i); +// hook filters +define('HOOK_FILTER_TWIG_DISPLAY', ++$i); +define('HOOK_FILTER_TWIG_RENDER', ++$i); +define('HOOK_FILTER_THEME_FOOTER', ++$i); + const HOOK_FIRST = HOOK_INIT; define('HOOK_LAST', $i); diff --git a/system/twig.php b/system/twig.php index fc3125fe..f59230e3 100644 --- a/system/twig.php +++ b/system/twig.php @@ -9,8 +9,7 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -use MyAAC\CsrfToken; -use Twig\Environment as Twig_Environment; +use MyAAC\Twig\EnvironmentBridge as MyAAC_Twig_EnvironmentBridge; use Twig\Extension\DebugExtension as Twig_DebugExtension; use Twig\Loader\FilesystemLoader as Twig_FilesystemLoader; use Twig\TwigFilter; @@ -20,7 +19,7 @@ global $twig, $twig_loader; $dev_mode = (config('env') === 'dev'); $twig_loader = new Twig_FilesystemLoader(SYSTEM . 'templates'); -$twig = new Twig_Environment($twig_loader, array( +$twig = new MyAAC_Twig_EnvironmentBridge($twig_loader, array( 'cache' => CACHE . 'twig/', 'auto_reload' => $dev_mode, 'debug' => $dev_mode From cc26b5c74445076e13b886ed3b26ad62eac38418 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 10 Mar 2025 10:48:12 +0100 Subject: [PATCH 005/148] Fix: add possibility to remove all menu items --- admin/pages/menus.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/admin/pages/menus.php b/admin/pages/menus.php index e2608b0b..572be25e 100644 --- a/admin/pages/menus.php +++ b/admin/pages/menus.php @@ -27,11 +27,11 @@ $pluginThemes = Plugins::getThemes(); if (isset($_POST['template'])) { $template = $_POST['template']; - if (isset($_POST['menu'])) { - $post_menu = $_POST['menu']; - $post_menu_link = $_POST['menu_link']; - $post_menu_blank = $_POST['menu_blank']; - $post_menu_color = $_POST['menu_color']; + if (isset($_POST['save'])) { + $post_menu = $_POST['menu'] ?? []; + $post_menu_link = $_POST['menu_link'] ?? []; + $post_menu_blank = $_POST['menu_blank'] ?? []; + $post_menu_color = $_POST['menu_color'] ?? []; if (count($post_menu) != count($post_menu_link)) { echo 'Menu count is not equal menu links. Something went wrong when sending form.'; return; @@ -135,7 +135,7 @@ if (isset($_POST['template'])) {