Compare commits

..

68 Commits

Author SHA1 Message Date
slawkens
be7746d73d Release v0.8.25 2026-01-31 09:41:21 +01:00
slawkens
6715a83d03 Use apcu_clear_cache 2026-01-30 23:09:06 +01:00
slawkens
347ad40da1 Fix xdebug warnings in load_config_lua 2026-01-30 23:08:26 +01:00
slawkens
b0e88aea5e Use __DIR__ instead of template path 2026-01-30 23:07:43 +01:00
slawkens
54c1f5f486 Fix polls link 2026-01-30 23:07:05 +01:00
slawkens
364b140316 Cache::remember: $ttl = 0 means no cache 2026-01-30 23:04:32 +01:00
slawkens
f7cf2425d0 Twig: add cache variable 2026-01-30 23:04:06 +01:00
slawkens
207cf3a3c1 Fix submenu initialization for missing elements
Added a check in InitializeMenu to skip submenu items if their corresponding DOM element does not exist, preventing potential JavaScript errors.
2026-01-30 23:03:14 +01:00
slawkens
b190db3149 Fix online skulls display (Fix #320) 2026-01-30 23:02:07 +01:00
slawkens
fc3eaefc3f Fix exception when email cannot be send on create account 2026-01-30 23:00:41 +01:00
slawkens
fcf2b14921 Fix Menu div wrong tag/closing (#329) 2026-01-30 22:57:40 +01:00
slawkens
496499abbb Replace firstChild with firstElementChild (Thanks to @un000000) 2026-01-30 22:56:19 +01:00
slawkens
52a6256905 Prevent injection in $db->hasColumn 2026-01-30 22:54:09 +01:00
slawkens
92254e2671 Cache::remember -1 = infinite
Patching from 1.x
2026-01-30 22:52:55 +01:00
slawkens
7378905ae8 New configurable: hooks_debug
To view where hooks are located in .twig files
Patching from 1.x
2026-01-30 22:51:14 +01:00
slawkens
ab89ccaaa7 Allow links in error_box 2026-01-30 22:50:15 +01:00
slawkens
d37c2e7720 Merge branch '0.8' of https://github.com/slawkens/myaac into 0.8 2026-01-30 22:48:00 +01:00
slawkens
db83a6c5a9 Show if there is mysql error on import schema
Weird fix, don't know why it didn't worked with query()
Patching from 1.x
2026-01-30 22:47:54 +01:00
slawkens
9bfa5bc0ab Ignore only top-most Lua folder 2026-01-30 22:46:56 +01:00
slawkens
6a1e6b470c Don't display hidden news for admin - it's confusing
Patching from 1.x
2026-01-30 22:46:02 +01:00
slawkens
0c69e59104 Merge branch '0.8' of https://github.com/slawkens/myaac into 0.8 2026-01-30 22:41:08 +01:00
slawkens
2e50f8f81c Fix $status['uptimeReadable'], was totally wrong 2026-01-30 22:40:58 +01:00
slawkens
ed8b36f452 Server Status: Write to status-error.log if there is connection error
Patching from 1.x
2026-01-30 22:38:19 +01:00
slawkens
fdf2476501 Update .gitignore 2026-01-30 22:37:42 +01:00
slawkens
63e0ce696e Fixed [player/guild/house] bb code in forum 2026-01-30 22:35:34 +01:00
slawkens
44c917aefa Account character list: Add [ DELETED ] for deleted characters 2026-01-30 22:34:33 +01:00
slawkens
0a930e9acb Account Manage: Change last login to correct login time
Instead of just "now"
2026-01-30 22:32:44 +01:00
slawkens
c376fd93c6 Return 404 when signature player not found (patching from 1.x)
In most cases it was a request for a non existing file
2026-01-30 22:32:21 +01:00
slawkens
a76741c9da Remove html tags from email function (patched from 1.x)
Better score in tests
2026-01-30 22:29:44 +01:00
slawkens
63a99e0f92 Fix post_edit being an author, didn't worked 2026-01-30 22:24:09 +01:00
slawkens
ca114eb564 Start 0.8.25-dev 2025-06-03 23:53:57 +02:00
slawkens
5ca10f5439 Release v0.8.24 2025-06-03 17:44:49 +02:00
slawkens
75bfc2cdb0 Update CHANGELOG.md 2025-06-03 17:44:40 +02:00
slawkens
e542e8a7ce Two new hooks for pages loaded from database (custom pages)
HOOK_BEFORE_PAGE_CUSTOM,
HOOK_AFTER_PAGE_CUSTOM
2025-05-31 22:08:28 +02:00
slawkens
fcfe5b0dbd Do not allow access to tools/ folder after install 2025-05-29 11:27:32 +02:00
slawkens
149e10261b Add code to insert guild_ranks, incase guild trigger is missing 2025-05-28 23:09:24 +02:00
slawkens
5726c9fa94 Load hooks before twig, add new hooks: HOOK_TWIG + HOOK_INIT 2025-05-16 07:42:50 +02:00
slawkens
26b2c472cc Fix HOOK_LAST 2025-05-15 22:40:09 +02:00
slawkens
76440a37d0 New hooks for account characters change-comment page 2025-05-15 20:22:36 +02:00
slawkens
335b7b3112 Do not return -1 in case of freePremium, makes things harder 2025-05-14 09:22:22 +02:00
slawkens
ddc13b110e Start v0.8.24-dev 2025-04-22 15:56:53 +02:00
slawkens
02918684fd Merge branch '0.8' of https://github.com/slawkens/myaac into 0.8 2025-04-22 14:20:45 +02:00
slawkens
5bc70beae6 Release v.0.8.23 2025-04-22 14:20:34 +02:00
slawkens
6418b782a3 Update buttons.base.html.twig 2025-04-22 14:15:37 +02:00
slawkens
687ccc4559 README.md corrections
* Add links to docs & faq
* add info about 2.x dev version
* fix some grammar typos
2025-04-22 14:13:12 +02:00
slawkens
29a198bfce Display more info when error parsing config.lua value 2025-04-22 14:07:46 +02:00
slawkens
06a235237d Plugin name is required, version is optional 2025-04-22 14:05:10 +02:00
slawkens
9c15c2fa68 Add $db->hasTableAndColumns($table, $columns), credits to @opentibiabr Team 2025-04-22 14:03:25 +02:00
slawkens
1708a48186 Change logout button color 2025-04-22 13:46:28 +02:00
slawkens
68170e42cd Fix headline.php: change image format to .png cause of black background 2025-04-22 13:45:35 +02:00
slawkens
4b9a7eaf85 Add noSubmit option to buttons.base 2025-04-22 13:44:45 +02:00
slawkens
01dda11a2f Merge branch '0.8' of https://github.com/slawkens/myaac into 0.8 2025-03-30 07:16:23 +02:00
slawkens
1d33750e85 Update .gitignore 2025-03-30 07:16:15 +02:00
slawkens
89f537c8c2 getPremDays: returns -1 if freePremium 2025-03-15 23:00:01 +01:00
slawkens
727da8b0cc Fix long title on headline.php 2025-02-12 16:19:07 +01:00
slawkens
5b6f29741d Update README.md 2025-01-27 22:59:02 +01:00
slawkens
e13bd879db Fix branch 2025-01-27 22:04:54 +01:00
slawkens
f696f74a06 Release v0.8.22 2025-01-27 22:04:17 +01:00
slawkens
3b18e400c0 Update CHANGELOG.md 2025-01-27 22:03:55 +01:00
slawkens
d1c72b3240 Update exception.php 2025-01-27 21:45:59 +01:00
slawkens
7abc3c7833 Exception: better style - better showing of longer exceptions 2025-01-27 21:30:39 +01:00
slawkens
c0c4fe33e9 Secure template.php of direct access 2025-01-27 21:30:16 +01:00
slawkens
05827b7861 Typo 2025-01-27 21:29:57 +01:00
slawkens
c304a9ab43 Better exception handler, which clears the whole html output, so the message is better visible 2025-01-27 21:29:43 +01:00
slawkens
d390ea325e Fix exception $account->getName 2025-01-18 19:12:08 +01:00
slawkens
37ba9c7366 All $cache->set calls should have $ttl 2025-01-17 22:55:35 +01:00
slawkens
7c3ebf70fa Optimize $player->isOnline() function, thanks @gesior 2025-01-17 22:52:00 +01:00
slawkens
eda773cb55 Start v0.8.22-dev 2025-01-09 20:26:17 +01:00
47 changed files with 371 additions and 166 deletions

2
.gitignore vendored
View File

@@ -4,6 +4,7 @@ Thumbs.db
# #
/.htaccess /.htaccess
/lua
# composer # composer
composer.lock composer.lock
@@ -23,6 +24,7 @@ releases
tmp tmp
config.local.php config.local.php
config2.local.php
# all custom templates # all custom templates
templates/* templates/*

View File

@@ -1,5 +1,77 @@
# Changelog # Changelog
## [0.8.25 - 31.01.2026]
### Added
* New configurable: hooks_debug To view where hooks are located in .twig files (https://github.com/slawkens/myaac/commit/7378905ae8cf033e36a27461b5ccffeed042dacd)
* Twig: add global cache variable (https://github.com/slawkens/myaac/commit/f7cf2425d0e970356c477a96b20c4c31837430e7)
### Changed
* Server Status: Write to status-error.log if there is a connection error (https://github.com/slawkens/myaac/commit/ed8b36f4528668f29ea1a2adc7234ec249fa031b)
* Remove HTML tags from the email function (patched from 1.x) Better score in tests (https://github.com/slawkens/myaac/commit/a76741c9dae97584cbc6736bbc6404d1e59f856d)
* Return 404 when the signature player is not found (patching from 1.x) - In most cases it was a request for a non existing file (https://github.com/slawkens/myaac/commit/c376fd93c6fbf3f9c4bd79bae8875720464c28fa)
* Don't display hidden news for admin - it's confusing (https://github.com/slawkens/myaac/commit/6a1e6b470ca05e5a43d9986865f8938e92951e45)
* Allow links in error_box.html.twig (https://github.com/slawkens/myaac/commit/ab89ccaaa722f4c1acdfb0302c3cddb2ed343e61)
* Account character list: Add [ DELETED ] for deleted characters (https://github.com/slawkens/myaac/commit/44c917aefa20ad8dcba7a47ccab50635e33f2e53)
### Fixed
* Fix $status['uptimeReadable'], was totally wrong (https://github.com/slawkens/myaac/commit/2e50f8f81cfd1bfe763c6ed8e329c89b69604865)
* Fixed [player/guild/house] bb code in forum (https://github.com/slawkens/myaac/commit/63e0ce696e078fb0b020c45a777d1c6571ac1ae3)
* Fix post_edit being an author, didn't worked (https://github.com/slawkens/myaac/commit/63a99e0f92214bc5fd60b867f80bb451af29da79)
* Show if there is a mysql error on import schema (https://github.com/slawkens/myaac/commit/db83a6c5a92a56ef47afd148ab1621759211e4b9)
* Prevent injection in $db->hasColumn (https://github.com/slawkens/myaac/commit/52a62569056582da2862ffcfbb5c68bf7f25c4df)
* Account Create: Fix the exception when email cannot be sent (https://github.com/slawkens/myaac/commit/fc3eaefc3f84cf4e977d4f3cc8b2fbf96555cc2a)
* Online: Fix online skulls display (Fix #320) (https://github.com/slawkens/myaac/commit/b190db3149fca54217ca507e8502096d40813d44)
* Tibiacom template: Fix submenu initialization for missing elements (https://github.com/slawkens/myaac/commit/207cf3a3c1b6f3ed18e3850e2240c15e6ca9e51c)
* Account Manage: Change the last login to the correct login time - Instead of just "now" (https://github.com/slawkens/myaac/commit/0a930e9acb7f3adc708307cb2d4e1f57d9aa08ad)
* Fix Menu div wrong tag/closing (#329) (https://github.com/slawkens/myaac/commit/fcf2b1492147c03ee3aa825284e3c974f6c2f66e)
* tibiacom template: Fix polls link in the widget (https://github.com/slawkens/myaac/commit/54c1f5f486872efad418402b439a1a2e09abaa5f)
* Fix xdebug warnings in load_config_lua (https://github.com/slawkens/myaac/commit/347ad40da10afa39b6c8cabd73937a21a3b629f6)
### Internal
* Replace firstChild with firstElementChild (Thanks to @un000000) (https://github.com/slawkens/myaac/commit/496499abbb54da738bf9190cf9cf962a5e3ce4ba)
* Cache::remember -1 = infinite (https://github.com/slawkens/myaac/commit/92254e2671ec6f37e936f48f07ec645c7c595a5a)
* Cache::remember: $ttl = 0 means no cache (https://github.com/slawkens/myaac/commit/364b140316346c3f8720caefb709fb1c412369ad)
* Use apcu_clear_cache to clear cache (https://github.com/slawkens/myaac/commit/6715a83d03851bd191d74f431031495df27ea8f9)
## [0.8.24 - 03.06.2025]
### Added
* Add code to insert guild_ranks on guild create, in case the guild trigger is missing (https://github.com/slawkens/myaac/commit/149e10261befab22a38246bd792e2e4d1c42ef1e)
* Two new hooks for pages loaded from a database (custom pages): HOOK_BEFORE_PAGE_CUSTOM + HOOK_AFTER_PAGE_CUSTOM (https://github.com/slawkens/myaac/commit/e542e8a7cebad2d4bd6984c62cd6f385363ba9eb)
* Load hooks before twig, add new hooks: HOOK_TWIG + HOOK_INIT (https://github.com/slawkens/myaac/commit/5726c9fa94e6f5a198917f6bda9014c0cbb141fb)
* New hooks for account characters change-comment page (https://github.com/slawkens/myaac/commit/76440a37d009b845db9157312f2807774e15de14)
### Fixed
* Do not allow access to tools/ folder after install (https://github.com/slawkens/myaac/commit/fcfe5b0dbd33fd628031fe60ae3f2acc5164eed8)
### Changed
* Do not return -1 in case of freePremium, makes things harder (https://github.com/slawkens/myaac/commit/335b7b3112b3f2ed87b46c5dbc5db70a33bbd953)
## [0.8.23 - 22.04.2025]
### Added
* Add db->hasTableAndColumns(table, columns), credits to @opentibiabr Team (https://github.com/slawkens/myaac/commit/9c15c2fa6848d966457972fce0d04347ecbd4f2c)
* Add noSubmit option to buttons.base (https://github.com/slawkens/myaac/commit/4b9a7eaf859f9d3dbc90deb03564fcddde2f90d3)
### Changed
* Display more info when error parsing config.lua value (https://github.com/slawkens/myaac/commit/29a198bfcedeb5d22e0d34c5c53098142acdf477)
* Change logout button color to red in tibiacom template (https://github.com/slawkens/myaac/commit/1708a48186294e3eea0a79344fdf56ba93327c6d)
### Fixed
* Fix headline.php: change image format to .png cause of black background (https://github.com/slawkens/myaac/commit/68170e42cd8fac43c55654ba595f09425618f26e)
* Fix long title on headline.php (https://github.com/slawkens/myaac/commit/727da8b0cc968d0cafc502dd9c8cebf17e46bf76)
* getPremDays: returns -1 if freePremium (https://github.com/slawkens/myaac/commit/89f537c8c2646c748a14ee46539a6103fda88ec1)
## [0.8.22 - 27.01.2025]
### Changed
* Better exception handler, which clears the whole html output, so the message is better visible + better style (https://github.com/slawkens/myaac/commit/c304a9ab43bf0bda41907db3e6f65293350640a2 + https://github.com/slawkens/myaac/commit/7abc3c78334d44fb64684b26d8a305d0fe676caa)
* Optimize $player->isOnline() function, thanks @gesior (https://github.com/slawkens/myaac/commit/7c3ebf70fa4751af986be7b46ee3530d4875271e)
* All $cache->set calls should have $ttl (https://github.com/slawkens/myaac/commit/37ba9c7366139778d09d1316d7cb49a255165778)
### Fixed
* exception in lostaccount.php - $account->getName() (https://github.com/slawkens/myaac/commit/d390ea325e2dbfd87a830cfe40991f58e07a87a1)
## [0.8.21 - 09.01.2025] ## [0.8.21 - 09.01.2025]
### Added ### Added

View File

@@ -12,11 +12,18 @@ Official website: https://my-aac.org
| Version | Status | Branch | Requirements | | Version | Status | Branch | Requirements |
|:--------|:-----------------------|:--------|:---------------| |:--------|:-----------------------|:--------|:---------------|
| **1.x** | **Active development** | develop | **PHP >= 8.1** | | 2.x | Experimental features | develop | PHP >= 8.1 |
| **1.x** | **Active development** | main | **PHP >= 8.1** |
| 0.9.x | Not developed anymore | 0.9 | PHP >= 7.2.5 | | 0.9.x | Not developed anymore | 0.9 | PHP >= 7.2.5 |
| 0.8.x | Active support | master | PHP >= 7.2.5 | | 0.8.x | Active support | 0.8 | PHP >= 7.2.5 |
| 0.7.x | End Of Life | 0.7 | PHP >= 5.3.3 | | 0.7.x | End Of Life | 0.7 | PHP >= 5.3.3 |
The recommended version to install is 1.x, which can be found at releases page - [https://github.com/slawkens/myaac/releases](https://github.com/slawkens/myaac/releases).
### Documentation
* [docs.my-aac.org](https://docs.my-aac.org)
* [my-aac.org - FAQ](https://my-aac.org/faqs/)
### Requirements ### Requirements
- MySQL database - MySQL database
@@ -47,23 +54,23 @@ Official website: https://my-aac.org
### Configuration ### Configuration
Check *config.php* to get more informations. (Notice: MyAAC 1.0+ doesn't use config.php anymore, it has been moved to Admin Panel - Settings page). Check *config.php* to get more information. (Notice: MyAAC 1.0+ doesn't use config.php anymore, it has been moved to Admin Panel - Settings page).
Use *config.local.php* for your local configuration changes. Use *config.local.php* for your local configuration changes.
### Branches ### Branches
This repository follows the Git Flow Workflow. This repository follows the Git Flow Workflow.
Cheatsheet: [Git-Flow-Cheetsheet](https://danielkummer.github.io/git-flow-cheatsheet) Cheatsheet: [Git-Flow-Cheatsheet](https://danielkummer.github.io/git-flow-cheatsheet)
That means, we use: That means, we use:
* master branch, for current stable release * main branch, for current stable release
* develop branch, for development version (next release) * develop branch, for development version (next release)
* feature branches, for features etc. * feature branches, for features etc.
### Known Problems ### Known Problems
- Some compatibility issues with some exotical distibutions. - Some compatibility issues with some exotic distributions.
### Contributing ### Contributing
@@ -77,7 +84,7 @@ Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our w
### Other Notes ### Other Notes
If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org If you have a great idea or want to contribute to the project - visit our website at https://www.my-aac.org
## Project supported by JetBrains ## Project supported by JetBrains

View File

@@ -34,11 +34,6 @@ if(config('env') === 'dev') {
error_reporting(E_ALL); error_reporting(E_ALL);
} }
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
require SYSTEM . 'status.php'; require SYSTEM . 'status.php';
require SYSTEM . 'login.php'; require SYSTEM . 'login.php';
require SYSTEM . 'migrate.php'; require SYSTEM . 'migrate.php';

View File

@@ -26,7 +26,7 @@
if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.'); if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.');
define('MYAAC', true); define('MYAAC', true);
define('MYAAC_VERSION', '0.8.21'); define('MYAAC_VERSION', '0.8.25');
define('DATABASE_VERSION', 33); define('DATABASE_VERSION', 33);
define('TABLE_PREFIX', 'myaac_'); define('TABLE_PREFIX', 'myaac_');
define('START_TIME', microtime(true)); define('START_TIME', microtime(true));
@@ -100,7 +100,7 @@ for($i = 1; $i < $size; $i++)
$basedir = str_replace(array('/admin', '/install', '/tools'), '', $basedir); $basedir = str_replace(array('/admin', '/install', '/tools'), '', $basedir);
define('BASE_DIR', $basedir); define('BASE_DIR', $basedir);
if (file_exists(BASE . 'config.local.php') && !defined('MYAAC_INSTALL')) { if (file_exists(BASE . 'config.local.php')) {
require BASE . 'config.local.php'; require BASE . 'config.local.php';
} }

View File

@@ -24,6 +24,7 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
ob_start();
require_once 'common.php'; require_once 'common.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';
@@ -192,10 +193,6 @@ define('PAGE', $page);
$template_place_holders = array(); $template_place_holders = array();
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
require_once SYSTEM . 'login.php'; require_once SYSTEM . 'login.php';
require_once SYSTEM . 'status.php'; require_once SYSTEM . 'status.php';
@@ -221,7 +218,7 @@ if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_stat
if(fetchDatabaseConfig('last_usage_report', $value)) { if(fetchDatabaseConfig('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time; $should_report = time() > (int)$value + $report_time;
if($cache->enabled()) { if($cache->enabled()) {
$cache->set('last_usage_report', $value); $cache->set('last_usage_report', $value, 60 * 60);
} }
} }
else { else {
@@ -236,7 +233,7 @@ if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_stat
updateDatabaseConfig('last_usage_report', time()); updateDatabaseConfig('last_usage_report', time());
if($cache->enabled()) { if($cache->enabled()) {
$cache->set('last_usage_report', time()); $cache->set('last_usage_report', time(), 60 * 60);
} }
} }
} }
@@ -337,7 +334,7 @@ if($load_it)
$success = false; $success = false;
$tmp_content = getCustomPage($page, $success); $tmp_content = getCustomPage($page, $success);
if($success) { if($success && $hooks->trigger(HOOK_BEFORE_PAGE_CUSTOM)) {
$content .= $tmp_content; $content .= $tmp_content;
if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) { if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) {
$pageInfo = getCustomPageInfo($page); $pageInfo = getCustomPageInfo($page);
@@ -345,6 +342,8 @@ if($load_it)
'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0') 'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0')
)) . $content; )) . $content;
} }
$hooks->trigger(HOOK_AFTER_PAGE_CUSTOM);
} else { } else {
$file = TEMPLATES . "$template_name/pages/$page.php"; $file = TEMPLATES . "$template_name/pages/$page.php";
if(!@file_exists($file) || preg_match('/[^A-z0-9_\-]/', $page)) { if(!@file_exists($file) || preg_match('/[^A-z0-9_\-]/', $page)) {

View File

@@ -13,9 +13,6 @@ require BASE . 'install/includes/functions.php';
require BASE . 'install/includes/locale.php'; require BASE . 'install/includes/locale.php';
require SYSTEM . 'clients.conf.php'; require SYSTEM . 'clients.conf.php';
if(file_exists(BASE . 'config.local.php'))
require BASE . 'config.local.php';
// ignore undefined index from Twig autoloader // ignore undefined index from Twig autoloader
$config['env'] = 'prod'; $config['env'] = 'prod';

View File

@@ -139,14 +139,5 @@ else {
} }
$_SESSION['installed'] = true; $_SESSION['installed'] = true;
} }
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') !== false)
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
} }
} }

View File

@@ -1,3 +1,4 @@
<?php defined('MYAAC') or die('Direct access not allowed!'); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>"> <html xmlns="http://www.w3.org/1999/xhtml" dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>">
<head> <head>

View File

@@ -7,6 +7,11 @@ require SYSTEM . 'functions.php';
require BASE . 'install/includes/functions.php'; require BASE . 'install/includes/functions.php';
require BASE . 'install/includes/locale.php'; require BASE . 'install/includes/locale.php';
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
return;
}
$error = false; $error = false;
require BASE . 'install/includes/config.php'; require BASE . 'install/includes/config.php';
@@ -32,7 +37,7 @@ if($db->hasTable(TABLE_PREFIX . 'account_actions')) {
else { else {
// import schema // import schema
try { try {
$db->query(file_get_contents(BASE . 'install/includes/schema.sql')); $db->exec(file_get_contents(BASE . 'install/includes/schema.sql'));
$locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']); $locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']);
success($locale['step_database_success_schema']); success($locale['step_database_success_schema']);

View File

@@ -97,6 +97,16 @@ require_once SYSTEM . 'migrations/22.php';
require_once SYSTEM . 'migrations/27.php'; require_once SYSTEM . 'migrations/27.php';
require_once SYSTEM . 'migrations/30.php'; require_once SYSTEM . 'migrations/30.php';
// cleanup
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') !== false)
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
$locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']); $locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(str_replace('tools/', '', BASE_URL), $locale['step_finish_homepage'], true), $locale['step_finish_desc']); $locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(str_replace('tools/', '', BASE_URL), $locale['step_finish_homepage'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$LINK$', generateLink('https://my-aac.org', 'https://my-aac.org', true), $locale['step_finish_desc']); $locale['step_finish_desc'] = str_replace('$LINK$', generateLink('https://my-aac.org', 'https://my-aac.org', true), $locale['step_finish_desc']);

View File

@@ -22,7 +22,7 @@ if [ $1 = "prepare" ]; then
mkdir -p tmp mkdir -p tmp
# get myaac from git archive # get myaac from git archive
git archive --format zip --output tmp/myaac.zip master git archive --format zip --output tmp/myaac.zip 0.8
cd tmp/ || exit cd tmp/ || exit

View File

@@ -8,7 +8,6 @@ if(PHP_SAPI !== 'cli') {
require_once __DIR__ . '/../../common.php'; require_once __DIR__ . '/../../common.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php'; require_once SYSTEM . 'init.php';
require_once SYSTEM . 'hooks.php';
if($argc !== 2) { if($argc !== 2) {
echo 'This command expects one parameter: zip file name (plugin)' . PHP_EOL; echo 'This command expects one parameter: zip file name (plugin)' . PHP_EOL;

View File

@@ -37,12 +37,14 @@ function exception_handler($exception) {
} }
// display beautiful error message // display beautiful error message
// the file is .twig.html, but its not really parsed by Twig // the file is .twig.html, but it's not really parsed by Twig
// we just replace some values manually // we just replace some values manually
// cause in case Twig throws exception, we can show it too // cause in case Twig throws exception, we can show it too
$content = file_get_contents($template_file); $content = file_get_contents($template_file);
$content = str_replace(array('{{ BASE_URL }}', '{{ exceptionClass }}', '{{ message }}', '{{ backtrace }}', '{{ powered_by }}'), array(BASE_URL, get_class($exception), $message, $backtrace_formatted, base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=')), $content); $content = str_replace(array('{{ BASE_URL }}', '{{ exceptionClass }}', '{{ message }}', '{{ backtrace }}', '{{ powered_by }}'), array(BASE_URL, get_class($exception), $message, $backtrace_formatted, base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=')), $content);
@ob_clean();
echo $content; echo $content;
} }

View File

@@ -823,11 +823,11 @@ function getWorldName($id)
* *
* @param string $to Recipient email address. * @param string $to Recipient email address.
* @param string $subject Subject of the message. * @param string $subject Subject of the message.
* @param string $body Message body in html format. * @param string $body Message body in HTML format.
* @param string $altBody Alternative message body, plain text. * @param string $altBody Alternative message body, plain text.
* @return bool PHPMailer status returned (success/failure). * @return bool PHPMailer status returned (success/failure).
*/ */
function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true) function _mail(string $to, string $subject, string $body, string $altBody = ''): bool
{ {
/** @var PHPMailer $mailer */ /** @var PHPMailer $mailer */
global $mailer, $config; global $mailer, $config;
@@ -841,15 +841,6 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->clearAllRecipients(); $mailer->clearAllRecipients();
} }
$signature_html = '';
if(isset($config['mail_signature']['html']))
$signature_html = $config['mail_signature']['html'];
if($add_html_tags && isset($body[0]))
$tmp_body = '<html><head></head><body>' . $body . '<br/><br/>' . $signature_html . '</body></html>';
else
$tmp_body = $body . '<br/><br/>' . $signature_html;
if($config['smtp_enabled']) if($config['smtp_enabled'])
{ {
$mailer->isSMTP(); $mailer->isSMTP();
@@ -864,6 +855,12 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->isMail(); $mailer->isMail();
} }
if(isset($config['mail_signature']['html'])) {
$signature_html = $config['mail_signature']['html'];
}
$tmp_body = $body . '<br/><br/>' . $signature_html;
$mailer->isHTML(isset($body[0]) > 0); $mailer->isHTML(isset($body[0]) > 0);
$mailer->From = $config['mail_address']; $mailer->From = $config['mail_address'];
$mailer->Sender = $config['mail_address']; $mailer->Sender = $config['mail_address'];
@@ -934,11 +931,12 @@ function load_config_lua($filename)
foreach($lines as $ln => $line) foreach($lines as $ln => $line)
{ {
$line = trim($line); $line = trim($line);
if(@$line[0] === '{' || @$line[0] === '}') { if(isset($line[0]) && ($line[0] === '{' || $line[0] === '}')) {
// arrays are not supported yet // arrays are not supported yet
// just ignore the error // just ignore the error
continue; continue;
} }
$tmp_exp = explode('=', $line, 2); $tmp_exp = explode('=', $line, 2);
if(strpos($line, 'dofile') !== false) if(strpos($line, 'dofile') !== false)
{ {
@@ -972,12 +970,19 @@ function load_config_lua($filename)
} }
else 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); $value = str_replace($tmp_key, $tmp_value, $value);
$ret = @eval("return $value;"); }
if((string) $ret == '' && trim($value) !== '""') // = parser error
{ try {
throw new RuntimeException('ERROR: Loading config.lua file. Line <b>' . ($ln + 1) . '</b> of LUA config file is not valid [key: <b>' . $key . '</b>]'); $ret = eval("return $value;");
}
catch (Throwable $e) {
throw new RuntimeException('ERROR: Loading config.lua file. Line: ' . ($ln + 1) . ' - Unable to parse value "' . $value . '" - ' . $e->getMessage());
}
if((string) $ret == '' && trim($value) !== '""') {
throw new RuntimeException('ERROR: Loading config.lua file. Line ' . ($ln + 1) . ' is not valid [key: ' . $key . ']');
} }
$result[$key] = $ret; $result[$key] = $ret;
} }
@@ -1170,6 +1175,10 @@ function clearCache()
if ($cache->fetch('last_kills', $tmp)) { if ($cache->fetch('last_kills', $tmp)) {
$cache->delete('last_kills'); $cache->delete('last_kills');
} }
if (function_exists('apcu_clear_cache')) {
apcu_clear_cache();
}
} }
deleteDirectory(CACHE . 'signatures', ['index.html'], true); deleteDirectory(CACHE . 'signatures', ['index.html'], true);
@@ -1331,6 +1340,43 @@ function getDatabasePages($withHidden = false): array
return $ret; return $ret;
} }
function getStatusUptimeReadable(int $uptime): string
{
$fullMinute = 60;
$fullHour = (60 * $fullMinute);
$fullDay = (24 * $fullHour);
$fullMonth = (30 * $fullDay);
$fullYear = (365 * $fullDay);
// years
$years = floor($uptime / $fullYear);
$y = ($years > 1 ? "$years years, " : ($years == 1 ? 'year, ' : ''));
$uptime -= $years * $fullYear;
// months
$months = floor($uptime / $fullMonth);
$m = ($months > 1 ? "$months months, " : ($months == 1 ? 'month, ' : ''));
$uptime -= $months * $fullMonth;
// days
$days = floor($uptime / $fullDay);
$d = ($days > 1 ? "$days days, " : ($days == 1 ? 'day, ' : ''));
$uptime -= $days * $fullDay;
// hours
$hours = floor($uptime / $fullHour);
$uptime -= $hours * $fullHour;
// minutes
$min = floor($uptime / $fullMinute);
return "{$y}{$m}{$d}{$hours}h {$min}m";
}
// validator functions // validator functions
require_once LIBS . 'validator.php'; require_once LIBS . 'validator.php';
require_once SYSTEM . 'compat/base.php'; require_once SYSTEM . 'compat/base.php';

