Compare commits

...

86 Commits
v0.8.18 ... 0.8

Author SHA1 Message Date
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
slawkens
c5c266b023 Update CHANGELOG.md 2025-01-09 19:26:27 +01:00
slawkens
9483cfaad8 vendor should be accessible, cause of debugbar 2025-01-09 13:39:58 +01:00
slawkens
b4ed68dfd7 Prepare v0.8.21 release 2025-01-09 10:46:51 +01:00
slawkens
39b19ed4c8 Fix change sex price deducted 2025-01-09 09:42:09 +01:00
slawkens
580b888b1d Fix XSS in forum 2025-01-08 23:29:34 +01:00
slawkens
19d3e15c11 Fix move_thread by unauthorized user 2025-01-08 22:34:16 +01:00
slawkens
5a68d204bb Fix for TFS 1.4.2 where conditions is NULL 2024-12-29 15:38:02 +01:00
slawkens
e09fe51774 Set default_socket_timeout for ipinfo.io checkup 2024-12-26 08:53:40 +01:00
slawkens
b2c9eb4745 Support for button_color (red, green, blue) 2024-12-05 21:49:24 +01:00
slawkens
d96787ec21 Update to v0.8.21-defv 2024-11-26 19:00:20 +01:00
slawkens
5df5c64e4f Update to v0.8.20 2024-11-26 18:34:51 +01:00
slawkens
3c4b19743f Linux is case-sensitive, made a mistake here, sorry! 2024-11-26 18:25:01 +01:00
slawkens
0e25ce553c Set current version to 0.8.20-dev 2024-11-19 15:24:42 +01:00
slawkens
2e4bbeb7f7 Release v0.8.19 2024-11-19 14:10:25 +01:00
slawkens
cb6640343b Prepare 0.8.19 changelog 2024-11-19 14:09:49 +01:00
slawkens
4658d1cb29 More obvious name for parameter in -> installMenus 2024-11-19 14:03:49 +01:00
slawkens
b25feaadf6 Fix includes 2024-11-19 14:03:02 +01:00
slawkens
2693db5f6f images/news is in the main folder 2024-11-19 08:21:06 +01:00
slawkens
8195b44061 require src/plugins.php 2024-11-19 07:46:16 +01:00
slawkens
035d0c1012 Add forward-compatible MyAAC namespace 2024-11-19 07:15:26 +01:00
slawkens
5a953ce901 Do not clear menus by default 2024-11-19 07:05:40 +01:00
slawkens
01660bd2b4 Fix for console displaying REQUEST_URI 2024-11-18 23:47:31 +01:00
slawkens
5b858c521a target_blank in template menus links 2024-11-18 23:47:11 +01:00
slawkens
d1c5a189c3 Add Plugins::installMenus function 2024-11-18 23:46:37 +01:00
slawkens
de1bb37bcb getGuildNameById($id) + getGuildLogoById($id) 2024-11-18 23:46:04 +01:00
slawkens
e0036a3e32 Syntactic sugar for db structure changes 2024-11-08 14:38:00 +01:00
slawkens
7f4737631d Add none vocation to highscores 2024-10-10 15:33:25 +02:00
slawkens
317505bf19 Add missing Validator::characterName check 2024-09-12 09:40:36 +02:00
slawkens
55b8645d3f Set default encryption to sha1 2024-09-08 15:05:12 +02:00
slawkens
ffb8f0879b two hooks for compatibility 2024-09-08 15:03:45 +02:00
slawkens
79f5614dce Add more clients (13.22+) 2024-09-08 14:47:36 +02:00
slawkens
2c347d0eac Interesting update from opentibiabr (Uptime readable) 2024-09-08 14:47:21 +02:00
slawkens
d40178104b New hooks in account manage + create 2024-09-08 06:23:17 +02:00
slawkens
55543ee881 Fix title - should be account logs 2024-09-08 06:22:29 +02:00
slawkens
d39386cfab Fix bans page getPlayerNameByAccount + getPlayerNameById 2024-09-08 06:21:40 +02:00
slawkens
b5bbae62b0 Prefer get_browser_real_ip() over REMOTE_ADDR 2024-09-08 05:36:33 +02:00
slawkens
71ef30d35e Better tables.headline.html.twig (patched from 1.0) 2024-09-07 17:28:45 +02:00
anyeor
263c7bed07 fix: require login before create new thread (#261)
We have to login first to see new thread button.
2024-07-26 18:19:29 +02:00
slawkens
1458b7a412 Fix $db->update when there is null value 2024-07-24 17:30:33 +02:00
slawkens
3e00c52128 Optimize OTS_House::load function with appropriate FETCH_ASSOC 2024-07-24 17:30:03 +02:00
slawkens
d73aceb272 Better https detection (patched from develop) 2024-07-23 16:39:24 +02:00
slawkens
1c55d4a220 Set Admin Account verified by default 2024-07-12 22:19:36 +02:00
slawkens
1edf8833c8 Patching from develop
* Allow account_create_character_create even if account_mail_verify is activated
* Fixes to account verify - do not allow login without verified email (Thanks @anyeor)
2024-07-09 23:51:12 +02:00
slawkens
0ffc5f68b4 deny all is enough 2024-06-23 09:56:12 +02:00
slawkens
81b6652738 Fix if <flags> is not present in monster.xml 2024-06-05 21:58:44 +02:00
slawkens
e5b4d2c6b3 Fix warnings in basic.js 2024-05-30 09:49:06 +02:00
slawkens
da1830371f Fix blessings longer than 3 characters 2024-05-30 08:24:02 +02:00
slawkens
6ba04967ed Update to 0.8.19-dev 2024-05-29 21:55:15 +02:00
66 changed files with 652 additions and 296 deletions

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@ Thumbs.db
# #
/.htaccess /.htaccess
lua
# composer # composer
composer.lock composer.lock

View File

@@ -1,5 +1,103 @@
# Changelog # Changelog
## [0.8.24 - 03.06.2025]
### Added
* Add code to insert guild_ranks on guild create, in case guild trigger is missing (https://github.com/slawkens/myaac/commit/149e10261befab22a38246bd792e2e4d1c42ef1e)
* Two new hooks for pages loaded from 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]
### Added
* support for button_color (red, green, blue) (https://github.com/slawkens/myaac/commit/b2c9eb474513650a014352d820602b8007eb3bf3)
### Changed
* Set default_socket_timeout for ipinfo.io checkup (https://github.com/slawkens/myaac/commit/e09fe517747e4f462c72395ede39759bf308d171)
### Fixed
* XSS in forum (https://github.com/slawkens/myaac/commit/580b888b1dd1317d7ccf5f888536159c3bfe4324)
* move_thread by unauthorized user (https://github.com/slawkens/myaac/commit/19d3e15c114de65ef6c379e4da66d32138a0e7c4)
* change sex wrong price deducted (https://github.com/slawkens/myaac/commit/39b19ed4c8724385ee80f7d02219e84f6b3f5d95)
* fix for TFS 1.4.2 exception on creating character, where conditions column is NULL (https://github.com/slawkens/myaac/commit/5a68d204bb24392d424efde4133b0a3222e788bb)
## [0.8.20 - 26.11.2024]
Small fix regarding the latest release and the linux system.
Download this one, instead of the 0.8.19 if you are using linux.
If you are using 0.8.19, make this update:
The fix is to make this change in the system/libs/hooks.php
Change
```
require_once LIBS . 'src/plugins.php';
```
Into:
```
require_once LIBS . 'src/Plugins.php';
```
Yeah, we just changed 'p' to 'P' - that's just case-sensitive nature of linux.
## [0.8.19 - 19.11.2024]
### Added
* syntactic sugar for db structure changes (https://github.com/slawkens/myaac/commit/e0036a3e32e8c37c28665dd7ae18ac9b8fc167d9)
* add "None" vocation to highscores (https://github.com/slawkens/myaac/commit/7f4737631dfcb6ec255c6d9301304d3bf222a033)
* new hooks in account manage + create (https://github.com/slawkens/myaac/commit/d40178104b0f411b9672102c49a4b87ac16e1779)
* new functions: getGuildNameById($id) + getGuildLogoById($id) + Plugins::installMenus($templateName, $menus, $clearOld = false) (https://github.com/slawkens/myaac/commit/de1bb37bcb6d111fbdf185ef9c2fec7e7f05053e + https://github.com/slawkens/myaac/commit/d1c5a189c3b182a36933ed507c6ae36b61fe1d45 + https://github.com/slawkens/myaac/commit/5a953ce901522d080aa16fcfcd268e9544bf6e1a)
### Changed
* set default encryption to sha1 (https://github.com/slawkens/myaac/commit/55b8645d3f38c47f4aafc1906625b676c429cdd5)
* prefer get_browser_real_ip() over REMOTE_ADDR (cause of Cloudflare and similar services) (https://github.com/slawkens/myaac/commit/b5bbae62b09db50a73bfa3e288245ea718005aa9)
* allow account_create_character_create even if account_mail_verify is activated (https://github.com/slawkens/myaac/commit/1edf8833c844b25372017e4affaf12aa02cdce7a)
* better https detection (patched from develop) (https://github.com/slawkens/myaac/commit/d73aceb272d0615244fcfd0998d75e6c6c15d3fe)
* require login before create new thread (#261, @anyeor)
* better tables.headline.html.twig (patched from 1.0) (https://github.com/slawkens/myaac/commit/71ef30d35ecb2f876e9b861f211f737302bf408e)
### Fixed
* bans page fixed functions getPlayerNameByAccount + getPlayerNameById (https://github.com/slawkens/myaac/commit/d39386cfabfa13e5c916ead69e2f8f90fdc47f4f)
* account verify - do not allow login without verified email (https://github.com/slawkens/myaac/commit/1edf8833c844b25372017e4affaf12aa02cdce7a, Thanks @anyeor)
* if <flags> is not present in monster.xml (https://github.com/slawkens/myaac/commit/81b6652738a7b04be3980cbf55443a6fbe437b34)
* $db->update when there is null value (https://github.com/slawkens/myaac/commit/1458b7a412ff6875cebba1b88d380f7f959ee6be)
* error on $db __destruct saving current script name in CLI (https://github.com/slawkens/myaac/commit/01660bd2b4967315c0e16d2f83c6c39f0b78683d)
## [0.8.18 - 29.05.2024] ## [0.8.18 - 29.05.2024]
### 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

@@ -210,7 +210,7 @@ if ($id > 0) {
if ($hasBlessingsColumn) { if ($hasBlessingsColumn) {
$blessings = $_POST['blessings']; $blessings = $_POST['blessings'];
verify_number($blessings, 'Blessings', 2); verify_number($blessings, 'Blessings', 3);
} }
$balance = $_POST['balance']; $balance = $_POST['balance'];

View File

@@ -10,8 +10,6 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Plugin manager'; $title = 'Plugin manager';
require_once LIBS . 'plugins.php';
$twig->display('admin.plugins.form.html.twig'); $twig->display('admin.plugins.form.html.twig');
if (isset($_REQUEST['uninstall'])) { if (isset($_REQUEST['uninstall'])) {

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.18'); define('MYAAC_VERSION', '0.8.25-dev');
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';
} }
@@ -115,7 +115,7 @@ if(!IS_CLI) {
} }
} }
define('SERVER_URL', 'http' . (isset($_SERVER['HTTPS'][0]) && strtolower($_SERVER['HTTPS']) === 'on' ? 's' : '') . '://' . $baseHost); define('SERVER_URL', 'http' . (isHttps() ? 's' : '') . '://' . $baseHost);
define('BASE_URL', SERVER_URL . BASE_DIR . '/'); define('BASE_URL', SERVER_URL . BASE_DIR . '/');
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/'); define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/');
@@ -125,3 +125,11 @@ if(!IS_CLI) {
} }
} }
require SYSTEM . 'autoload.php'; require SYSTEM . 'autoload.php';
function isHttps(): bool
{
return
(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
|| (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443);
}

View File

@@ -77,6 +77,7 @@ $config = array(
'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 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_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 'database_persistent' => false, // use database permanent connection (like server), may speed up your site
'database_encryption' => 'sha1',
// multiworld system (only TFS 0.3) // multiworld system (only TFS 0.3)
'multiworld' => false, // use multiworld system? 'multiworld' => false, // use multiworld system?

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';
@@ -189,14 +186,14 @@ clearstatcache();
if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) { if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) {
if(!file_exists(BASE . 'install/ip.txt')) { if(!file_exists(BASE . 'install/ip.txt')) {
$content = warning('AAC installation is disabled. To enable it make file <b>ip.txt</b> in install/ directory and put there your IP.<br/> $content = warning('AAC installation is disabled. To enable it make file <b>ip.txt</b> in install/ directory and put there your IP.<br/>
Your IP is:<br /><b>' . $_SERVER['REMOTE_ADDR'] . '</b>', true); Your IP is:<br /><b>' . get_browser_real_ip() . '</b>', true);
} }
else { else {
$file_content = trim(file_get_contents(BASE . 'install/ip.txt')); $file_content = trim(file_get_contents(BASE . 'install/ip.txt'));
$allow = false; $allow = false;
$listIP = preg_split('/\s+/', $file_content); $listIP = preg_split('/\s+/', $file_content);
foreach($listIP as $ip) { foreach($listIP as $ip) {
if($_SERVER['REMOTE_ADDR'] == $ip) { if(get_browser_real_ip() == $ip) {
$allow = true; $allow = true;
} }
} }

View File

@@ -79,6 +79,8 @@ else {
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN); $account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us'); $account_used->setCustomField('country', 'us');
$account_used->setCustomField('email_verified', 1);
if($db->hasColumn('accounts', 'group_id')) if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId()); $account_used->setCustomField('group_id', $groups->getHighestId());
if($db->hasColumn('accounts', 'type')) if($db->hasColumn('accounts', 'type'))
@@ -137,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>
@@ -45,4 +46,4 @@
<p style="text-align: center;"><?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?></p> <p style="text-align: center;"><?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?></p>
</div> </div>
</body> </body>
</html> </html>

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';

View File

@@ -97,8 +97,18 @@ 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']);
success($locale['step_finish_desc']); success($locale['step_finish_desc']);

View File

@@ -10,24 +10,16 @@ server {
# this is very important, be sure its in your nginx conf - it prevents access to logs etc. # this is very important, be sure its in your nginx conf - it prevents access to logs etc.
location ~ /system { location ~ /system {
deny all; deny all;
return 404;
}
location /vendor {
deny all;
return 404;
} }
# block .htaccess, CHANGELOG.md, composer.json etc. # block .htaccess, CHANGELOG.md, composer.json etc.
# this is to prevent finding software versions # this is to prevent finding software versions
location ~\.(ht|md|json|dist)$ { location ~\.(ht|md|json|dist)$ {
deny all; deny all;
return 404;
} }
# block git files and folders # block git files and folders
location ~ /\.git { location ~ /\.git {
return 404;
deny all; deny all;
} }

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,8 +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';
require_once LIBS . 'plugins.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

@@ -105,4 +105,8 @@ $config['clients'] = [
1316, 1316,
1320, 1320,
1321, 1321,
1322,
1330,
1332,
1340,
]; ];

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

@@ -972,12 +972,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;
} }
@@ -1268,6 +1275,39 @@ function escapeHtml($html) {
return htmlspecialchars($html); return htmlspecialchars($html);
} }
function getGuildNameById($id)
{
global $db;
$guild = $db->query('SELECT `name` FROM `guilds` WHERE `id` = ' . (int)$id);
if ($guild->rowCount() > 0) {
return $guild->fetchColumn();
}
return false;
}
function getGuildLogoById($id)
{
global $db;
$logo = 'default.gif';
$query = $db->query('SELECT `logo_name` FROM `guilds` WHERE `id` = ' . (int)$id);
if ($query->rowCount() == 1) {
$query = $query->fetch(PDO::FETCH_ASSOC);
$guildLogo = $query['logo_name'];
if (!empty($guildLogo) && file_exists('images/guilds/' . $guildLogo)) {
$logo = $guildLogo;
}
}
return BASE_URL . 'images/guilds/' . $logo;
}
function displayErrorBoxWithBackButton($errors, $action = null) { function displayErrorBoxWithBackButton($errors, $action = null) {
global $twig; global $twig;
$twig->display('error_box.html.twig', ['errors' => $errors]); $twig->display('error_box.html.twig', ['errors' => $errors]);

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);
@@ -48,13 +55,22 @@ define('HOOK_ACCOUNT_CREATE_AFTER_VOCATION', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_TOWNS', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_TOWNS', ++$i);
define('HOOK_ACCOUNT_CREATE_BEFORE_SUBMIT_BUTTON', ++$i); define('HOOK_ACCOUNT_CREATE_BEFORE_SUBMIT_BUTTON', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_FORM', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_FORM', ++$i);
define('HOOK_ACCOUNT_CREATE_POST', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_SUBMIT', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_SUBMIT', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_SAVED', ++$i);
define('HOOK_ACCOUNT_MANAGE_BEFORE_GENERAL_INFORMATION', ++$i);
define('HOOK_ACCOUNT_MANAGE_BEFORE_PUBLIC_INFORMATION', ++$i);
define('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS', ++$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';
class Hook class Hook
{ {
private $_name, $_type, $_file; private $_name, $_type, $_file;

View File

@@ -28,7 +28,8 @@ if($config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($
ob_start('ob_gzhandler'); ob_start('ob_gzhandler');
// cache // cache
require_once SYSTEM . 'libs/cache.php'; require_once LIBS . 'cache.php';
require_once LIBS . 'src/Cache.php';
$cache = Cache::getInstance(); $cache = Cache::getInstance();
// trim values we receive // trim values we receive
@@ -73,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);
@@ -116,13 +117,19 @@ if(!isset($config['highscores_ids_hidden']) || count($config['highscores_ids_hid
$config['highscores_ids_hidden'] = array(0); $config['highscores_ids_hidden'] = array(0);
} }
$config['account_create_character_create'] = config('account_create_character_create') && (!config('mail_enabled') || !config('account_mail_verify')); $config['account_mail_verify'] = config('account_mail_verify') && config('mail_enabled');
// POT // POT
require_once SYSTEM . 'libs/pot/OTS.php'; 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

@@ -71,7 +71,7 @@ class Forum
'post_smile' => 0, 'post_html' => 1, 'post_smile' => 0, 'post_html' => 1,
'post_date' => time(), 'post_date' => time(),
'last_edit_aid' => 0, 'edit_date' => 0, 'last_edit_aid' => 0, 'edit_date' => 0,
'post_ip' => $_SERVER['REMOTE_ADDR'] 'post_ip' => get_browser_real_ip()
))) { ))) {
$thread_id = $db->lastInsertId(); $thread_id = $db->lastInsertId();
$db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `first_post`=".(int) $thread_id." WHERE `id` = ".(int) $thread_id); $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `first_post`=".(int) $thread_id." WHERE `id` = ".(int) $thread_id);
@@ -93,7 +93,7 @@ class Forum
'post_smile' => $smile, 'post_smile' => $smile,
'post_html' => $html, 'post_html' => $html,
'post_date' => time(), 'post_date' => time(),
'post_ip' => $_SERVER['REMOTE_ADDR'] 'post_ip' => get_browser_real_ip()
)); ));
} }
public static function add_board($name, $description, $access, $guild, &$errors) public static function add_board($name, $description, $access, $guild, &$errors)

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'];
@@ -405,4 +398,60 @@ class Plugins {
return $string; return $string;
} }
/**
* Install menus
* Helper function for plugins
*
* @param string $templateName
* @param array $menus
*/
public static function installMenus($templateName, $menus, $clearOld = false)
{
global $db;
if ($clearOld) {
$db->query('DELETE FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($templateName));
}
// check if menus already exist
$query = $db->query('SELECT `id` FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($templateName) . ' LIMIT 1;');
if ($query->rowCount() > 0) {
return;
}
foreach ($menus as $category => $_menus) {
$i = 0;
foreach ($_menus as $name => $link) {
$color = '';
$blank = 0;
if (is_array($link)) {
if (isset($link['name'])) {
$name = $link['name'];
}
if (isset($link['color'])) {
$color = $link['color'];
}
if (isset($link['blank'])) {
$blank = $link['blank'] ? 1 : 0;
}
$link = $link['link'];
}
$insert_array = [
'template' => $templateName,
'name' => $name,
'link' => $link,
'category' => $category,
'ordering' => $i++,
'blank' => $blank,
'color' => $color,
];
$db->insert(TABLE_PREFIX . 'menu', $insert_array);
}
}
}
} }

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

@@ -167,8 +167,14 @@ abstract class OTS_Base_DB extends PDO implements IOTS_DB
$query = 'UPDATE '.$this->tableName($table).' SET '; $query = 'UPDATE '.$this->tableName($table).' SET ';
$count = count($fields); $count = count($fields);
for ($i = 0; $i < $count; $i++) for ($i = 0; $i < $count; $i++) {
$query.= $this->fieldName($fields[$i]).' = '.$this->quote($values[$i]).', '; $value = 'NULL';
if ($values[$i] !== null) {
$value = $this->quote($values[$i]);
}
$query.= $this->fieldName($fields[$i]).' = '.$value.', ';
}
$query = substr($query, 0, -2); $query = substr($query, 0, -2);
$query.=' WHERE ('; $query.=' WHERE (';
@@ -212,6 +218,30 @@ abstract class OTS_Base_DB extends PDO implements IOTS_DB
$this->exec($query); $this->exec($query);
return true; return true;
} }
public function addColumn($table, $column, $definition): void {
$this->exec('ALTER TABLE ' . $this->tableName($table) . ' ADD ' . $this->fieldName($column) . ' ' . $definition . ';');
}
public function modifyColumn($table, $column, $definition): void {
$this->exec('ALTER TABLE ' . $this->tableName($table) . ' MODIFY ' . $this->fieldName($column) . ' ' . $definition . ';');
}
public function changeColumn($table, $from, $to, $definition): void {
$this->exec('ALTER TABLE ' . $this->tableName($table) . ' CHANGE ' . $this->fieldName($from) . ' ' . $this->fieldName($to) . ' ' . $definition . ';');
}
public function dropColumn($table, $column): void {
$this->exec('ALTER TABLE ' . $this->tableName($table) . ' DROP COLUMN ' . $this->fieldName($column) . ';');
}
public function renameTable($from, $to): void {
$this->exec('RENAME TABLE ' . $this->tableName($from) . ' TO ' . $this->tableName($to) . ';');
}
public function dropTable($table, $ifExists = true): void {
$this->exec('DROP TABLE ' . ($ifExists ? 'IF EXISTS' : '') . ' ' . $this->tableName($table) . ';');
}
/** /**
* LIMIT/OFFSET clause for queries. * LIMIT/OFFSET clause for queries.
* *

View File

@@ -151,7 +151,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
} }
if($this->logged) { if($this->logged) {
log_append('database.log', $_SERVER['REQUEST_URI'] . PHP_EOL . $this->getLog()); $currentScript = $_SERVER['REQUEST_URI'] ?? $_SERVER['SCRIPT_FILENAME'];
log_append('database.log', $currentScript . PHP_EOL . $this->getLog());
} }
} }
@@ -219,6 +220,19 @@ class OTS_DB_MySQL extends OTS_Base_DB
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 '" . $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() {
foreach($this->has_table_cache as $key => $value) { foreach($this->has_table_cache as $key => $value) {
$this->hasTableInternal($key); $this->hasTableInternal($key);

View File

@@ -60,12 +60,7 @@ class OTS_House extends OTS_Row_DAO
private $tiles = array(); private $tiles = array();
public function load($id) { public function load($id) {
$this->data = $this->db->query('SELECT * FROM `houses` WHERE `id` = ' . $id )->fetch(); $this->data = $this->db->query('SELECT * FROM `houses` WHERE `id` = ' . $id )->fetch(PDO::FETCH_ASSOC);
foreach($this->data as $key => $value) {
if(is_numeric($key)) {
unset($this->data[$key]);
}
}
} }
public function find($name) public function find($name)

View File

@@ -15,11 +15,11 @@
/** /**
* Wrapper for monsters files DOMDocument. * Wrapper for monsters files DOMDocument.
* *
* <p> * <p>
* Note: as this class extends {@link http://www.php.net/manual/en/ref.dom.php DOMDocument class} and contains exacly file XML tree you can work on it as on normal DOM tree. * Note: as this class extends {@link http://www.php.net/manual/en/ref.dom.php DOMDocument class} and contains exacly file XML tree you can work on it as on normal DOM tree.
* </p> * </p>
* *
* @package POT * @package POT
* @version 0.1.3 * @version 0.1.3
* @property-read string $name Monster name. * @property-read string $name Monster name.
@@ -44,14 +44,14 @@ class OTS_Monster extends DOMDocument
{ {
$this->loaded = parent::loadXML($source, $options); $this->loaded = parent::loadXML($source, $options);
} }
public function loaded() public function loaded()
{ {
return $this->loaded; return $this->loaded;
} }
/** /**
* Returns monster name. * Returns monster name.
* *
* @return string Name. * @return string Name.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -62,7 +62,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns monster race. * Returns monster race.
* *
* @return string Race. * @return string Race.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -73,7 +73,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns amount of experience for killing this monster. * Returns amount of experience for killing this monster.
* *
* @return int Experience points. * @return int Experience points.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -84,7 +84,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns monster speed. * Returns monster speed.
* *
* @return int Speed. * @return int Speed.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -95,7 +95,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns amount of mana required to summon this monster. * Returns amount of mana required to summon this monster.
* *
* @return int|bool Mana required (false if not possible). * @return int|bool Mana required (false if not possible).
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -114,7 +114,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns monster HP. * Returns monster HP.
* *
* @return int Hit points. * @return int Hit points.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -125,28 +125,29 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns all monster flags (in format flagname => value). * Returns all monster flags (in format flagname => value).
* *
* @return array Flags. * @return array Flags.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
public function getFlags() public function getFlags()
{ {
$flags = array(); $flags = array();
// read all flags if ($this->documentElement->getElementsByTagName('flags')->item(0)) {
foreach( $this->documentElement->getElementsByTagName('flags')->item(0)->getElementsByTagName('flag') as $flag) foreach( $this->documentElement->getElementsByTagName('flags')->item(0)->getElementsByTagName('flag') as $flag)
{ {
$flag = $flag->attributes->item(0); $flag = $flag->attributes->item(0);
$flags[$flag->nodeName] = (int) $flag->nodeValue; $flags[$flag->nodeName] = (int) $flag->nodeValue;
} }
}
return $flags; return $flags;
} }
/** /**
* Returns specified flag value. * Returns specified flag value.
* *
* @param string $flag Flag. * @param string $flag Flag.
* @return int|bool Flag value (false if not set). * @return int|bool Flag value (false if not set).
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
@@ -169,7 +170,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns voices that monster can sound. * Returns voices that monster can sound.
* *
* @return array List of voices. * @return array List of voices.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -214,17 +215,17 @@ class OTS_Monster extends DOMDocument
$chance = 100000; $chance = 100000;
} }
} }
$count = $item->getAttribute('countmax'); $count = $item->getAttribute('countmax');
if(empty($count)) { if(empty($count)) {
$count = 1; $count = 1;
} }
$id = $item->getAttribute('id'); $id = $item->getAttribute('id');
if(empty($id)) { if(empty($id)) {
$id = $item->getAttribute('name'); $id = $item->getAttribute('name');
} }
$loot[] = array('id' => $id, 'count' => $count, 'chance' => $chance); $loot[] = array('id' => $id, 'count' => $count, 'chance' => $chance);
} }
} }
@@ -234,11 +235,11 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns all possible loot. * Returns all possible loot.
* *
* <p> * <p>
* In order to use this method you have to have global items list loaded. * In order to use this method you have to have global items list loaded.
* </p> * </p>
* *
* @version 0.1.0 * @version 0.1.0
* @since 0.1.0 * @since 0.1.0
* @return array List of item types. * @return array List of item types.
@@ -275,7 +276,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns all monster immunities. * Returns all monster immunities.
* *
* @return array Immunities. * @return array Immunities.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -306,7 +307,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Checks if monster has given immunity. * Checks if monster has given immunity.
* *
* @param string $name Immunity to check. * @param string $name Immunity to check.
* @return bool Immunity state. * @return bool Immunity state.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
@@ -334,7 +335,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns monster defense rate. * Returns monster defense rate.
* *
* @return int Defense rate. * @return int Defense rate.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -353,7 +354,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns monster armor. * Returns monster armor.
* *
* @return int Armor rate. * @return int Armor rate.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -372,7 +373,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns list of special defenses. * Returns list of special defenses.
* *
* @return array List of defense effects. * @return array List of defense effects.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -396,7 +397,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns list of monster attacks. * Returns list of monster attacks.
* *
* @return array List of attafck effects. * @return array List of attafck effects.
* @throws DOMException On DOM operation error. * @throws DOMException On DOM operation error.
*/ */
@@ -420,7 +421,7 @@ class OTS_Monster extends DOMDocument
/** /**
* Magic PHP5 method. * Magic PHP5 method.
* *
* @version 0.1.0 * @version 0.1.0
* @since 0.1.0 * @since 0.1.0
* @param string $name Property name. * @param string $name Property name.
@@ -481,11 +482,11 @@ class OTS_Monster extends DOMDocument
/** /**
* Returns string representation of XML. * Returns string representation of XML.
* *
* <p> * <p>
* If any display driver is currently loaded then it uses it's method. Otherwise just returns monster XML content. * If any display driver is currently loaded then it uses it's method. Otherwise just returns monster XML content.
* </p> * </p>
* *
* @version 0.1.3 * @version 0.1.3
* @since 0.1.0 * @since 0.1.0
* @return string String representation of object. * @return string String representation of object.

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.
* *
@@ -763,21 +765,29 @@ class OTS_Player extends OTS_Row_DAO
$this->data['deleted'] = (int) $deleted; $this->data['deleted'] = (int) $deleted;
} }
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']) )
{ {
throw new E_OTS_NotLoaded(); throw new E_OTS_NotLoaded();
} }
return $this->data['online'] == 1; return $this->data['online'] == 1;
} }
public function getCreated() public function getCreated()
{ {
@@ -1745,11 +1755,6 @@ class OTS_Player extends OTS_Row_DAO
*/ */
public function getConditions() public function getConditions()
{ {
if( !isset($this->data['conditions']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['conditions']; return $this->data['conditions'];
} }

View File

@@ -0,0 +1,5 @@
<?php
namespace MyAAC;
class Cache extends \Cache {}

View File

@@ -0,0 +1,5 @@
<?php
namespace MyAAC;
class Plugins extends \Plugins {}

View File

@@ -33,7 +33,7 @@ class Visitors
$this->sessionTime = $sessionTime; $this->sessionTime = $sessionTime;
$this->cleanVisitors(); $this->cleanVisitors();
$ip = $_SERVER['REMOTE_ADDR']; $ip = get_browser_real_ip();
if($this->visitorExists($ip)) if($this->visitorExists($ip))
$this->updateVisitor($ip, $_SERVER['REQUEST_URI']); $this->updateVisitor($ip, $_SERVER['REQUEST_URI']);
else else

View File

@@ -74,7 +74,7 @@ else
else else
$tmp = array(); $tmp = array();
$ip = $_SERVER['REMOTE_ADDR']; $ip = get_browser_real_ip();
$t = isset($tmp[$ip]) ? $tmp[$ip] : NULL; $t = isset($tmp[$ip]) ? $tmp[$ip] : NULL;
} }
@@ -88,28 +88,32 @@ else
&& (!isset($t) || $t['attempts'] < 5) && (!isset($t) || $t['attempts'] < 5)
) )
{ {
session_regenerate_id(); if (config('mail_enabled') && config('account_mail_verify') && (int)$account_logged->getCustomField('email_verified') !== 1) {
setSession('account', $account_logged->getId()); $errors[] = 'Your account is not verified. Please verify your email address. If the message is not coming check the SPAM folder in your E-Mail client.';
setSession('password', encrypt(($config_salt_enabled ? $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 { else {
$account_logged->setCustomField('web_lastlogin', time()); session_regenerate_id();
} setSession('account', $account_logged->getId());
setSession('password', encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password));
if ($remember_me) {
setSession('remember_me', true);
}
$hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me)); $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 else
{ {

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

@@ -33,6 +33,10 @@ else
if(empty($errors)) if(empty($errors))
{ {
if(!Validator::characterName($name)) {
$errors[] = Validator::getLastError();
}
if(!admin() && !Validator::newCharacterName($name)) if(!admin() && !Validator::newCharacterName($name))
$errors[] = Validator::getLastError(); $errors[] = Validator::getLastError();
} }

View File

@@ -59,7 +59,7 @@ else
$new_sex_str = $config['genders'][$new_sex]; $new_sex_str = $config['genders'][$new_sex];
$player->save(); $player->save();
$account_logged->setCustomField("premium_points", $points - $config['account_change_character_name_points']); $account_logged->setCustomField('premium_points', $points - $config['account_change_character_sex_points']);
$account_logged->logAction('Changed sex on character <b>' . $player->getName() . '</b> from <b>' . $old_sex_str . '</b> to <b>' . $new_sex_str . '</b>.'); $account_logged->logAction('Changed sex on character <b>' . $player->getName() . '</b> from <b>' . $old_sex_str . '</b> to <b>' . $new_sex_str . '</b>.');
$twig->display('success.html.twig', array( $twig->display('success.html.twig', array(
'title' => 'Character Sex Changed', 'title' => 'Character Sex Changed',

View File

@@ -29,11 +29,13 @@ else
$account = new OTS_Account(); $account = new OTS_Account();
$account->load($query['id']); $account->load($query['id']);
if ($account->isLoaded()) { if ($account->isLoaded()) {
$db->update('accounts', ['email_verified' => '1'], ['email_hash' => $hash]);
success('You have now verified your e-mail, this will increase the security of your account. Thank you for doing this. You can now <a href=' . getLink('account/manage') . '>log in</a>.');
$hooks->trigger(HOOK_EMAIL_CONFIRMED, ['account' => $account]); $hooks->trigger(HOOK_EMAIL_CONFIRMED, ['account' => $account]);
} }
} }
else {
$db->update('accounts', array('email_verified' => '1'), array('email_hash' => $hash)); error('Link has expired.');
success('You have now verified your e-mail, this will increase the security of your account. Thank you for doing this.'); }
} }
?>

View File

@@ -167,37 +167,31 @@ function getBanType($typeId)
function getPlayerNameByAccount($id) function getPlayerNameByAccount($id)
{ {
global $vowels, $ots, $db; global $db;
if(is_numeric($id)) if(!is_numeric($id)) {
{ return '';
$player = new OTS_Player(); }
$player->load($id);
if($player->isLoaded())
return $player->getName();
else
{
$playerQuery = $db->query('SELECT `id` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;')->fetch();
$tmp = "*Error*"; $playerQuery = $db->query('SELECT `name` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;');
/* if ($playerQuery->rowCount() == 0) {
$acco = new OTS_Account(); return "*Error*";
$acco->load($id); }
if(!$acco->isLoaded())
return "Unknown name";
foreach($acco->getPlayersList() as $p) $playerQuery = $playerQuery->fetch();
{ return $playerQuery['name'];
$player= new OTS_Player(); }
$player->find($p);*/
$player->load($playerQuery['id']);
//echo 'id gracza = ' . $p . '<br/>';
if($player->isLoaded())
$tmp = $player->getName();
// break;
//}
return $tmp; function getPlayerNameById($id)
} {
if (!is_numeric($id)) {
return '';
}
global $db;
$playerQuery = $db->query('SELECT `name` FROM `players` WHERE `id` = ' . $id);
if ($playerQuery->rowCount()) {
$player = $playerQuery->fetch(PDO::FETCH_ASSOC);
return $player['name'];
} }
return ''; return '';

View File

@@ -137,7 +137,13 @@ if($save)
$params['account_id'] = $_POST['account']; $params['account_id'] = $_POST['account'];
} }
/**
* two hooks for compatibility
*/
$hooks->trigger(HOOK_ACCOUNT_CREATE_AFTER_SUBMIT, $params); $hooks->trigger(HOOK_ACCOUNT_CREATE_AFTER_SUBMIT, $params);
if (!$hooks->trigger(HOOK_ACCOUNT_CREATE_POST, $params)) {
return;
}
if(config('account_create_character_create')) { if(config('account_create_character_create')) {
$character_name = isset($_POST['name']) ? stripslashes(ucwords(strtolower($_POST['name']))) : null; $character_name = isset($_POST['name']) ? stripslashes(ucwords(strtolower($_POST['name']))) : null;
@@ -167,6 +173,8 @@ if($save)
$new_account->setEMail($email); $new_account->setEMail($email);
$new_account->save(); $new_account->save();
$hooks->trigger(HOOK_ACCOUNT_CREATE_AFTER_SAVED, ['account' => $new_account]);
if($config_salt_enabled) if($config_salt_enabled)
$new_account->setCustomField('salt', $salt); $new_account->setCustomField('salt', $salt);
@@ -211,6 +219,9 @@ if($save)
if(_mail($email, 'New account on ' . $config['lua']['serverName'], $body_html)) if(_mail($email, 'New account on ' . $config['lua']['serverName'], $body_html))
{ {
echo 'Your account has been created.<br/><br/>'; echo 'Your account has been created.<br/><br/>';
warning("Before you can login - you need to verify your E-Mail. The verification link has been sent to $email. If the message is not coming - remember to check the SPAM folder.");
$twig->display('success.html.twig', array( $twig->display('success.html.twig', array(
'title' => 'Account Created', 'title' => 'Account Created',
'description' => 'Your account ' . $account_type . ' is <b>' . $tmp_account . '</b><br/>You will need the account ' . $account_type . ' and your password to play on ' . configLua('serverName') . '. 'description' => 'Your account ' . $account_type . ' is <b>' . $tmp_account . '</b><br/>You will need the account ' . $account_type . ' and your password to play on ' . configLua('serverName') . '.
@@ -227,15 +238,6 @@ if($save)
} }
else else
{ {
if(config('account_create_character_create')) {
// character creation
$character_created = $createCharacter->doCreate($character_name, $character_sex, $character_vocation, $character_town, $new_account, $errors);
if (!$character_created) {
error('There was an error creating your character. Please create your character later in account management page.');
error(implode(' ', $errors));
}
}
if($config['account_create_auto_login']) { if($config['account_create_auto_login']) {
$_POST['account_login'] = USE_ACCOUNT_NAME ? $account_name : $account_id; $_POST['account_login'] = USE_ACCOUNT_NAME ? $account_name : $account_id;
$_POST['password_login'] = $password2; $_POST['password_login'] = $password2;
@@ -280,6 +282,15 @@ if($save)
} }
} }
if(config('account_create_character_create')) {
// character creation
$character_created = $createCharacter->doCreate($character_name, $character_sex, $character_vocation, $character_town, $new_account, $errors);
if (!$character_created) {
error('There was an error creating your character. Please create your character later in account management page.');
error(implode(' ', $errors));
}
}
return; return;
} }
} }
@@ -291,7 +302,9 @@ if($config['account_country_recognize']) {
$country_recognized = $country_session; $country_recognized = $country_session;
} }
else { else {
$info = json_decode(@file_get_contents('http://ipinfo.io/' . $_SERVER['REMOTE_ADDR'] . '/geo'), true); ini_set('default_socket_timeout', 5);
$info = json_decode(@file_get_contents('https://ipinfo.io/' . get_browser_real_ip() . '/geo'), true);
if(isset($info['country'])) { if(isset($info['country'])) {
$country_recognized = strtolower($info['country']); $country_recognized = strtolower($info['country']);
setSession('country', $country_recognized); setSession('country', $country_recognized);

View File

@@ -23,7 +23,7 @@ if(Forum::canPost($account_logged))
if(isset($thread['id'])) if(isset($thread['id']))
{ {
$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']) . '">'.$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;

View File

@@ -12,6 +12,7 @@ defined('MYAAC') or die('Direct access not allowed!');
if(!Forum::isModerator()) { if(!Forum::isModerator()) {
echo 'You are not logged in or you are not moderator.'; echo 'You are not logged in or you are not moderator.';
return;
} }
$save = isset($_REQUEST['save']) && (int)$_REQUEST['save'] == 1; $save = isset($_REQUEST['save']) && (int)$_REQUEST['save'] == 1;

View File

@@ -24,7 +24,7 @@ if(Forum::canPost($account_logged))
if(isset($thread['id']) && Forum::hasAccess($thread['section'])) if(isset($thread['id']) && Forum::hasAccess($thread['section']))
{ {
echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread_id) . '">'.$thread['post_topic'].'</a> >> <b>Post new reply</b><br /><h3>'.$thread['post_topic'].'</h3>'; echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread_id) . '">'.htmlspecialchars($thread['post_topic']).'</a> >> <b>Post new reply</b><br /><h3>'.htmlspecialchars($thread['post_topic']).'</h3>';
$quote = isset($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : NULL; $quote = isset($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : NULL;
$text = isset($_REQUEST['text']) ? stripslashes(trim($_REQUEST['text'])) : NULL; $text = isset($_REQUEST['text']) ? stripslashes(trim($_REQUEST['text'])) : NULL;
@@ -37,7 +37,7 @@ if(Forum::canPost($account_logged))
if (!superAdmin()) { if (!superAdmin()) {
$html = 0; $html = 0;
} }
if(isset($_REQUEST['quote'])) if(isset($_REQUEST['quote']))
{ {
$quoted_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $quote)->fetchAll(); $quoted_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $quote)->fetchAll();

View File

@@ -65,7 +65,7 @@ if(Forum::canPost($account_logged))
} }
if (count($errors) == 0) { if (count($errors) == 0) {
$saved = true; $saved = true;
$db->query("INSERT INTO `" . FORUM_TABLE_PREFIX . "forum` (`first_post` ,`last_post` ,`section` ,`replies` ,`views` ,`author_aid` ,`author_guid` ,`post_text` ,`post_topic` ,`post_smile`, `post_html` ,`post_date` ,`last_edit_aid` ,`edit_date`, `post_ip`) VALUES ('0', '" . time() . "', '" . (int)$section_id . "', '0', '0', '" . $account_logged->getId() . "', '" . (int)$char_id . "', " . $db->quote($text) . ", " . $db->quote($post_topic) . ", '" . (int)$smile . "', '" . (int)$html . "', '" . time() . "', '0', '0', '" . $_SERVER['REMOTE_ADDR'] . "')"); $db->query("INSERT INTO `" . FORUM_TABLE_PREFIX . "forum` (`first_post` ,`last_post` ,`section` ,`replies` ,`views` ,`author_aid` ,`author_guid` ,`post_text` ,`post_topic` ,`post_smile`, `post_html` ,`post_date` ,`last_edit_aid` ,`edit_date`, `post_ip`) VALUES ('0', '" . time() . "', '" . (int)$section_id . "', '0', '0', '" . $account_logged->getId() . "', '" . (int)$char_id . "', " . $db->quote($text) . ", " . $db->quote($post_topic) . ", '" . (int)$smile . "', '" . (int)$html . "', '" . time() . "', '0', '0', '" . get_browser_real_ip() . "')");
$thread_id = $db->lastInsertId(); $thread_id = $db->lastInsertId();
$db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `first_post`=" . (int)$thread_id . " WHERE `id` = " . (int)$thread_id); $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `first_post`=" . (int)$thread_id . " WHERE `id` = " . (int)$thread_id);
header('Location: ' . getForumThreadLink($thread_id)); header('Location: ' . getForumThreadLink($thread_id));

View File

@@ -35,7 +35,7 @@ for($i = 0; $i < $threads_count['threads_count'] / $config['forum_threads_per_pa
$links_to_pages .= '<b>'.($i + 1).' </b>'; $links_to_pages .= '<b>'.($i + 1).' </b>';
} }
echo '<a href="' . getLink('forum') . '">Boards</a> >> <b>'.$sections[$section_id]['name'].'</b>'; echo '<a href="' . getLink('forum') . '">Boards</a> >> <b>'.$sections[$section_id]['name'].'</b>';
if(!$sections[$section_id]['closed'] || Forum::isModerator()) if($logged && (!$sections[$section_id]['closed'] || Forum::isModerator()))
{ {
echo '<br /><br /> echo '<br /><br />
<a href="?subtopic=forum&action=new_thread&section_id='.$section_id.'"><img src="images/forum/topic.gif" border="0" /></a>'; <a href="?subtopic=forum&action=new_thread&section_id='.$section_id.'"><img src="images/forum/topic.gif" border="0" /></a>';
@@ -62,7 +62,7 @@ if(isset($last_threads[0]))
if(Forum::isModerator()) if(Forum::isModerator())
{ {
echo '<a href="?subtopic=forum&action=move_thread&id='.$thread['id'].'"\')"><span style="color:darkgreen">[MOVE]</span></a>'; echo '<a href="?subtopic=forum&action=move_thread&id='.$thread['id'].'"\')"><span style="color:darkgreen">[MOVE]</span></a>';
echo '<a href="?subtopic=forum&action=remove_post&id='.$thread['id'].'" onclick="return confirm(\'Are you sure you want remove thread > '.$thread['post_topic'].' <?\')"><span style="color: red">[REMOVE]</span></a> '; echo '<a href="?subtopic=forum&action=remove_post&id='.$thread['id'].'" onclick="return confirm(\'Are you sure you want remove thread > '.htmlspecialchars($thread['post_topic']).' <?\')"><span style="color: red">[REMOVE]</span></a> ';
} }
$player->load($thread['player_id']); $player->load($thread['player_id']);
@@ -73,7 +73,7 @@ if(isset($last_threads[0]))
$player_account = $player->getAccount(); $player_account = $player->getAccount();
$canEditForum = $player_account->hasFlag(FLAG_CONTENT_FORUM) || $player_account->isAdmin(); $canEditForum = $player_account->hasFlag(FLAG_CONTENT_FORUM) || $player_account->isAdmin();
echo '<a href="' . getForumThreadLink($thread['id']) . '">'.($canEditForum ? $thread['post_topic'] : htmlspecialchars($thread['post_topic'])) . '</a><br /><small>'.($canEditForum ? substr(strip_tags($thread['post_text']), 0, 50) : htmlspecialchars(substr($thread['post_text'], 0, 50))).'...</small></td><td>' . getPlayerLink($thread['name']) . '</td><td>'.(int) $thread['replies'].'</td><td>'.(int) $thread['views'].'</td><td>'; echo '<a href="' . getForumThreadLink($thread['id']) . '">'.htmlspecialchars($thread['post_topic']) . '</a><br /><small>'.($canEditForum ? substr(strip_tags($thread['post_text']), 0, 50) : htmlspecialchars(substr($thread['post_text'], 0, 50))).'...</small></td><td>' . getPlayerLink($thread['name']) . '</td><td>'.(int) $thread['replies'].'</td><td>'.(int) $thread['views'].'</td><td>';
if($thread['last_post'] > 0) if($thread['last_post'] > 0)
{ {
$last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['id']." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch(); $last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['id']." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch();
@@ -87,7 +87,7 @@ if(isset($last_threads[0]))
echo '</td></tr>'; echo '</td></tr>';
} }
echo '</table>'; echo '</table>';
if(!$sections[$section_id]['closed'] || Forum::isModerator()) if($logged && (!$sections[$section_id]['closed'] || Forum::isModerator()))
echo '<br /><a href="?subtopic=forum&action=new_thread&section_id='.$section_id.'"><img src="images/forum/topic.gif" border="0" /></a>'; echo '<br /><a href="?subtopic=forum&action=new_thread&section_id='.$section_id.'"><img src="images/forum/topic.gif" border="0" /></a>';
} }
else else

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

@@ -30,10 +30,12 @@ if($config['highscores_vocation_box'] && isset($vocation))
if(strtolower($name) == $vocation) { if(strtolower($name) == $vocation) {
$add_vocs = array($id); $add_vocs = array($id);
$i = $id + $config['vocations_amount']; if ($id !== 0) {
while(isset($config['vocations'][$i])) { $i = $id + $config['vocations_amount'];
$add_vocs[] = $i; while(isset($config['vocations'][$i])) {
$i += $config['vocations_amount']; $add_vocs[] = $i;
$i += $config['vocations_amount'];
}
} }
$add_sql = 'AND `vocation` IN (' . implode(', ', $add_vocs) . ')'; $add_sql = 'AND `vocation` IN (' . implode(', ', $add_vocs) . ')';
@@ -355,7 +357,7 @@ if($config['highscores_vocation_box'])
<tr bgcolor="'.$config['lightborder'].'"> <tr bgcolor="'.$config['lightborder'].'">
<td> <td>
<a href="' . getLink('highscores') . '/' . $list . '" class="size_xs">[ALL]</A><BR>'; <a href="' . getLink('highscores') . '/' . $list . '" class="size_xs">[ALL]</A><BR>';
for($i = 1; $i <= $config['vocations_amount']; $i++) { for($i = 0; $i <= $config['vocations_amount']; $i++) {
echo '<a href="' . getLink('highscores') . '/' . $list . '/' . strtolower($config_vocations[$i]) . '" class="size_xs">' . $config_vocations[$i] . '</a><br/>'; echo '<a href="' . getLink('highscores') . '/' . $list . '/' . strtolower($config_vocations[$i]) . '" class="size_xs">' . $config_vocations[$i] . '</a><br/>';
} }
echo ' echo '

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

@@ -142,10 +142,14 @@ function updateStatus() {
} }
} }
$status['uptime'] = $serverStatus->getUptime(); $uptime = $status['uptime'] = $serverStatus->getUptime();
$h = floor($status['uptime'] / 3600); $m = date('m', $uptime);
$m = floor(($status['uptime'] - $h * 3600) / 60); $m = $m > 1 ? "$m months, " : ($m == 1 ? 'month, ' : '');
$status['uptimeReadable'] = $h . 'h ' . $m . 'm'; $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);
} }
} }
} }
@@ -147,7 +147,7 @@ function get_template_menus() {
$menus = array(); $menus = array();
foreach($result as $menu) { foreach($result as $menu) {
$link_full = strpos(trim($menu['link']), 'http') === 0 ? $menu['link'] : getLink($menu['link']); $link_full = strpos(trim($menu['link']), 'http') === 0 ? $menu['link'] : getLink($menu['link']);
$menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'link_full' => $link_full, 'blank' => $menu['blank'] == 1, 'color' => $menu['color']); $menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'link_full' => $link_full, 'blank' => $menu['blank'] == 1, 'target_blank' => ($menu['blank'] == 1 ? ' target="blank"' : ''), 'color' => $menu['color']);
} }
$new_menus = array(); $new_menus = array();

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>
@@ -108,4 +111,4 @@ If you do not want to specify a certain field, just leave it blank.<br/><br/>
</table> </table>
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -130,7 +130,7 @@
{{ hook('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1') }} {{ hook('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1') }}
{% if (not config.mail_enabled or not config.account_mail_verify) and config.account_create_character_create %} {% if config.account_create_character_create %}
<tr> <tr>
<td> <td>
<div class="TableShadowContainerRightTop"> <div class="TableShadowContainerRightTop">

View File

@@ -86,6 +86,7 @@
</div> </div>
<br/><br/> <br/><br/>
{% endif %} {% endif %}
{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_GENERAL_INFORMATION') }}
<a name="General+Information"></a> <a name="General+Information"></a>
<h2>General Information</h2> <h2>General Information</h2>
<table width="100%"> <table width="100%">
@@ -122,6 +123,7 @@
{% endautoescape %} {% endautoescape %}
</table> </table>
<br/> <br/>
{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_PUBLIC_INFORMATION') }}
<a name="Public+Information"></a> <a name="Public+Information"></a>
<h2>Public Information</h2> <h2>Public Information</h2>
<table width="100%"> <table width="100%">
@@ -139,8 +141,9 @@
{% include('buttons.base.html.twig') %} {% include('buttons.base.html.twig') %}
</form> </form>
<br/> <br/>
{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS') }}
<a name="Account+Logs" ></a> <a name="Account+Logs" ></a>
<h2>Action Log</h2> <h2>Account Logs</h2>
<table> <table>
<tr bgcolor="{{ config.vdarkborder }}" class="white"> <tr bgcolor="{{ config.vdarkborder }}" class="white">
<th>Action</th><th>Date</th><th>IP</th> <th>Action</th><th>Date</th><th>IP</th>
@@ -158,6 +161,7 @@
{% endautoescape %} {% endautoescape %}
</table> </table>
<br/> <br/>
{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_CHARACTERS') }}
<a name="Characters" ></a> <a name="Characters" ></a>
<h2>Character list: {{ players|length }} characters.</h2> <h2>Character list: {{ players|length }} characters.</h2>
<table> <table>

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

@@ -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

@@ -49,7 +49,7 @@
<table width="100%"> <table width="100%">
<tr bgcolor="{{ config.vdarkborder }}"> <tr bgcolor="{{ config.vdarkborder }}">
<td colspan="2"> <td colspan="2">
<span style="color: white"><b>Last 5 posts from thread: {{ topic|raw }}</b></span> <span style="color: white"><b>Last 5 posts from thread: {{ topic }}</b></span>
</td> </td>
</tr> </tr>
{% set i = 0 %} {% set i = 0 %}

View File

@@ -1,6 +1,6 @@
<div class="NewsHeadline"> <div class="NewsHeadline">
<div class="NewsHeadlineBackground" style="background-image:url({{ template_path }}/images/news/newsheadline_background.gif)"> <div class="NewsHeadlineBackground" style="background-image:url({{ template_path }}/images/news/newsheadline_background.gif)">
<img src="{{ template_path }}/images/news/icon_{{ icon }}.gif" class="NewsHeadlineIcon" /> <img src="{{ constant('BASE_URL') }}images/news/icon_{{ icon }}.gif" class="NewsHeadlineIcon" />
<div class="NewsHeadlineDate">{{ date|date(config.news_date_format) }} - </div> <div class="NewsHeadlineDate">{{ date|date(config.news_date_format) }} - </div>
<div class="NewsHeadlineText">{{ title }}</div> <div class="NewsHeadlineText">{{ title }}</div>
{% if config.news_author and author is not empty %} {% if config.news_author and author is not empty %}
@@ -20,4 +20,4 @@
</tr> </tr>
{% endif %} {% endif %}
</table> </table>
<br/> <br/>

View File

@@ -5,11 +5,11 @@
{% set i = 0 %} {% set i = 0 %}
{% for ticker in tickers %} {% for ticker in tickers %}
<tr bgcolor="{{ getStyle(i) }}"> <tr bgcolor="{{ getStyle(i) }}">
<td style="width: 16px;"><img src="{{ template_path }}/images/news/icon_{{ ticker.icon }}_small.gif"/></td> <td style="width: 16px;"><img src="{{ constant('BASE_URL') }}images/news/icon_{{ ticker.icon }}_small.gif"/></td>
<td style="width: 80px;">{{ ticker.date|date("j M Y") }}</td> <td style="width: 80px;">{{ ticker.date|date("j M Y") }}</td>
<td>{{ ticker.body|raw }}</td> <td>{{ ticker.body|raw }}</td>
</tr> </tr>
{% set i = i + 1 %} {% set i = i + 1 %}
{% endfor %} {% endfor %}
</table> </table>
<br/> <br/>

View File

@@ -1,24 +1,14 @@
<div class="TableContainer"> <table border="0" cellspacing="1" cellpadding="4" width="100%">
<div class="CaptionContainer"> <thead>
<div class="CaptionInnerContainer"> <tr bgcolor="{{ config.vdarkborder }}">
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span> <td colspan="3" class="white"><b>{{ title|raw }}</b></td>
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span> </tr>
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span> </thead>
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span> <tbody>
<div class="Text" >{{ title|raw }}</div> <tr style="background-color: {% if background is not null %}{{ background }}{% else %}{{ config.lightborder }}{% endif %}">
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span> <td>
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span> {{ content|raw }}
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span> </td>
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span> </tr>
</div> </tbody>
</div> </table>
<table class="Table5" cellpadding="0" cellspacing="0" style="background-color: {{ config.lightborder }}">
<tr>
<td>
<div class="InnerTableContainer">
{{ content|raw }}
</div>
</td>
</tr>
</table>
</div>

View File

@@ -83,3 +83,5 @@ $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]);

View File

@@ -111,6 +111,7 @@
</div> </div>
<br/><br/> <br/><br/>
{% endif %} {% endif %}
{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_GENERAL_INFORMATION') }}
<a name="General+Information" ></a> <a name="General+Information" ></a>
<div class="TopButtonContainer"> <div class="TopButtonContainer">
<div class="TopButton"> <div class="TopButton">
@@ -236,6 +237,7 @@
</table> </table>
</div> </div>
<br/> <br/>
{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_PUBLIC_INFORMATION') }}
<a name="Public+Information"></a> <a name="Public+Information"></a>
<div class="TopButtonContainer"> <div class="TopButtonContainer">
<div class="TopButton"> <div class="TopButton">
@@ -313,6 +315,7 @@
</table> </table>
</div> </div>
<br/> <br/>
{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS') }}
<a name="Account+Logs" ></a> <a name="Account+Logs" ></a>
<div class="TopButtonContainer"> <div class="TopButtonContainer">
<div class="TopButton"> <div class="TopButton">
@@ -384,6 +387,7 @@
</table> </table>
</div> </div>
<br/> <br/>
{{ hook('HOOK_ACCOUNT_MANAGE_BEFORE_CHARACTERS') }}
<a name="Characters" ></a> <a name="Characters" ></a>
<div class="TopButtonContainer"> <div class="TopButtonContainer">
<div class="TopButton" > <div class="TopButton" >
@@ -516,4 +520,4 @@
</tr> </tr>
</table> </table>
</div> </div>
<br/><br/> <br/><br/>

View File

@@ -1,8 +1,19 @@
{% spaceless %} {% apply spaceless %}
<div class="BigButton" style="background-image:url({{ template_path }}/images/global/buttons/button_blue.gif)">
<div onMouseOver="MouseOverBigButton(this);" onMouseOut="MouseOutBigButton(this);"> {% set tmp_image = 'sbutton' %}
<div class="BigButtonOver" style="background-image:url({{ template_path }}/images/global/buttons/{% if button_color is defined and button_color == 'green' %}button_green{% else %}button_blue_over{% endif %}.gif);" ></div>
<input class="BigButtonText" type="submit" value="{{ button_name }}"> {% if button_color is defined %}
{% if button_color == 'green' %}
{% set tmp_image = 'sbutton_green' %}
{% elseif button_color == 'red' %}
{% set tmp_image = 'sbutton_red' %}
{% endif %}
{% endif %}
<div class="BigButton" style="background-image:url({{ template_path }}/images/global/buttons/{{ tmp_image }}.gif)">
<div onMouseOver="MouseOverBigButton(this);" onMouseOut="MouseOutBigButton(this);">
<div class="BigButtonOver" style="background-image:url({{ template_path }}/images/global/buttons/{{ tmp_image }}_over.gif);" ></div>
<input class="BigButtonText" {% if noSubmit is not defined %}type="submit"{% endif %} value="{{ button_name }}">
</div>
</div> </div>
</div> {% endapply %}
{% endspaceless %}

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

@@ -0,0 +1,24 @@
<div class="TableContainer">
<div class="CaptionContainer">
<div class="CaptionInnerContainer">
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
<div class="Text" >{{ title|raw }}</div>
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
</div>
</div>
<table class="{% if tableClass is not null %}{{ tableClass }}{% else %}Table3{% endif %}" cellpadding="0" cellspacing="0" style="background-color: {% if background is not null %}{{ background }}{% else %}{{ config.lightborder }}{% endif %}">
<tr>
<td>
<div class="InnerTableContainer">
{{ content|raw }}
</div>
</td>
</tr>
</table>
</div>

View File

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