View File

@@ -10,9 +10,12 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$i = 0; $i = 0;
define('HOOK_INIT', ++$i);
define('HOOK_STARTUP', ++$i); define('HOOK_STARTUP', ++$i);
define('HOOK_BEFORE_PAGE', ++$i); define('HOOK_BEFORE_PAGE', ++$i);
define('HOOK_BEFORE_PAGE_CUSTOM', ++$i);
define('HOOK_AFTER_PAGE', ++$i); define('HOOK_AFTER_PAGE', ++$i);
define('HOOK_AFTER_PAGE_CUSTOM', ++$i);
define('HOOK_FINISH', ++$i); define('HOOK_FINISH', ++$i);
define('HOOK_TIBIACOM_ARTICLE', ++$i); define('HOOK_TIBIACOM_ARTICLE', ++$i);
define('HOOK_TIBIACOM_BORDER_3', ++$i); define('HOOK_TIBIACOM_BORDER_3', ++$i);
@@ -30,6 +33,10 @@ define('HOOK_CHARACTERS_AFTER_CHARACTERS', ++$i);
define('HOOK_LOGIN', ++$i); define('HOOK_LOGIN', ++$i);
define('HOOK_LOGIN_ATTEMPT', ++$i); define('HOOK_LOGIN_ATTEMPT', ++$i);
define('HOOK_LOGOUT', ++$i); define('HOOK_LOGOUT', ++$i);
define('HOOK_ACCOUNT_CHARACTERS_CHANGE_COMMENT_AFTER_SUCCESS', ++$i);
define('HOOK_ACCOUNT_CHARACTERS_CHANGE_COMMENT_AFTER_NAME', ++$i);
define('HOOK_ACCOUNT_CHARACTERS_CHANGE_COMMENT_AFTER_HIDE_ACCOUNT', ++$i);
define('HOOK_ACCOUNT_CHARACTERS_CHANGE_COMMENT_AFTER_COMMENT', ++$i);
define('HOOK_ACCOUNT_CREATE_BEFORE_FORM', ++$i); define('HOOK_ACCOUNT_CREATE_BEFORE_FORM', ++$i);
define('HOOK_ACCOUNT_CREATE_BEFORE_BOXES', ++$i); define('HOOK_ACCOUNT_CREATE_BEFORE_BOXES', ++$i);
define('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1', ++$i); define('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1', ++$i);
@@ -57,8 +64,9 @@ define('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS', ++$i);
define('HOOK_ACCOUNT_MANAGE_BEFORE_CHARACTERS', ++$i); define('HOOK_ACCOUNT_MANAGE_BEFORE_CHARACTERS', ++$i);
define('HOOK_EMAIL_CONFIRMED', ++$i); define('HOOK_EMAIL_CONFIRMED', ++$i);
define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i); define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i);
define('HOOK_TWIG', ++$i);
define('HOOK_FIRST', HOOK_STARTUP); define('HOOK_FIRST', HOOK_STARTUP);
define('HOOK_LAST', HOOK_EMAIL_CONFIRMED); define('HOOK_LAST', $i);
require_once LIBS . 'plugins.php'; require_once LIBS . 'plugins.php';
require_once LIBS . 'src/Plugins.php'; require_once LIBS . 'src/Plugins.php';

View File

@@ -74,8 +74,8 @@ if($config_lua_reload) {
// cache config // cache config
if($cache->enabled()) { if($cache->enabled()) {
$cache->set('config_lua', serialize($config['lua']), 120); $cache->set('config_lua', serialize($config['lua']), 2 * 60);
$cache->set('server_path', $config['server_path']); $cache->set('server_path', $config['server_path'], 10 * 60);
} }
} }
unset($tmp); unset($tmp);
@@ -124,6 +124,12 @@ require_once SYSTEM . 'libs/pot/OTS.php';
$ots = POT::getInstance(); $ots = POT::getInstance();
require_once SYSTEM . 'database.php'; require_once SYSTEM . 'database.php';
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
$hooks->trigger(HOOK_INIT);
// twig // twig
require_once SYSTEM . 'twig.php'; require_once SYSTEM . 'twig.php';

View File

@@ -114,7 +114,7 @@ class Cache
public static function remember($key, $ttl, $callback) public static function remember($key, $ttl, $callback)
{ {
$cache = self::getInstance(); $cache = self::getInstance();
if(!$cache->enabled()) { if(!$cache->enabled() || $ttl == 0) {
return $callback(); return $callback();
} }
@@ -123,6 +123,11 @@ class Cache
return unserialize($value); return unserialize($value);
} }
// -1 for infinite cache
if ($ttl == -1) {
$ttl = 10 * 365 * 24 * 60 * 60; // 10 years should be enough
}
$value = $callback(); $value = $callback();
$cache->set($key, serialize($value), $ttl); $cache->set($key, serialize($value), $ttl);
return $value; return $value;

View File

@@ -230,6 +230,7 @@ class Forum
if(!is_int($rows / 2)) { $bgcolor = 'ABED25'; } else { $bgcolor = '23ED25'; } $rows++; if(!is_int($rows / 2)) { $bgcolor = 'ABED25'; } else { $bgcolor = '23ED25'; } $rows++;
$text = str_ireplace('[code]'.$code.'[/code]', '<i>Code:</i><br /><table cellpadding="0" style="background-color: #'.$bgcolor.'; width: 480px; border-style: dotted; border-color: #CCCCCC; border-width: 2px"><tr><td>'.$code.'</td></tr></table>', $text); $text = str_ireplace('[code]'.$code.'[/code]', '<i>Code:</i><br /><table cellpadding="0" style="background-color: #'.$bgcolor.'; width: 480px; border-style: dotted; border-color: #CCCCCC; border-width: 2px"><tr><td>'.$code.'</td></tr></table>', $text);
} }
$rows = 0; $rows = 0;
while(stripos($text, '[quote]') !== false && stripos($text, '[/quote]') !== false ) while(stripos($text, '[quote]') !== false && stripos($text, '[/quote]') !== false )
{ {
@@ -237,11 +238,31 @@ class Forum
if(!is_int($rows / 2)) { $bgcolor = 'AAAAAA'; } else { $bgcolor = 'CCCCCC'; } $rows++; if(!is_int($rows / 2)) { $bgcolor = 'AAAAAA'; } else { $bgcolor = 'CCCCCC'; } $rows++;
$text = str_ireplace('[quote]'.$quote.'[/quote]', '<table cellpadding="0" style="background-color: #'.$bgcolor.'; width: 480px; border-style: dotted; border-color: #007900; border-width: 2px"><tr><td>'.$quote.'</td></tr></table>', $text); $text = str_ireplace('[quote]'.$quote.'[/quote]', '<table cellpadding="0" style="background-color: #'.$bgcolor.'; width: 480px; border-style: dotted; border-color: #007900; border-width: 2px"><tr><td>'.$quote.'</td></tr></table>', $text);
} }
$rows = 0;
while(stripos($text, '[url]') !== false && stripos($text, '[/url]') !== false ) $tagsToParse = [
'url' => function ($str) {
return '<a href="'.$str.'" target="_blank">'.$str.'</a>';
},
'player' => function ($str) {
return generateLink(getPlayerLink($str, false), $str, true);
},
'guild' => function ($str) {
return generateLink(getGuildLink($str, false), $str, true);
},
'house' => function ($str) {
return generateLink(getHouseLink($str, false), $str, true);
}
];
foreach ($tagsToParse as $tag => $callback) {
while(stripos($text, "[$tag]") !== false && stripos($text, "[/$tag]") !== false
&& stripos($text, "[$tag]") < stripos($text, "[/$tag]"))
{ {
$url = substr($text, stripos($text, '[url]')+5, stripos($text, '[/url]') - stripos($text, '[url]') - 5); $length = strlen("[$tag]");
$text = str_ireplace('[url]'.$url.'[/url]', '<a href="'.$url.'" target="_blank">'.$url.'</a>', $text); $substr = substr($text, stripos($text, "[$tag]") + $length, stripos($text, "[/$tag]") - stripos($text, "[$tag]") - $length);
$text = str_ireplace('[' . $tag . ']' . $substr . '[/' . $tag . ']', $callback($substr), $text);
}
} }
$xhtml = false; $xhtml = false;
@@ -251,9 +272,6 @@ class Forum
'#\[u\](.*?)\[/u\]#si' => ($xhtml ? '<span style="text-decoration: underline;">\\1</span>' : '<u>\\1</u>'), '#\[u\](.*?)\[/u\]#si' => ($xhtml ? '<span style="text-decoration: underline;">\\1</span>' : '<u>\\1</u>'),
'#\[s\](.*?)\[/s\]#si' => ($xhtml ? '<strike>\\1</strike>' : '<s>\\1</s>'), '#\[s\](.*?)\[/s\]#si' => ($xhtml ? '<strike>\\1</strike>' : '<s>\\1</s>'),
'#\[guild\](.*?)\[/guild\]#si' => urldecode(generateLink(getGuildLink('$1', false), '$1', true)),
'#\[house\](.*?)\[/house\]#si' => urldecode(generateLink(getHouseLink('$1', false), '$1', true)),
'#\[player\](.*?)\[/player\]#si' => urldecode(generateLink(getPlayerLink('$1', false), '$1', true)),
// TODO: [poll] tag // TODO: [poll] tag
'#\[color=(.*?)\](.*?)\[/color\]#si' => ($xhtml ? '<span style="color: \\1;">\\2</span>' : '<span style="color: \\1">\\2</span>'), '#\[color=(.*?)\](.*?)\[/color\]#si' => ($xhtml ? '<span style="color: \\1;">\\2</span>' : '<span style="color: \\1">\\2</span>'),

View File

@@ -144,20 +144,13 @@ class Plugins {
$continue = true; $continue = true;
if(!isset($plugin_json['name']) || empty(trim($plugin_json['name']))) { if(!isset($plugin_json['name']) || empty(trim($plugin_json['name']))) {
self::$warnings[] = 'Plugin "name" tag is not set.'; self::$error = 'Plugin "name" tag is not set.';
} return false;
if(!isset($plugin_json['description']) || empty(trim($plugin_json['description']))) {
self::$warnings[] = 'Plugin "description" tag is not set.';
} }
if(!isset($plugin_json['version']) || empty(trim($plugin_json['version']))) { if(!isset($plugin_json['version']) || empty(trim($plugin_json['version']))) {
self::$warnings[] = 'Plugin "version" tag is not set.'; self::$warnings[] = 'Plugin "version" tag is not set.';
} }
if(!isset($plugin_json['author']) || empty(trim($plugin_json['author']))) {
self::$warnings[] = 'Plugin "author" tag is not set.';
}
if(!isset($plugin_json['contact']) || empty(trim($plugin_json['contact']))) {
self::$warnings[] = 'Plugin "contact" tag is not set.';
}
if(isset($plugin_json['require'])) { if(isset($plugin_json['require'])) {
$require = $plugin_json['require']; $require = $plugin_json['require'];

View File

@@ -374,16 +374,13 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
if(isset($this->data['premium_ends_at']) || isset($this->data['premend'])) { if(isset($this->data['premium_ends_at']) || isset($this->data['premend'])) {
$col = isset($this->data['premium_ends_at']) ? 'premium_ends_at' : 'premend'; $col = isset($this->data['premium_ends_at']) ? 'premium_ends_at' : 'premend';
$ret = ceil(($this->data[$col] - time()) / (24 * 60 * 60)); $ret = ceil(($this->data[$col] - time()) / (24 * 60 * 60));
return $ret > 0 ? $ret : 0; return max($ret, 0);
} }
if($this->data['premdays'] == 0) { if($this->data['premdays'] == 0) {
return 0; return 0;
} }
global $config;
if(isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium'])) return -1;
if($this->data['premdays'] == self::GRATIS_PREMIUM_DAYS){ if($this->data['premdays'] == self::GRATIS_PREMIUM_DAYS){
return self::GRATIS_PREMIUM_DAYS; return self::GRATIS_PREMIUM_DAYS;
} }

View File

@@ -216,8 +216,21 @@ class OTS_DB_MySQL extends OTS_Base_DB
return $this->hasColumnInternal($table, $column); return $this->hasColumnInternal($table, $column);
} }
private function hasColumnInternal($table, $column) { private function hasColumnInternal($table, $column): bool {
return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE '" . $column . "'")->fetchAll()) > 0); return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE " . $this->quote($column))->fetchAll()) > 0);
}
public function hasTableAndColumns(string $table, array $columns = []): bool
{
if (!$this->hasTable($table)) return false;
foreach ($columns as $column) {
if (!$this->hasColumn($table, $column)) {
return false;
}
}
return true;
} }
public function revalidateCache() { public function revalidateCache() {

View File

@@ -108,6 +108,8 @@ class OTS_Player extends OTS_Row_DAO
POT::SKILL_SHIELD => array('value' => 0, 'tries' => 0), POT::SKILL_SHIELD => array('value' => 0, 'tries' => 0),
POT::SKILL_FISH => array('value' => 0, 'tries' => 0) POT::SKILL_FISH => array('value' => 0, 'tries' => 0)
); );
private static array $playersOnline;
/** /**
* Magic PHP5 method. * Magic PHP5 method.
* *
@@ -765,10 +767,18 @@ class OTS_Player extends OTS_Row_DAO
public function isOnline() public function isOnline()
{ {
if($this->db->hasTable('players_online')) // tfs 1.0 if($this->db->hasTable('players_online')) {// tfs 1.0
{ if (!isset(self::$playersOnline)) {
$query = $this->db->query('SELECT `player_id` FROM `players_online` WHERE `player_id` = ' . $this->data['id']); self::$playersOnline = [];
return $query->rowCount() > 0;
$query = $this->db->query('SELECT `player_id` FROM `players_online`');
foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $item) {
self::$playersOnline[$item['player_id']] = true;
}
}
return isset(self::$playersOnline[$this->data['id']]);
} }
if( !isset($this->data['online']) ) if( !isset($this->data['online']) )

View File

@@ -92,6 +92,8 @@ class OTS_ServerInfo
return new OTS_Buffer($data); return new OTS_Buffer($data);
} }
log_append('status-error.log', "Cannot connect to {$this->server}:{$this->port} - Error code: $error, message: $message");
return false; return false;
} }

View File

@@ -36,6 +36,8 @@ if($player_name != null) {
'description' => 'The character information has been changed.' 'description' => 'The character information has been changed.'
)); ));
$show_form = false; $show_form = false;
$hooks->trigger(HOOK_ACCOUNT_CHARACTERS_CHANGE_COMMENT_AFTER_SUCCESS, ['player' => $player]);
} }
} }
} else { } else {

View File

@@ -232,8 +232,9 @@ if($save)
} }
else else
{ {
error('An error occorred while sending email! Account not created. Try again. For Admin: More info can be found in system/logs/mailer-error.log'); error('An error occurred while sending email! Account not created. Try again. For Admin: More info can be found in system/logs/mailer-error.log');
$new_account->delete(); $new_account->delete();
return;
} }
} }
else else

View File

@@ -24,7 +24,7 @@ if(Forum::canPost($account_logged))
{ {
$first_post = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread['first_post']." LIMIT 1")->fetch(); $first_post = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread['first_post']." LIMIT 1")->fetch();
echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread['first_post']) . '">'.htmlspecialchars($first_post['post_topic']).'</a> >> <b>Edit post</b>'; echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread['first_post']) . '">'.htmlspecialchars($first_post['post_topic']).'</a> >> <b>Edit post</b>';
if(Forum::hasAccess($thread['section'] && ($account_logged->getId() == $thread['author_aid'] || Forum::isModerator()))) if(Forum::hasAccess($thread['section']) && ($account_logged->getId() == $thread['author_aid'] || Forum::isModerator()))
{ {
$char_id = $post_topic = $text = $smile = $html = null; $char_id = $post_topic = $text = $smile = $html = null;
$players_from_account = $db->query("SELECT `players`.`name`, `players`.`id` FROM `players` WHERE `players`.`account_id` = ".(int) $account_logged->getId())->fetchAll(); $players_from_account = $db->query("SELECT `players`.`name`, `players`.`id` FROM `players` WHERE `players`.`account_id` = ".(int) $account_logged->getId())->fetchAll();

View File

@@ -111,7 +111,26 @@ if(isset($todo) && $todo == 'save')
$new_guild->setOwner($player); $new_guild->setOwner($player);
$new_guild->save(); $new_guild->save();
$new_guild->setCustomField('description', 'New guild. Leader must edit this text :)'); $new_guild->setCustomField('description', 'New guild. Leader must edit this text :)');
//$new_guild->setCustomField('creationdata', time());
if ($db->hasTable('guild_ranks')) {
$query = $db->query("SELECT * FROM guild_ranks WHERE guild_id = " . $new_guild->getId());
if($query->rowCount() == 0) {
$ranks = [
['level' => 3, 'name' => 'the Leader'],
['level' => 2, 'name' => 'a Vice-Leader'],
['level' => 1, 'name' => 'a Member'],
];
foreach ($ranks as $rank) {
$db->insert('guild_ranks', [
'guild_id' => $new_guild->getId(),
'name' => $rank['name'],
'level' => $rank['level'],
]);
}
}
}
$ranks = $new_guild->getGuildRanksList(); $ranks = $new_guild->getGuildRanksList();
$ranks->orderBy('level', POT::ORDER_DESC); $ranks->orderBy('level', POT::ORDER_DESC);
foreach($ranks as $rank) { foreach($ranks as $rank) {
@@ -119,14 +138,11 @@ if(isset($todo) && $todo == 'save')
$player->setRank($rank); $player->setRank($rank);
} }
} }
$twig->display('guilds.create.success.html.twig', array( $twig->display('guilds.create.success.html.twig', array(
'guild_name' => $guild_name, 'guild_name' => $guild_name,
'leader_name' => $player->getName() 'leader_name' => $player->getName()
)); ));
/*$db->exec('INSERT INTO `guild_ranks` (`id`, `guild_id`, `name`, `level`) VALUES (null, '.$new_guild->getId().', "the Leader", 3)');
$db->exec('INSERT INTO `guild_ranks` (`id`, `guild_id`, `name`, `level`) VALUES (null, '.$new_guild->getId().', "a Vice-Leader", 2)');
$db->exec('INSERT INTO `guild_ranks` (`id`, `guild_id`, `name`, `level`) VALUES (null, '.$new_guild->getId().', "a Member", 1)');*/
} }
else { else {
sort($array_of_player_nig); sort($array_of_player_nig);

View File

@@ -93,7 +93,7 @@ elseif($action == 'sendcode')
$newcode = generateRandomString(30, true, false, true); $newcode = generateRandomString(30, true, false, true);
$mailBody = ' $mailBody = '
You asked to reset your ' . $config['lua']['serverName'] . ' password.<br/> You asked to reset your ' . $config['lua']['serverName'] . ' password.<br/>
<p>Account name: '.$account->getName().'</p> <p>Account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . ' ' .(USE_ACCOUNT_NAME ? $account->getName() : $account->getId()).'</p>
<br /> <br />
To do so, please click this link: To do so, please click this link:
<p><a href="' . BASE_URL . '?subtopic=lostaccount&action=checkcode&code='.$newcode.'&character='.urlencode($nick).'">'.BASE_URL.'/?subtopic=lostaccount&action=checkcode&code='.$newcode.'&character='.urlencode($nick).'</a></p> <p><a href="' . BASE_URL . '?subtopic=lostaccount&action=checkcode&code='.$newcode.'&character='.urlencode($nick).'">'.BASE_URL.'/?subtopic=lostaccount&action=checkcode&code='.$newcode.'&character='.urlencode($nick).'</a></p>
@@ -150,7 +150,7 @@ elseif($action == 'step1' && $action_type == 'reckey')
$account_key = $account->getCustomField('key'); $account_key = $account->getCustomField('key');
if(!empty($account_key)) if(!empty($account_key))
{ {
echo 'If you enter right recovery key you will see form to set new e-mail and password to account. To this e-mail will be send your new password and account name.<BR> echo 'If you enter right recovery key you will see form to set new e-mail and password to account. To this e-mail will be send your new password and account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . '.<BR>
<FORM ACTION="?subtopic=lostaccount&action=step2" METHOD=post> <FORM ACTION="?subtopic=lostaccount&action=step2" METHOD=post>
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Please enter your recovery key</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Please enter your recovery key</B></TD></TR>
@@ -304,21 +304,22 @@ elseif($action == 'step3')
if($config_salt_enabled) if($config_salt_enabled)
$account->setCustomField('salt', $salt); $account->setCustomField('salt', $salt);
echo 'Your account name, new password and new e-mail.<BR> echo 'Your account ' . (USE_ACCOUNT_NAME ? 'name' : 'number') . ', new password and new e-mail.<BR>
<FORM ACTION="?subtopic=accountmanagement" onsubmit="return validate_form(this)" METHOD=post> <FORM ACTION="?subtopic=accountmanagement" onsubmit="return validate_form(this)" METHOD=post>
<INPUT TYPE=hidden NAME="character" VALUE=""> <INPUT TYPE=hidden NAME="character" VALUE="">
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Your account name, new password and new e-mail</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Your account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . ', new password and new e-mail</B></TD></TR>
<TR><TD BGCOLOR="'.$config['darkborder'].'"> <TR><TD BGCOLOR="'.$config['darkborder'].'">
Account name:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>'.$account->getName().'</b><BR> Account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . ':&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>'.(USE_ACCOUNT_NAME ? $account->getName() : $account->getId()).'</b><BR>
New password:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>'.$new_pass.'</b><BR> New password:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>'.$new_pass.'</b><BR>
New e-mail address:&nbsp;<b>'.$new_email.'</b><BR>'; New e-mail address:&nbsp;<b>'.$new_email.'</b><BR>';
if($account->getCustomField('email_next') < time()) if($account->getCustomField('email_next') < time())
{ {
$mailBody = ' $mailBody = '
<h3>Your account name and new password!</h3> <h3>Your account ' . (USE_ACCOUNT_NAME ? 'name' : 'number') . ' and new password!</h3>
<p>Changed password and e-mail to your account in Lost Account Interface on server <a href="'.BASE_URL.'"><b>'.$config['lua']['serverName'].'</b></a></p> <p>Changed password and e-mail to your account in Lost Account Interface on server <a href="'.BASE_URL.'"><b>'.$config['lua']['serverName'].'</b></a></p>
<p>Account name: <b>'.$account->getName().'</b></p> <p>Account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . ': <b>'.(USE_ACCOUNT_NAME ? $account->getName() : $account->getId()).'</b></p>
<p>New password: <b>'.$new_pass.'</b></p> <p>New password: <b>'.$new_pass.'</b></p>
<p>E-mail: <b>'.$new_email.'</b> (this e-mail)</p> <p>E-mail: <b>'.$new_email.'</b> (this e-mail)</p>
<br /> <br />
@@ -326,7 +327,7 @@ elseif($action == 'step3')
if(_mail($account->getCustomField('email'), $config['lua']['serverName']." - New password to your account", $mailBody)) if(_mail($account->getCustomField('email'), $config['lua']['serverName']." - New password to your account", $mailBody))
{ {
echo '<br /><small>Sent e-mail with your account name and password to new e-mail. You should receive this e-mail in 15 minutes. You can login now with new password!</small>'; echo '<br /><small>Sent e-mail with your account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . ' and password to new e-mail. You should receive this e-mail in 15 minutes. You can login now with new password!</small>';
} }
else else
{ {
@@ -423,7 +424,7 @@ elseif($action == 'checkcode')
<INPUT TYPE=hidden NAME="character" VALUE="'.$character.'"> <INPUT TYPE=hidden NAME="character" VALUE="'.$character.'">
<INPUT TYPE=hidden NAME="code" VALUE="'.$code.'"> <INPUT TYPE=hidden NAME="code" VALUE="'.$code.'">
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Code & account name</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Code & account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . '</B></TD></TR>
<TR><TD BGCOLOR="'.$config['darkborder'].'"> <TR><TD BGCOLOR="'.$config['darkborder'].'">
New password:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT TYPE=password ID="passor" NAME="passor" VALUE="" SIZE="40")><BR /> New password:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT TYPE=password ID="passor" NAME="passor" VALUE="" SIZE="40")><BR />
Repeat new password:&nbsp;<INPUT TYPE=password ID="passor2" NAME="passor2" VALUE="" SIZE="40")><BR /> Repeat new password:&nbsp;<INPUT TYPE=password ID="passor2" NAME="passor2" VALUE="" SIZE="40")><BR />
@@ -497,19 +498,19 @@ elseif($action == 'setnewpassword')
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Changed password</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Changed password</B></TD></TR>
<TR><TD BGCOLOR="'.$config['darkborder'].'"> <TR><TD BGCOLOR="'.$config['darkborder'].'">
New password:&nbsp;<b>'.$newpassword.'</b><BR /> New password:&nbsp;<b>'.$newpassword.'</b><BR />
Account name:&nbsp;&nbsp;&nbsp;<i>(Already on your e-mail)</i><BR />'; Account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . ':&nbsp;&nbsp;&nbsp;<i>(Already on your e-mail)</i><BR />';
$mailBody = ' $mailBody = '
<h3>Your account name and password!</h3> <h3>Your account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . ' and password!</h3>
<p>Changed password to your account in Lost Account Interface on server <a href="'.BASE_URL.'"><b>'.$config['lua']['serverName'].'</b></a></p> <p>Changed password to your account in Lost Account Interface on server <a href="'.BASE_URL.'"><b>'.$config['lua']['serverName'].'</b></a></p>
<p>Account name: <b>'.$account->getName().'</b></p> <p>Account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . ': <b>'.(USE_ACCOUNT_NAME ? $account->getName() : $account->getId()).'</b></p>
<p>New password: <b>'.$newpassword.'</b></p> <p>New password: <b>'.$newpassword.'</b></p>
<br /> <br />
<p><u>It\'s automatic e-mail from OTS Lost Account System. Do not reply!</u></p>'; <p><u>It\'s automatic e-mail from OTS Lost Account System. Do not reply!</u></p>';
if(_mail($account->getCustomField('email'), $config['lua']['serverName']." - Your new password", $mailBody)) if(_mail($account->getCustomField('email'), $config['lua']['serverName']." - Your new password", $mailBody))
{ {
echo '<br /><small>New password work! Sent e-mail with your password and account name. You should receive this e-mail in 15 minutes. You can login now with new password!'; echo '<br /><small>New password work! Sent e-mail with your password and account ' . (USE_ACCOUNT_NAME ? 'Name' : 'Number') . '. You should receive this e-mail in 15 minutes. You can login now with new password!';
} }
else else
{ {

View File

@@ -115,7 +115,7 @@ if(!$news_cached)
); );
} }
$tickers_db = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'news` WHERE `type` = ' . TICKER .($canEdit ? '' : ' AND `hidden` != 1') .' ORDER BY `date` DESC LIMIT ' . $config['news_ticker_limit']); $tickers_db = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'news` WHERE `type` = ' . TICKER . ' AND `hidden` != 1 ORDER BY `date` DESC LIMIT ' . $config['news_ticker_limit']);
$tickers_content = ''; $tickers_content = '';
if($tickers_db->rowCount() > 0) if($tickers_db->rowCount() > 0)
{ {
@@ -134,7 +134,7 @@ if(!$news_cached)
if($cache->enabled() && !$canEdit) if($cache->enabled() && !$canEdit)
$cache->set('news_' . $template_name . '_' . TICKER, $tickers_content, 60 * 60); $cache->set('news_' . $template_name . '_' . TICKER, $tickers_content, 60 * 60);
$featured_article_db =$db->query('SELECT `id`, `title`, `article_text`, `article_image`, `hidden` FROM `' . TABLE_PREFIX . 'news` WHERE `type` = ' . ARTICLE . ($canEdit ? '' : ' AND `hidden` != 1') .' ORDER BY `date` DESC LIMIT 1'); $featured_article_db =$db->query('SELECT `id`, `title`, `article_text`, `article_image`, `hidden` FROM `' . TABLE_PREFIX . 'news` WHERE `type` = ' . ARTICLE . ' AND `hidden` != 1 ORDER BY `date` DESC LIMIT 1');
$article = ''; $article = '';
if($featured_article_db->rowCount() > 0) { if($featured_article_db->rowCount() > 0) {
$article = $featured_article_db->fetch(); $article = $featured_article_db->fetch();
@@ -166,7 +166,7 @@ else {
if(!$news_cached) if(!$news_cached)
{ {
ob_start(); ob_start();
$newses = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news') . ' WHERE type = ' . NEWS . ($canEdit ? '' : ' AND hidden != 1') . ' ORDER BY date' . ' DESC LIMIT ' . $config['news_limit']); $newses = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news') . ' WHERE type = ' . NEWS . ' AND hidden != 1 ORDER BY date' . ' DESC LIMIT ' . $config['news_limit']);
if($newses->rowCount() > 0) if($newses->rowCount() > 0)
{ {
foreach($newses as $news) foreach($newses as $news)

View File

@@ -143,13 +143,7 @@ function updateStatus() {
} }
$uptime = $status['uptime'] = $serverStatus->getUptime(); $uptime = $status['uptime'] = $serverStatus->getUptime();
$m = date('m', $uptime); $status['uptimeReadable'] = getStatusUptimeReadable($uptime);
$m = $m > 1 ? "$m months, " : ($m == 1 ? 'month, ' : '');
$d = date('d', $uptime);
$d = $d > 1 ? "$d days, " : ($d == 1 ? 'day, ' : '');
$h = date('H', $uptime);
$min = date('i', $uptime);
$status['uptimeReadable'] = "{$m}{$d}{$h}h {$min}m";
$status['monsters'] = $serverStatus->getMonstersCount(); $status['monsters'] = $serverStatus->getMonstersCount();
$status['motd'] = $serverStatus->getMOTD(); $status['motd'] = $serverStatus->getMOTD();

View File

@@ -83,7 +83,7 @@ else {
unset($file); unset($file);
if ($cache->enabled()) { if ($cache->enabled()) {
$cache->set('template_ini_' . $template_name, serialize($template_ini)); $cache->set('template_ini_' . $template_name, serialize($template_ini), 10 * 60);
} }
} }
} }

View File

@@ -32,6 +32,7 @@ If you do not want to specify a certain field, just leave it blank.<br/><br/>
<td class="LabelV">Name:</td> <td class="LabelV">Name:</td>
<td style="width:80%;" >{{ player.getName() }}</td> <td style="width:80%;" >{{ player.getName() }}</td>
</tr> </tr>
{{ hook('HOOK_ACCOUNT_CHARACTERS_CHANGE_COMMENT_AFTER_NAME') }}
<tr> <tr>
<td class="LabelV" >Hide Account:</td> <td class="LabelV" >Hide Account:</td>
<td> <td>
@@ -41,6 +42,7 @@ If you do not want to specify a certain field, just leave it blank.<br/><br/>
{% if player.getCustomField('group_id') > 1 %} (you will be also hidden on the Team page!){% endif %} {% if player.getCustomField('group_id') > 1 %} (you will be also hidden on the Team page!){% endif %}
</td> </td>
</tr> </tr>
{{ hook('HOOK_ACCOUNT_CHARACTERS_CHANGE_COMMENT_AFTER_HIDE_ACCOUNT') }}
</table> </table>
</div> </div>
</div> </div>
@@ -64,6 +66,7 @@ If you do not want to specify a certain field, just leave it blank.<br/><br/>
<td class="LabelV" ><span>Comment:</span></td> <td class="LabelV" ><span>Comment:</span></td>
<td style="width:80%;"><textarea name="comment" rows="10" cols="50" wrap="virtual">{{ player.getCustomField('comment')|raw }}</textarea><br>[max. length: 2000 chars, 50 lines (ENTERs)]</td> <td style="width:80%;"><textarea name="comment" rows="10" cols="50" wrap="virtual">{{ player.getCustomField('comment')|raw }}</textarea><br>[max. length: 2000 chars, 50 lines (ENTERs)]</td>
</tr> </tr>
{{ hook('HOOK_ACCOUNT_CHARACTERS_CHANGE_COMMENT_AFTER_COMMENT') }}
</table> </table>
</div> </div>
</div> </div>

View File

@@ -109,7 +109,7 @@
</tr> </tr>
<tr style="background-color: {{ config.darkborder }};" > <tr style="background-color: {{ config.darkborder }};" >
<td>Last Login:</td> <td>Last Login:</td>
<td>{{ "now"|date("j F Y, G:i:s") }}</td> <td>{{ account_logged.getCustomField('web_lastlogin')|date("j F Y, G:i:s") }}</td>
</tr> </tr>
{% autoescape false %} {% autoescape false %}
<tr style="background-color: {{ config.lightborder }};" > <tr style="background-color: {{ config.lightborder }};" >
@@ -173,7 +173,7 @@
{% set i = i + 1 %} {% set i = i + 1 %}
<tr bgcolor="{{ getStyle(i) }}"> <tr bgcolor="{{ getStyle(i) }}">
<td> <td>
<a href="{{ getLink('characters/' ~ player.getName()|urlencode) }}">{{ player.getName() }}</a> <a href="{{ getLink('characters/' ~ player.getName()|urlencode) }}">{{ player.getName() }}</a>{% if player.isDeleted() %}<span style="color: red"><b> [ DELETED ] </b></span>{% endif %}
</td> </td>
<td>{{ player.getLevel() }}</td> <td>{{ player.getLevel() }}</td>
<td>{{ player.getVocationName() }}</td> <td>{{ player.getVocationName() }}</td>

View File

@@ -1 +1 @@
<input type="submit" name="{{ button_name }}" value="{{ button_name }}" /> <input {% if noSubmit is not defined %}type="submit"{% endif %} name="{{ button_name }}" value="{{ button_name }}" />

View File

@@ -9,7 +9,7 @@
<div class="AttentionSign" style="background-image:url({{ template_path }}/images/content/attentionsign.gif);"></div> <div class="AttentionSign" style="background-image:url({{ template_path }}/images/content/attentionsign.gif);"></div>
<b>The Following Errors Have Occurred:</b><br/> <b>The Following Errors Have Occurred:</b><br/>
{% for error in errors %} {% for error in errors %}
<li>{{ error|striptags('<b>')|raw }}</li> <li>{{ error|striptags('<b><a>')|raw }}</li>
{% endfor %} {% endfor %}
</div> </div>
<div class="BoxFrameHorizontal" style="background-image:url({{ template_path }}/images/content/box-frame-horizontal.gif);"></div> <div class="BoxFrameHorizontal" style="background-image:url({{ template_path }}/images/content/box-frame-horizontal.gif);"></div>

View File

@@ -18,8 +18,6 @@
font-family: Verdana, Geneva, sans-serif; font-family: Verdana, Geneva, sans-serif;
} }
.center { .center {
height: 500px;
position: absolute;
top:0; top:0;
bottom: 0; bottom: 0;
left: 0; left: 0;
@@ -38,7 +36,7 @@
} }
#footer { #footer {
position: absolute; margin-top: 20px;
bottom: 15px; bottom: 15px;
width: 100%; width: 100%;

View File

@@ -104,7 +104,7 @@
{% if config.online_outfit %} {% if config.online_outfit %}
<td width="5%"><img style="position:absolute;margin-top:{% if player.player.looktype in [75, 266, 302] %}-20px;margin-left:-0px;{% else %}-45px;margin-left:-25px;{% endif %}" src="{{ player.outfit }}" alt="player outfit"/></td> <td width="5%"><img style="position:absolute;margin-top:{% if player.player.looktype in [75, 266, 302] %}-20px;margin-left:-0px;{% else %}-45px;margin-left:-25px;{% endif %}" src="{{ player.outfit }}" alt="player outfit"/></td>
{% endif %} {% endif %}
<td>{{ player.name|raw }}{{ player.skull }}</td> <td>{{ player.name|raw }}{{ player.skull|raw }}</td>
<td>{{ player.level }}</td> <td>{{ player.level }}</td>
<td>{{ player.vocation }}</td> <td>{{ player.vocation }}</td>
</tr> </tr>

View File

@@ -50,6 +50,10 @@ $twig->addFunction($function);
$function = new TwigFunction('hook', function ($context, $hook, array $params = []) { $function = new TwigFunction('hook', function ($context, $hook, array $params = []) {
global $hooks; global $hooks;
if (config('hooks_debug')) {
note($hook);
}
if(is_string($hook)) { if(is_string($hook)) {
if (defined($hook)) { if (defined($hook)) {
$hook = constant($hook); $hook = constant($hook);
@@ -83,3 +87,7 @@ $filter = new TwigFilter('urlencode', function ($s) {
$twig->addFilter($filter); $twig->addFilter($filter);
unset($function, $filter); unset($function, $filter);
$hooks->trigger(HOOK_TWIG, ['twig' => $twig, 'twig_loader' => $twig_loader]);
$twig->addGlobal('cache', $cache);

View File

@@ -161,7 +161,7 @@
</tr> </tr>
<tr style="background-color: {{ config.darkborder }};" > <tr style="background-color: {{ config.darkborder }};" >
<td class="LabelV" >Last Login:</td> <td class="LabelV" >Last Login:</td>
<td>{{ "now"|date("j F Y, G:i:s") }}</td> <td>{{ account_logged.getCustomField('web_lastlogin')|date("j F Y, G:i:s") }}</td>
</tr> </tr>
{% autoescape false %} {% autoescape false %}
<tr style="background-color: {{ config.lightborder }};" > <tr style="background-color: {{ config.lightborder }};" >

View File

@@ -1,6 +1,6 @@
<div id="CurrentPollBox" class="Themebox" style="background-image:url({{ template_path }}/images/themeboxes/current-poll/currentpollbox.gif);"> <div id="CurrentPollBox" class="Themebox" style="background-image:url({{ template_path }}/images/themeboxes/current-poll/currentpollbox.gif);">
<div id="CurrentPollText">{{ poll.question }}</div> <div id="CurrentPollText">{{ poll.question }}</div>
<a class="ThemeboxButton" href="{{ getLink('polls') }}/{{ poll.id }}" onMouseOver="MouseOverBigButton(this);" onMouseOut="MouseOutBigButton(this);" style="background-image:url({{ template_path }}/images/global/buttons/sbutton.gif);"><div class="BigButtonOver" style="background-image:url({{ template_path }}/images/global/buttons/sbutton_over.gif);"></div><div class="ButtonText" style="background-image:url({{ template_path }}/images/global/buttons/_sbutton_votenow.gif);"></div> <a class="ThemeboxButton" href="{{ getLink('polls') }}?id={{ poll.id }}" onMouseOver="MouseOverBigButton(this);" onMouseOut="MouseOutBigButton(this);" style="background-image:url({{ template_path }}/images/global/buttons/sbutton.gif);"><div class="BigButtonOver" style="background-image:url({{ template_path }}/images/global/buttons/sbutton_over.gif);"></div><div class="ButtonText" style="background-image:url({{ template_path }}/images/global/buttons/_sbutton_votenow.gif);"></div>
</a> </a>
<div class="Bottom" style="background-image:url({{ template_path }}/images/general/box-bottom.gif);"></div> <div class="Bottom" style="background-image:url({{ template_path }}/images/general/box-bottom.gif);"></div>
</div> </div>

View File

@@ -13,7 +13,7 @@
<div class="BigButton" style="background-image:url({{ template_path }}/images/global/buttons/{{ tmp_image }}.gif)"> <div class="BigButton" style="background-image:url({{ template_path }}/images/global/buttons/{{ tmp_image }}.gif)">
<div onMouseOver="MouseOverBigButton(this);" onMouseOut="MouseOutBigButton(this);"> <div onMouseOver="MouseOverBigButton(this);" onMouseOut="MouseOutBigButton(this);">
<div class="BigButtonOver" style="background-image:url({{ template_path }}/images/global/buttons/{{ tmp_image }}_over.gif);" ></div> <div class="BigButtonOver" style="background-image:url({{ template_path }}/images/global/buttons/{{ tmp_image }}_over.gif);" ></div>
<input class="BigButtonText" type="submit" value="{{ button_name }}"> <input class="BigButtonText" {% if noSubmit is not defined %}type="submit"{% endif %} value="{{ button_name }}">
</div> </div>
</div> </div>
{% endapply %} {% endapply %}

View File

@@ -1,3 +1,3 @@
{% set button_name = 'Logout' %} {% set button_name = 'Logout' %}
{% set button_image = '_sbutton_logout' %} {% set button_color = 'red' %}
{% include('buttons.base.html.twig') %} {% include('buttons.base.html.twig') %}

View File

@@ -21,7 +21,7 @@ if(!@file_exists($page_file))
putenv('GDFONTPATH=' . __DIR__); putenv('GDFONTPATH=' . __DIR__);
// create image // create image
$image = imagecreatetruecolor(250, 28); $image = imagecreatetruecolor(600, 28);
// make the background transparent // make the background transparent
imagecolortransparent($image, imagecolorallocate($image, 0, 0, 0)); imagecolortransparent($image, imagecolorallocate($image, 0, 0, 0));
@@ -31,12 +31,12 @@ if(!@file_exists($page_file))
imagettftext($image, 18, 0, 4, 20, imagecolorallocate($image, 240, 209, 164), $font, $_GET['t']); imagettftext($image, 18, 0, 4, 20, imagecolorallocate($image, 240, 209, 164), $font, $_GET['t']);
// header mime type // header mime type
header('Content-type: image/gif'); header('Content-type: image/png');
// save image // save image
imagegif($image/*, $file*/); imagepng($image/*, $file*/);
//} //}
// output image // output image
//header('Content-type: image/gif'); //header('Content-type: image/png');
//readfile($file); //readfile($file);

View File

@@ -82,13 +82,13 @@ if(isset($config['boxes']))
// mouse-over and click events of the loginbox // mouse-over and click events of the loginbox
function MouseOverLoginBoxText(source) function MouseOverLoginBoxText(source)
{ {
source.lastChild.style.visibility = "visible"; source.lastElementChild.style.visibility = "visible";
source.firstChild.style.visibility = "hidden"; source.firstElementChild.style.visibility = "hidden";
} }
function MouseOutLoginBoxText(source) function MouseOutLoginBoxText(source)
{ {
source.firstChild.style.visibility = "visible"; source.firstElementChild.style.visibility = "visible";
source.lastChild.style.visibility = "hidden"; source.lastElementChild.style.visibility = "hidden";
} }
function LoginButtonAction() function LoginButtonAction()
{ {
@@ -147,6 +147,9 @@ if(isset($config['boxes']))
function InitializeMenu() function InitializeMenu()
{ {
for(menuItemName in menu[0]) { for(menuItemName in menu[0]) {
if (!document.getElementById(menuItemName+"_Submenu")) {
continue;
}
if(menu[0][menuItemName] == "0") { if(menu[0][menuItemName] == "0") {
document.getElementById(menuItemName+"_Submenu").style.visibility = "hidden"; document.getElementById(menuItemName+"_Submenu").style.visibility = "hidden";
document.getElementById(menuItemName+"_Submenu").style.display = "none"; document.getElementById(menuItemName+"_Submenu").style.display = "none";
@@ -205,11 +208,11 @@ if(isset($config['boxes']))
// mouse-over effects of menubuttons and submenuitems // mouse-over effects of menubuttons and submenuitems
function MouseOverMenuItem(source) function MouseOverMenuItem(source)
{ {
source.firstChild.style.visibility = "visible"; source.firstElementChild.style.visibility = "visible";
} }
function MouseOutMenuItem(source) function MouseOutMenuItem(source)
{ {
source.firstChild.style.visibility = "hidden"; source.firstElementChild.style.visibility = "hidden";
} }
function MouseOverSubmenuItem(source) function MouseOverSubmenuItem(source)
{ {
@@ -315,7 +318,7 @@ if(isset($config['boxes']))
<div id="LoginBottom" class="Loginstatus" style="background-image:url(<?php echo $template_path; ?>/images/general/box-bottom.gif)" ></div> <div id="LoginBottom" class="Loginstatus" style="background-image:url(<?php echo $template_path; ?>/images/general/box-bottom.gif)" ></div>
</div> </div>
<div-- id='Menu'> <div id='Menu'>
<div id='MenuTop' style='background-image:url(<?php echo $template_path; ?>/images/general/box-top.gif);'></div> <div id='MenuTop' style='background-image:url(<?php echo $template_path; ?>/images/general/box-top.gif);'></div>
<?php <?php
@@ -371,6 +374,7 @@ foreach($config['menu_categories'] as $id => $cat) {
<?php <?php
} }
?> ?>
</div>
<script type="text/javascript"> <script type="text/javascript">
InitializePage(); InitializePage();
</script> </script>
@@ -428,7 +432,7 @@ foreach($config['menu_categories'] as $id => $cat) {
foreach($config['boxes'] as $box) { foreach($config['boxes'] as $box) {
/** @var string $template_name */ /** @var string $template_name */
$file = TEMPLATES . $template_name . '/boxes/' . $box . '.php'; $file = __DIR__ . '/boxes/' . $box . '.php';
if(file_exists($file)) { if(file_exists($file)) {
include($file); ?> include($file); ?>
<?php <?php

View File

@@ -1,11 +1,11 @@
function MouseOverBigButton(source) { function MouseOverBigButton(source) {
if (source?.firstChild?.style) { if (source?.firstElementChild?.style) {
source.firstChild.style.visibility = "visible"; source.firstElementChild.style.visibility = "visible";
} }
} }
function MouseOutBigButton(source) { function MouseOutBigButton(source) {
if (source?.firstChild?.style) { if (source?.firstElementChild?.style) {
source.firstChild.style.visibility = "hidden"; source.firstElementChild.style.visibility = "hidden";
} }
} }
function BigButtonAction(path) { function BigButtonAction(path) {

View File

@@ -33,14 +33,14 @@
if(!isset($_REQUEST['name'])) if(!isset($_REQUEST['name']))
die('Please enter name as get or post parameter.'); die('Please enter name as get or post parameter.');
$name = stripslashes(ucwords(strtolower(trim($_REQUEST['name']))));
$player = new OTS_Player(); $player = new OTS_Player();
$player->find($name); $player->find($_REQUEST['name']);
if(!$player->isLoaded()) if(!$player->isLoaded())
{ {
header('Content-type: image/png'); //header('Content-type: image/png');
readfile(SIGNATURES_IMAGES.'nocharacter.png'); //readfile(SIGNATURES_IMAGES.'nocharacter.png');
http_response_code(404);
exit; exit;
} }