Compare commits

..

1 Commits

Author SHA1 Message Date
slawkens
e106ef7f6c First attempt 2025-09-28 16:58:37 +02:00
97 changed files with 848 additions and 1599 deletions

View File

@@ -22,7 +22,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
php-versions: [ '8.1', '8.2', '8.3', '8.4', '8.5' ] php-versions: [ '8.1', '8.2', '8.3', '8.4' ]
ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration) ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration)
name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }}) name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }})
steps: steps:

3
.gitignore vendored
View File

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

View File

@@ -1,69 +1,5 @@
# Changelog # Changelog
## [1.8.6 - 14.12.2025]
### Added
* Added hook for adding custom rules to validate new character name (https://github.com/slawkens/myaac/commit/8e6749c59984631288e8e9803819b2f0ff389761)
### Fixed
* Highscores: Fix ordering by different skills (Adjust order by desc: skill_tries, manaspent, experience) - More exact results (https://github.com/slawkens/myaac/commit/c86257e6dacbad773aa09c0958eeaa106a967f2d)
* Fix exception shown on first install, when there is no vendor - Before it displayed 500 white page, now it display the exception (https://github.com/slawkens/myaac/commit/18a1178e4b93607a350259679e0366cb83fb4126)
* Fix typo $up -> $down, in migration nr 7, was failing due that (https://github.com/slawkens/myaac/commit/fd74f01291d0e9cdb92ee1b95021c9d7b591ad7c)
### Changed
* Ini set html_errors = 0, to show html code in exceptions (https://github.com/slawkens/myaac/commit/9ed06782e67772826d927ad847a077b99df5060d)
## [1.8.5 - 21.11.2025]
### Added
* New Setting: Account Countries Most Popular (https://github.com/slawkens/myaac/commit/946364f59d7cd01472877108ab27ec78fb28307a)
### Changed
* Status: Write to status-error.log if there is connection error (https://github.com/slawkens/myaac/commit/780d4ccef741c1dd45a00bfc121fba9f1a175313)
* Settings: escapeHtml in values (support for html code) (https://github.com/slawkens/myaac/commit/5861efdbe900ccd35309913af0c0a5f3d4cdc1a8)
* News Page: Don't display hidden news for admin - it's confusing (https://github.com/slawkens/myaac/commit/175e97828b9a08ec3080cc8d3fb4eb3f1c08649f)
* Plugins System: Add plugin:remove + plugin:delete as alias for plugin:uninstall + plugin:activate/deactivate (https://github.com/slawkens/myaac/commit/6367054487368c92741bfd1dc7c70c52aea9ee87, https://github.com/slawkens/myaac/commit/baec6c9ebf5c342b3b2f7123427c6ba21dbb93bc)
### Fixed
* Status: Fix $status['uptimeReadable'], was totally wrong (https://github.com/slawkens/myaac/commit/0a6d44bf21417562491aabc93543a2bc3a44b2df)
* Guilds: Detect "deletion" column in guilds show/delete (https://github.com/slawkens/myaac/commit/6775a061bebc9ff449522f0173556d4a7a44fa5e, https://github.com/slawkens/myaac/commit/603d860b56bc7418db09e206f40aa06d0682c00e)
* General: Ensure some cache folders & index.html exists (https://github.com/slawkens/myaac/commit/730a0f29124811f525207c24c06eb0d088fa3434)
## [1.8.4 - 27.10.2025]
### Changed
* Reimport myaac_ tables on every install, this fixes errors when one table is missing or is duplicated (https://github.com/slawkens/myaac/commit/2580edadf84779f09fd395c21f92019b2c762f83)
* Use custom env init on migrate, migrate:run and migrate:to (https://github.com/slawkens/myaac/commit/13ea68cc0c9349380c8e4051d702a6c2c8256f44, https://github.com/slawkens/myaac/commit/07fd034fe4cb0ffdb88667b1e400f414d0c6d06f)
### Fixed
* Show if there is mysql error on import schema (https://github.com/slawkens/myaac/commit/44110a9496b4385e42c31b75de301037e711b6c3)
* Fix the premium checks, introduced in v1.8.3 (https://github.com/slawkens/myaac/commit/9d92a11fb7cb6d7a1619d79c12faaa0b1c01f980)
## [1.8.3 - 21.10.2025]
### Added
* Feature: resend email verify (https://github.com/slawkens/myaac/commit/fe821c58085483e70491dcf76376ad5b96de3fdd)
* New config: hooks_debug (To view where hooks are located in .twig files) (https://github.com/slawkens/myaac/commit/8c3cb0e06f9709c1de3398b48221241e7cbdd310)
* Functions: Add db->getColumnInfo(table, column) (https://github.com/slawkens/myaac/commit/c898fe25efff6793a01d11c26fc153cb23fcb858)
* Plugins: Add option to use ?subtopic=x for plugins pages (https://github.com/slawkens/myaac/commit/97f9d3d6f6c28aef6d824973058d7133f56e09c4)
* getTopPlayers() Function - Add lookmount & promotion (https://github.com/slawkens/myaac/commit/2da0024c68f1cedc38a16ebbc6f52ffa55e65f7a, https://github.com/slawkens/myaac/commit/901df48d134079d648a18f9d82b60182e818ac02)
* New hooks for account/change-password (https://github.com/slawkens/myaac/commit/470555f2687809a0c12491bbb27597e64b8929c1)
### Changed
* Feature: show vip days in account management (https://github.com/slawkens/myaac/commit/c88b08eb1ec1f560cbfdaaa16b24e3a0f26da7b3, by @andreoam)
* Allow links in error_box.html.twig (https://github.com/slawkens/myaac/commit/9acad15451071639acf7a7d4e81619b0a9742b12)
* Canary - Comment code to update lastday in login.php (https://github.com/slawkens/myaac/commit/38902c30d114fdbce259467f5820f97037b393e9)
* Cache::remember $ttl = -1 = infinite (https://github.com/slawkens/myaac/commit/64acf70d3854182d88aaf0b67f77cea2a254f179)
### Fixed
* Online - Allow for html code (example - img) in online_datacenter (https://github.com/slawkens/myaac/commit/3bb272ebbbd2eb7769d174b7082061d14a17bd44)
* Guilds - Fix guild create with freePremium enabled (https://github.com/slawkens/myaac/commit/c91bb5d4097647dca2196d3dea87bc90c89181d2)
* Canary - Fix premDays count (https://github.com/slawkens/myaac/commit/3e61692780d4add93b7b0e9f12f7a283bd8f4b7a)
* Template Change: Ignore set last visit for AJAX pages - Fixes template change redirect (https://github.com/slawkens/myaac/commit/89fae38caa7e4f645957fcf1a9330a36358ac04f)
* Admin Panel - Accounts: Fix lastip v6 (TFS master) (https://github.com/slawkens/myaac/commit/f54b1bdd2af4c16c64ddff0e87a6c96bc4cf9eeb)
* Functions - Prevent injection in $db->hasColumn (https://github.com/slawkens/myaac/commit/56bd7ec5ed904666074492f2e4f13e4fce226bee)
* Compat Config: Add missing config: email_lai_sec_interval (https://github.com/slawkens/myaac/commit/2eae44e0755e624a91be68b4d1ec26d01eb4d9a1)
## [1.8.2 - 26.09.2025] ## [1.8.2 - 26.09.2025]
### Added ### Added

View File

@@ -1,4 +0,0 @@
## [2.0-dev - x.x.2025]
### Changed
* Reworked account action logs to use single IP column as varchar(45) for both ipv4 and ipv6 (https://github.com/slawkens/myaac/pull/289)

4
aac
View File

@@ -25,9 +25,7 @@ foreach ($commandsGlob as $item) {
} }
$commandPre = '\\MyAAC\Commands\\'; $commandPre = '\\MyAAC\Commands\\';
if (!trait_exists($class = $commandPre . $name)) { $application->add(new ($commandPre . $name));
$application->add(new $class);
}
} }
$pluginCommands = Plugins::getCommands(); $pluginCommands = Plugins::getCommands();

View File

@@ -9,7 +9,6 @@
*/ */
use MyAAC\Models\Account as AccountModel; use MyAAC\Models\Account as AccountModel;
use MyAAC\Models\AccountAction;
use MyAAC\Models\Player; use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
@@ -482,8 +481,9 @@ else if (isset($_REQUEST['search'])) {
</thead> </thead>
<tbody> <tbody>
<?php <?php
$accountActions = AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get(); $accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
foreach ($accountActions as $i => $log): foreach ($accountActions as $i => $log):
$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6));
?> ?>
<tr> <tr>
<td><?php echo $i + 1; ?></td> <td><?php echo $i + 1; ?></td>

View File

@@ -6,7 +6,6 @@
* @package MyAAC * @package MyAAC
* @author Slawkens <slawkens@gmail.com> * @author Slawkens <slawkens@gmail.com>
* @author Lee * @author Lee
* @author gpedro
* @copyright 2020 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
@@ -20,9 +19,9 @@ $title = 'Mass Account Actions';
csrfProtect(); csrfProtect();
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); $hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$freePremium = getBoolean(configLua('freePremium')); $freePremium = $config['lua']['freePremium'];
function admin_give_points($points): void function admin_give_points($points)
{ {
global $hasPointsColumn; global $hasPointsColumn;
@@ -38,7 +37,7 @@ function admin_give_points($points): void
displayMessage($points . ' points added to all accounts.', true); displayMessage($points . ' points added to all accounts.', true);
} }
function admin_give_coins($coins): void function admin_give_coins($coins)
{ {
if (!HAS_ACCOUNT_COINS) { if (!HAS_ACCOUNT_COINS) {
displayMessage('Coins not supported.'); displayMessage('Coins not supported.');
@@ -53,7 +52,7 @@ function admin_give_coins($coins): void
displayMessage($coins . ' coins added to all accounts.', true); displayMessage($coins . ' coins added to all accounts.', true);
} }
function admin_give_premdays($days): void function admin_give_premdays($days)
{ {
global $db, $freePremium; global $db, $freePremium;
@@ -64,7 +63,6 @@ function admin_give_premdays($days): void
$value = $days * 86400; $value = $days * 86400;
$now = time(); $now = time();
// othire // othire
if ($db->hasColumn('accounts', 'premend')) { if ($db->hasColumn('accounts', 'premend')) {
// append premend // append premend
@@ -72,11 +70,14 @@ function admin_give_premdays($days): void
// set premend // set premend
if (Account::where('premend', '<=', $now)->update(['premend' => $now + $value])) { if (Account::where('premend', '<=', $now)->update(['premend' => $now + $value])) {
displayMessage($days . ' premium days added to all accounts.', true); displayMessage($days . ' premium days added to all accounts.', true);
return;
} else { } else {
displayMessage('Failed to execute set query.'); displayMessage('Failed to execute set query.');
return;
} }
} else { } else {
displayMessage('Failed to execute append query.'); displayMessage('Failed to execute append query.');
return;
} }
return; return;
@@ -91,14 +92,20 @@ function admin_give_premdays($days): void
// set lastday // set lastday
if (Account::where('lastday', '<=', $now)->update(['lastday' => $now + $value])) { if (Account::where('lastday', '<=', $now)->update(['lastday' => $now + $value])) {
displayMessage($days . ' premium days added to all accounts.', true); displayMessage($days . ' premium days added to all accounts.', true);
return;
} else { } else {
displayMessage('Failed to execute set query.'); displayMessage('Failed to execute set query.');
return;
} }
return;
} else { } else {
displayMessage('Failed to execute append query.'); displayMessage('Failed to execute append query.');
return;
} }
} else { } else {
displayMessage('Failed to execute set days query.'); displayMessage('Failed to execute set days query.');
return;
} }
return; return;
@@ -111,11 +118,14 @@ function admin_give_premdays($days): void
// set premium_ends_at // set premium_ends_at
if (Account::where('premium_ends_at', '<=', $now)->update(['premium_ends_at' => $now + $value])) { if (Account::where('premium_ends_at', '<=', $now)->update(['premium_ends_at' => $now + $value])) {
displayMessage($days . ' premium days added to all accounts.', true); displayMessage($days . ' premium days added to all accounts.', true);
return;
} else { } else {
displayMessage('Failed to execute set query.'); displayMessage('Failed to execute set query.');
return;
} }
} else { } else {
displayMessage('Failed to execute append query.'); displayMessage('Failed to execute append query.');
return;
} }
return; return;
@@ -160,8 +170,7 @@ else {
)); ));
} }
function displayMessage($message, $success = false): void function displayMessage($message, $success = false) {
{
global $twig, $hasPointsColumn, $freePremium; global $twig, $hasPointsColumn, $freePremium;
$success ? success($message): error($message); $success ? success($message): error($message);

View File

@@ -60,7 +60,7 @@ usort($menus, function ($a, $b) {
foreach ($menus as $i => $menu) { foreach ($menus as $i => $menu) {
if (isset($menu['link']) && is_array($menu['link'])) { if (isset($menu['link']) && is_array($menu['link'])) {
usort($menu['link'], function ($a, $b) { usort($menus[$i]['link'], function ($a, $b) {
return $a['order'] - $b['order']; return $a['order'] - $b['order'];
}); });
} }

View File

@@ -1,6 +1,5 @@
<?php <?php
const MYAAC_ADMIN = true; define('MYAAC_ADMIN', true);
const IGNORE_SET_LAST_VISIT = true;
require '../../common.php'; require '../../common.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';

View File

@@ -26,7 +26,6 @@
use MyAAC\DataLoader; use MyAAC\DataLoader;
const MYAAC_ADMIN = true; const MYAAC_ADMIN = true;
const IGNORE_SET_LAST_VISIT = true;
require '../../common.php'; require '../../common.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';

View File

@@ -3,7 +3,6 @@
use MyAAC\Settings; use MyAAC\Settings;
const MYAAC_ADMIN = true; const MYAAC_ADMIN = true;
const IGNORE_SET_LAST_VISIT = true;
require '../../common.php'; require '../../common.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';
@@ -12,7 +11,7 @@ require SYSTEM . 'login.php';
if(!admin()) { if(!admin()) {
http_response_code(500); http_response_code(500);
die('You are not logged in. Probably session expired. Please login again.'); die('Access denied.');
} }
csrfProtect(); csrfProtect();
@@ -40,6 +39,3 @@ if (count($errors) > 0) {
if ($success) { if ($success) {
echo 'Saved at ' . date('H:i'); echo 'Saved at ' . date('H:i');
} }
else {
echo 'Something unexpected happened - it was impossible to save the settings, please try again later. If problem persists - contact MyAAC developers.';
}

View File

@@ -1,6 +1,5 @@
<?php <?php
const MYAAC_ADMIN = true; define('MYAAC_ADMIN', true);
const IGNORE_SET_LAST_VISIT = true;
require '../../common.php'; require '../../common.php';
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';

View File

@@ -1,6 +1,5 @@
<?php <?php
const MYAAC_ADMIN = true; define('MYAAC_ADMIN', true);
const IGNORE_SET_LAST_VISIT = true;
require '../../common.php'; require '../../common.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';

View File

@@ -26,8 +26,8 @@
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
const MYAAC = true; const MYAAC = true;
const MYAAC_VERSION = '2.0-dev'; const MYAAC_VERSION = '1.8.3-dev';
const DATABASE_VERSION = 47; const DATABASE_VERSION = 45;
const TABLE_PREFIX = 'myaac_'; const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true)); define('START_TIME', microtime(true));
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
@@ -148,17 +148,16 @@ if(!IS_CLI) {
/** @var array $config */ /** @var array $config */
ini_set('log_errors', 1); ini_set('log_errors', 1);
if(isset($config['env']) && $config['env'] !== 'dev' && !defined('MYAAC_INSTALL')) { if(@$config['env'] === 'dev' || defined('MYAAC_INSTALL')) {
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
}
else {
ini_set('html_errors', 0);
ini_set('display_errors', 1); ini_set('display_errors', 1);
ini_set('display_startup_errors', 1); ini_set('display_startup_errors', 1);
error_reporting(E_ALL); error_reporting(E_ALL);
} }
else {
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
}
$autoloadFile = VENDOR . 'autoload.php'; $autoloadFile = VENDOR . 'autoload.php';
if (!is_file($autoloadFile)) { if (!is_file($autoloadFile)) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 B

View File

@@ -1,69 +0,0 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
use MyAAC\Models\Changelog;
use MyAAC\Models\Config;
use MyAAC\Models\ForumBoard;
use MyAAC\Models\Gallery;
use MyAAC\Models\NewsCategory;
if (Changelog::count() === 0) {
Changelog::create([
'type' => 3,
'where' => 2,
'date' => time(),
'body' => 'MyAAC installed. (:',
'hide' => 0,
]);
}
if (Config::where('name', 'database_version')->count() === 0) {
Config::create([
'name' => 'database_version',
'value' => DATABASE_VERSION,
]);
}
if (ForumBoard::count() === 0) {
$forumBoards = [
['name' => 'News', 'description' => 'News commenting', 'closed' => 1],
['name' => 'Trade', 'description' => 'Trade offers.', 'closed' => 0],
['name' => 'Quests', 'description' => 'Quest making.', 'closed' => 0],
['name' => 'Pictures', 'description' => 'Your pictures.', 'closed' => 0],
['name' => 'Bug Report', 'description' => 'Report bugs there.', 'closed' => 0],
];
$i = 0;
foreach ($forumBoards as $forumBoard) {
ForumBoard::create([
'name' => $forumBoard['name'],
'description' => $forumBoard['description'],
'ordering' => $i++,
'closed' => $forumBoard['closed'],
]);
}
}
if (NewsCategory::count() === 0) {
$newsCategoriesIcons = [
0, 1, 2, 3, 4
];
foreach ($newsCategoriesIcons as $iconId) {
NewsCategory::create([
'icon_id' => $iconId,
]);
}
}
if (Gallery::count() === 0) {
Gallery::create([
'comment' => 'Demon',
'image' => 'images/gallery/demon.jpg',
'thumb' => 'images/gallery/demon_thumb.gif',
'author' => 'MyAAC',
'ordering' => 0,
]);
}
success($locale['step_database_success_import_data']);

View File

@@ -1,23 +1,16 @@
CREATE TABLE IF NOT EXISTS `myaac_account_actions` SET @myaac_database_version = 45;
CREATE TABLE `myaac_account_actions`
( (
`id` int NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL, `account_id` int NOT NULL,
`ip` varchar(45) NOT NULL DEFAULT '', `ip` int unsigned NOT NULL DEFAULT 0,
`ipv6` binary(16) NOT NULL DEFAULT 0,
`date` int NOT NULL DEFAULT 0, `date` int NOT NULL DEFAULT 0,
`action` varchar(255) NOT NULL DEFAULT '', `action` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`) KEY (`account_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_account_emails_verify` CREATE TABLE `myaac_admin_menu`
(
`id` int NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL,
`hash` varchar(32) NOT NULL,
`sent_at` int NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_admin_menu`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '', `name` varchar(255) NOT NULL DEFAULT '',
@@ -28,7 +21,7 @@ CREATE TABLE IF NOT EXISTS `myaac_admin_menu`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_changelog` CREATE TABLE `myaac_changelog`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`body` varchar(500) NOT NULL DEFAULT '', `body` varchar(500) NOT NULL DEFAULT '',
@@ -40,7 +33,9 @@ CREATE TABLE IF NOT EXISTS `myaac_changelog`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_config` INSERT INTO `myaac_changelog` (`id`, `type`, `where`, `date`, `body`, `hide`) VALUES (1, 3, 2, UNIX_TIMESTAMP(), 'MyAAC installed. (:', 0);
CREATE TABLE `myaac_config`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL, `name` varchar(30) NOT NULL,
@@ -49,7 +44,9 @@ CREATE TABLE IF NOT EXISTS `myaac_config`
UNIQUE (`name`) UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_faq` INSERT INTO `myaac_config` (`name`, `value`) VALUES ('database_version', @myaac_database_version);
CREATE TABLE `myaac_faq`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`question` varchar(255) NOT NULL DEFAULT '', `question` varchar(255) NOT NULL DEFAULT '',
@@ -59,7 +56,7 @@ CREATE TABLE IF NOT EXISTS `myaac_faq`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_forum_boards` CREATE TABLE `myaac_forum_boards`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL, `name` varchar(32) NOT NULL,
@@ -71,8 +68,13 @@ CREATE TABLE IF NOT EXISTS `myaac_forum_boards`
`hide` tinyint NOT NULL DEFAULT 0, `hide` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`, `closed`) VALUES (NULL, 'News', 'News commenting', 0, 1);
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUES (NULL, 'Trade', 'Trade offers.', 1);
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUES (NULL, 'Quests', 'Quest making.', 2);
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUES (NULL, 'Pictures', 'Your pictures.', 3);
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUES (NULL, 'Bug Report', 'Report bugs there.', 4);
CREATE TABLE IF NOT EXISTS `myaac_forum` CREATE TABLE `myaac_forum`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`first_post` int NOT NULL DEFAULT 0, `first_post` int NOT NULL DEFAULT 0,
@@ -96,7 +98,7 @@ CREATE TABLE IF NOT EXISTS `myaac_forum`
KEY `section` (`section`) KEY `section` (`section`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_menu` CREATE TABLE `myaac_menu`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`template` varchar(255) NOT NULL, `template` varchar(255) NOT NULL,
@@ -110,7 +112,7 @@ CREATE TABLE IF NOT EXISTS `myaac_menu`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_monsters` ( CREATE TABLE `myaac_monsters` (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`hide` tinyint NOT NULL DEFAULT 0, `hide` tinyint NOT NULL DEFAULT 0,
`name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL,
@@ -143,7 +145,7 @@ CREATE TABLE IF NOT EXISTS `myaac_monsters` (
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_news` CREATE TABLE `myaac_news`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL, `title` varchar(100) NOT NULL,
@@ -161,7 +163,7 @@ CREATE TABLE IF NOT EXISTS `myaac_news`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_news_categories` CREATE TABLE `myaac_news_categories`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT "", `name` varchar(50) NOT NULL DEFAULT "",
@@ -171,7 +173,13 @@ CREATE TABLE IF NOT EXISTS `myaac_news_categories`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_notepad` INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 0);
INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 1);
INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 2);
INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 3);
INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 4);
CREATE TABLE `myaac_notepad`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL, `account_id` int NOT NULL,
@@ -181,7 +189,7 @@ CREATE TABLE IF NOT EXISTS `myaac_notepad`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_pages` CREATE TABLE `myaac_pages`
( (
`id` INT NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL, `name` varchar(30) NOT NULL,
@@ -197,7 +205,7 @@ CREATE TABLE IF NOT EXISTS `myaac_pages`
UNIQUE (`name`) UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_gallery` CREATE TABLE `myaac_gallery`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`comment` varchar(255) NOT NULL DEFAULT '', `comment` varchar(255) NOT NULL DEFAULT '',
@@ -209,7 +217,9 @@ CREATE TABLE IF NOT EXISTS `myaac_gallery`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_settings` INSERT INTO `myaac_gallery` (`id`, `ordering`, `comment`, `image`, `thumb`, `author`) VALUES (NULL, 1, 'Demon', 'images/gallery/demon.jpg', 'images/gallery/demon_thumb.gif', 'MyAAC');
CREATE TABLE `myaac_settings`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '', `name` varchar(255) NOT NULL DEFAULT '',
@@ -219,7 +229,7 @@ CREATE TABLE IF NOT EXISTS `myaac_settings`
KEY `key` (`key`) KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_spells` CREATE TABLE `myaac_spells`
( (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`spell` varchar(255) NOT NULL DEFAULT '', `spell` varchar(255) NOT NULL DEFAULT '',
@@ -242,7 +252,7 @@ CREATE TABLE IF NOT EXISTS `myaac_spells`
UNIQUE (`name`) UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_visitors` CREATE TABLE `myaac_visitors`
( (
`ip` varchar(45) NOT NULL, `ip` varchar(45) NOT NULL,
`lastvisit` int NOT NULL DEFAULT 0, `lastvisit` int NOT NULL DEFAULT 0,
@@ -251,7 +261,7 @@ CREATE TABLE IF NOT EXISTS `myaac_visitors`
UNIQUE (`ip`) UNIQUE (`ip`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE IF NOT EXISTS `myaac_weapons` CREATE TABLE `myaac_weapons`
( (
`id` int NOT NULL, `id` int NOT NULL,
`level` int NOT NULL DEFAULT 0, `level` int NOT NULL DEFAULT 0,

View File

@@ -30,12 +30,17 @@ if(!$error) {
} }
} }
if($db->hasTable(TABLE_PREFIX . 'account_actions')) {
$locale['step_database_error_table_exist'] = str_replace('$TABLE$', TABLE_PREFIX . 'account_actions', $locale['step_database_error_table_exist']);
warning($locale['step_database_error_table_exist']);
}
else {
// import schema // import schema
try { try {
$locale['step_database_importing'] = str_replace('$DATABASE_NAME$', config('database_name'), $locale['step_database_importing']); $locale['step_database_importing'] = str_replace('$DATABASE_NAME$', config('database_name'), $locale['step_database_importing']);
success($locale['step_database_importing']); success($locale['step_database_importing']);
$db->exec(file_get_contents(BASE . 'install/includes/schema.sql')); $db->query(file_get_contents(BASE . 'install/includes/schema.sql'));
$locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']); $locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']);
success($locale['step_database_success_schema']); success($locale['step_database_success_schema']);
@@ -44,8 +49,7 @@ catch(PDOException $error_) {
error($locale['step_database_error_schema'] . ' ' . $error_); error($locale['step_database_error_schema'] . ' ' . $error_);
return; return;
} }
}
require BASE . 'install/includes/import_base_data.php';
if(!$db->hasColumn('accounts', 'email')) { if(!$db->hasColumn('accounts', 'email')) {
if(query("ALTER TABLE `accounts` ADD `email` varchar(255) NOT NULL DEFAULT '';")) if(query("ALTER TABLE `accounts` ADD `email` varchar(255) NOT NULL DEFAULT '';"))
@@ -98,13 +102,18 @@ if(!$db->hasColumn('accounts', 'web_flags')) {
success($locale['step_database_adding_field'] . ' accounts.web_flags...'); success($locale['step_database_adding_field'] . ' accounts.web_flags...');
} }
if(!$db->hasColumn('accounts', 'email_hash')) {
if(query("ALTER TABLE `accounts` ADD `email_hash` VARCHAR(32) NOT NULL DEFAULT '' AFTER `web_flags`;"))
success($locale['step_database_adding_field'] . ' accounts.email_hash...');
}
if(!$db->hasColumn('accounts', 'email_verified')) { if(!$db->hasColumn('accounts', 'email_verified')) {
if(query("ALTER TABLE `accounts` ADD `email_verified` TINYINT(1) NOT NULL DEFAULT 0 AFTER `web_flags`;")) if(query("ALTER TABLE `accounts` ADD `email_verified` TINYINT(1) NOT NULL DEFAULT 0 AFTER `email_hash`;"))
success($locale['step_database_adding_field'] . ' accounts.email_verified...'); success($locale['step_database_adding_field'] . ' accounts.email_verified...');
} }
if(!$db->hasColumn('accounts', 'email_new')) { if(!$db->hasColumn('accounts', 'email_new')) {
if(query("ALTER TABLE `accounts` ADD `email_new` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_verified`;")) if(query("ALTER TABLE `accounts` ADD `email_new` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_hash`;"))
success($locale['step_database_adding_field'] . ' accounts.email_new...'); success($locale['step_database_adding_field'] . ' accounts.email_new...');
} }

View File

@@ -220,8 +220,6 @@ switch ($action) {
} }
} }
/*
* not needed anymore?
if (fieldExist('premdays', 'accounts') && fieldExist('lastday', 'accounts')) { if (fieldExist('premdays', 'accounts') && fieldExist('lastday', 'accounts')) {
$save = false; $save = false;
$timeNow = time(); $timeNow = time();
@@ -258,7 +256,6 @@ switch ($action) {
$account->save(); $account->save();
} }
} }
*/
$worlds = [$world]; $worlds = [$world];
$playdata = compact('worlds', 'characters'); $playdata = compact('worlds', 'characters');

View File

@@ -5,6 +5,8 @@ $deprecatedConfig = [
'genders', 'genders',
'template', 'template',
'template_allow_change', 'template_allow_change',
'vocations_amount',
'vocations',
'client', 'client',
'session_prefix', 'session_prefix',
'friendly_urls', 'friendly_urls',
@@ -79,7 +81,6 @@ $deprecatedConfig = [
'account_change_character_name_points' => 'account_change_character_name_price', 'account_change_character_name_points' => 'account_change_character_name_price',
'account_change_character_sex', 'account_change_character_sex',
'account_change_character_sex_points' => 'account_change_character_name_price', 'account_change_character_sex_points' => 'account_change_character_name_price',
'email_lai_sec_interval' => 'mail_lost_account_interval',
]; ];
foreach ($deprecatedConfig as $key => $value) { foreach ($deprecatedConfig as $key => $value) {

View File

@@ -433,22 +433,16 @@ function delete_guild($id)
$rank_list->orderBy('level'); $rank_list->orderBy('level');
global $db; global $db;
$deletedColumn = 'deleted';
if ($db->hasColumn('players', 'deletion')) {
$deletedColumn = 'deletion';
}
/** /**
* @var OTS_GuildRank $rank_in_guild * @var OTS_GuildRank $rank_in_guild
*/ */
foreach($rank_list as $rank_in_guild) { foreach($rank_list as $rank_in_guild) {
if($db->hasTable('guild_members')) if($db->hasTable('guild_members'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` AND `' . $deletedColumn . '` = 0 ORDER BY `name`;'); $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;');
else if($db->hasTable('guild_membership')) else if($db->hasTable('guild_membership'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_membership`.`rank_id` as `rank_id` FROM `players`, `guild_membership` WHERE `guild_membership`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_membership`.`player_id` AND `' . $deletedColumn . '` = 0 ORDER BY `name`;'); $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_membership`.`rank_id` as `rank_id` FROM `players`, `guild_membership` WHERE `guild_membership`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_membership`.`player_id` ORDER BY `name`;');
else else
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `' . $deletedColumn . '` = 0;'); $players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `deleted` = 0;');
$players_with_rank_number = $players_with_rank->rowCount(); $players_with_rank_number = $players_with_rank->rowCount();
if($players_with_rank_number > 0) { if($players_with_rank_number > 0) {
@@ -1148,18 +1142,10 @@ function getTopPlayers($limit = 5, $skill = 'level') {
'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet' 'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet'
]; ];
if ($db->hasColumn('players', 'promotion')) {
$columns[] = 'promotion';
}
if ($db->hasColumn('players', 'lookaddons')) { if ($db->hasColumn('players', 'lookaddons')) {
$columns[] = 'lookaddons'; $columns[] = 'lookaddons';
} }
if ($db->hasColumn('players', 'lookmount')) {
$columns[] = 'lookmount';
}
return Player::query() return Player::query()
->select($columns) ->select($columns)
->withOnlineStatus() ->withOnlineStatus()
@@ -1183,8 +1169,7 @@ function getTopPlayers($limit = 5, $skill = 'level') {
}); });
} }
function deleteDirectory($dir, $ignore = array(), $contentOnly = false): bool function deleteDirectory($dir, $ignore = array(), $contentOnly = false) {
{
if(!file_exists($dir)) { if(!file_exists($dir)) {
return true; return true;
} }
@@ -1210,21 +1195,6 @@ function deleteDirectory($dir, $ignore = array(), $contentOnly = false): bool
return rmdir($dir); return rmdir($dir);
} }
function ensureFolderExists($dir): void
{
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
}
function ensureIndexExists($dir): void
{
$dir = rtrim($dir, '/');
if (!file_exists($file = $dir . '/index.html')) {
touch($file);
}
}
function config($key) { function config($key) {
global $config; global $config;
if (is_array($key)) { if (is_array($key)) {
@@ -1662,14 +1632,13 @@ function camelCaseToUnderscore($input)
return ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_'); return ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_');
} }
function removeIfFirstSlash(&$text): void function removeIfFirstSlash(&$text) {
{
if(strpos($text, '/') === 0) { if(strpos($text, '/') === 0) {
$text = str_replace_first('/', '', $text); $text = str_replace_first('/', '', $text);
} }
}; };
function escapeHtml($html): string { function escapeHtml($html) {
return htmlspecialchars($html); return htmlspecialchars($html);
} }
@@ -1683,7 +1652,7 @@ function getGuildNameById($id)
return false; return false;
} }
function getGuildLogoById($id): string function getGuildLogoById($id)
{ {
$logo = 'default.gif'; $logo = 'default.gif';
@@ -1699,8 +1668,7 @@ function getGuildLogoById($id): string
return BASE_URL . GUILD_IMAGES_DIR . $logo; return BASE_URL . GUILD_IMAGES_DIR . $logo;
} }
function displayErrorBoxWithBackButton($errors, $action = null): void 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]);
$twig->display('account.back_button.html.twig', [ $twig->display('account.back_button.html.twig', [
@@ -1728,49 +1696,6 @@ function getAccountIdentityColumn(): string
return 'id'; return 'id';
} }
function isCanary(): bool
{
$vipSystemEnabled = configLua('vipSystemEnabled');
return isset($vipSystemEnabled);
}
function getStatusUptimeReadable(int $uptime): string
{
$fullMinute = 60;
$fullHour = (60 * $fullMinute);
$fullDay = (24 * $fullHour);
$fullMonth = (30 * $fullDay);
$fullYear = (365 * $fullDay);
// years
$years = floor($uptime / $fullYear);
$y = ($years > 1 ? "$years years, " : ($years == 1 ? 'year, ' : ''));
$uptime -= $years * $fullYear;
// months
$months = floor($uptime / $fullMonth);
$m = ($months > 1 ? "$months months, " : ($months == 1 ? 'month, ' : ''));
$uptime -= $months * $fullMonth;
// days
$days = floor($uptime / $fullDay);
$d = ($days > 1 ? "$days days, " : ($days == 1 ? 'day, ' : ''));
$uptime -= $days * $fullDay;
// hours
$hours = floor($uptime / $fullHour);
$uptime -= $hours * $fullHour;
// minutes
$min = floor($uptime / $fullMinute);
return "{$y}{$m}{$d}{$hours}h {$min}m";
}
// validator functions // validator functions
require_once SYSTEM . 'compat/base.php'; require_once SYSTEM . 'compat/base.php';

View File

@@ -14,14 +14,10 @@ use MyAAC\CsrfToken;
use MyAAC\Hooks; use MyAAC\Hooks;
use MyAAC\Plugins; use MyAAC\Plugins;
use MyAAC\Models\Town; use MyAAC\Models\Town;
use MyAAC\Server\XML\Vocations;
use MyAAC\Settings; use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
ensureIndexExists(CACHE);
ensureIndexExists(CACHE . 'twig/');
global $config; global $config;
if(!isset($config['installed']) || !$config['installed']) { if(!isset($config['installed']) || !$config['installed']) {
throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.'); throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.');
@@ -215,5 +211,3 @@ if (count($towns) <= 0) {
config(['towns', $towns]); config(['towns', $towns]);
unset($towns); unset($towns);
new Vocations();

View File

@@ -12,8 +12,6 @@
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/ */
use MyAAC\Models\AccountAction;
/** /**
* OTServ account abstraction. * OTServ account abstraction.
* *
@@ -445,9 +443,8 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
throw new E_OTS_NotLoaded(); throw new E_OTS_NotLoaded();
} }
if(isset($this->data['premium_ends_at']) || isset($this->data['premend']) || if(isset($this->data['premium_ends_at']) || isset($this->data['premend'])) {
(isCanary() && isset($this->data['lastday']))) { $col = isset($this->data['premium_ends_at']) ? 'premium_ends_at' : 'premend';
$col = (isset($this->data['premium_ends_at']) ? 'premium_ends_at' : (isset($this->data['lastday']) ? 'lastday' : 'premend'));
$ret = ceil(($this->data[$col] - time()) / (24 * 60 * 60)); $ret = ceil(($this->data[$col] - time()) / (24 * 60 * 60));
return max($ret, 0); return max($ret, 0);
} }
@@ -474,16 +471,14 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
return $this->data['lastday']; return $this->data['lastday'];
} }
public function isPremium(): bool public function isPremium()
{ {
if(isset($this->data['premium_ends_at']) || isset($this->data['premend']) || if(isset($this->data['premium_ends_at'])) {
(isCanary() && isset($this->data['lastday']))) { return $this->data['premium_ends_at'] > time();
$col = (isset($this->data['premium_ends_at']) ? 'premium_ends_at' : (isset($this->data['lastday']) ? 'lastday' : 'premend'));
return $this->data[$col] > time();
} }
if($this->data['premdays'] == self::GRATIS_PREMIUM_DAYS){ if(isset($this->data['premend'])) {
return true; return $this->data['premend'] > time();
} }
return ($this->data['premdays'] - (date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->data['lastday']))) - date("z", $this->data['lastday'])) > 0); return ($this->data['premdays'] - (date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->data['lastday']))) - date("z", $this->data['lastday'])) > 0);
@@ -1009,16 +1004,26 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
public function logAction($action) public function logAction($action)
{ {
AccountAction::create([ $ip = get_browser_real_ip();
'account_id' => $this->getId(), if(!str_contains($ip, ":")) {
'ip' => get_browser_real_ip(), $ipv6 = '0';
'date' => time(), }
'action' => $action, else {
]); $ipv6 = $ip;
$ip = '';
} }
public function getActionsLog($limit) { return $this->db->exec('INSERT INTO `' . TABLE_PREFIX . 'account_actions` (`account_id`, `ip`, `ipv6`, `date`, `action`) VALUES (' . $this->db->quote($this->getId()).', ' . ($ip == '' ? '0' : $this->db->quote(ip2long($ip))) . ', (' . ($ipv6 == '0' ? $this->db->quote('') : $this->db->quote(inet_pton($ipv6))) . '), UNIX_TIMESTAMP(NOW()), ' . $this->db->quote($action).')');
return AccountAction::where('account_id', $this->data['id'])->orderByDesc('date')->limit($limit)->get()->toArray(); }
public function getActionsLog($limit1, $limit2)
{
$actions = array();
foreach($this->db->query('SELECT `ip`, `ipv6`, `date`, `action` FROM `' . TABLE_PREFIX . 'account_actions` WHERE `account_id` = ' . $this->data['id'] . ' ORDER by `date` DESC LIMIT ' . $limit1 . ', ' . $limit2 . '')->fetchAll() as $a)
$actions[] = array('ip' => $a['ip'], 'ipv6' => $a['ipv6'], 'date' => $a['date'], 'action' => $a['action']);
return $actions;
} }
/** /**
* Returns players iterator. * Returns players iterator.

View File

@@ -26,7 +26,6 @@ use MyAAC\Cache\Cache;
*/ */
class OTS_DB_MySQL extends OTS_Base_DB class OTS_DB_MySQL extends OTS_Base_DB
{ {
private bool $hasCacheChanged = false;
private array $has_table_cache = []; private array $has_table_cache = [];
private array $has_column_cache = []; private array $has_column_cache = [];
private array $get_column_info_cache = []; private array $get_column_info_cache = [];
@@ -121,11 +120,6 @@ class OTS_DB_MySQL extends OTS_Base_DB
if($cache->fetch('database_columns', $tmp) && $tmp) { if($cache->fetch('database_columns', $tmp) && $tmp) {
$this->has_column_cache = unserialize($tmp); $this->has_column_cache = unserialize($tmp);
} }
$tmp = null;
if($cache->fetch('database_columns_info', $tmp) && $tmp) {
$this->get_column_info_cache = unserialize($tmp);
}
} }
} }
@@ -162,13 +156,11 @@ class OTS_DB_MySQL extends OTS_Base_DB
if ($this->clearCacheAfter) { if ($this->clearCacheAfter) {
$cache->delete('database_tables'); $cache->delete('database_tables');
$cache->delete('database_columns'); $cache->delete('database_columns');
$cache->delete('database_columns_info');
$cache->delete('database_checksum'); $cache->delete('database_checksum');
} }
else if ($this->hasCacheChanged) { else {
$cache->set('database_tables', serialize($this->has_table_cache), 3600); $cache->set('database_tables', serialize($this->has_table_cache), 3600);
$cache->set('database_columns', serialize($this->has_column_cache), 3600); $cache->set('database_columns', serialize($this->has_column_cache), 3600);
$cache->set('database_columns_info', serialize($this->get_column_info_cache), 3600);
$cache->set('database_checksum', serialize(sha1($config['database_host'] . '.' . $config['database_name'])), 3600); $cache->set('database_checksum', serialize(sha1($config['database_host'] . '.' . $config['database_name'])), 3600);
} }
} }
@@ -229,8 +221,6 @@ class OTS_DB_MySQL extends OTS_Base_DB
private function hasTableInternal($name): bool private function hasTableInternal($name): bool
{ {
$this->hasCacheChanged = true;
return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote(config('database_name')) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0); return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote(config('database_name')) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0);
} }
@@ -244,8 +234,6 @@ class OTS_DB_MySQL extends OTS_Base_DB
} }
private function hasColumnInternal($table, $column): bool { private function hasColumnInternal($table, $column): bool {
$this->hasCacheChanged = true;
return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE " . $this->quote($column))->fetchAll()) > 0); return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE " . $this->quote($column))->fetchAll()) > 0);
} }
@@ -277,14 +265,11 @@ class OTS_DB_MySQL extends OTS_Base_DB
return false; return false;
} }
$this->hasCacheChanged = true;
$formatResult = function ($result) { $formatResult = function ($result) {
return [ return [
'field' => $result['Field'], 'field' => $result['Field'],
'type' => $result['Type'], 'type' => $result['Type'],
'null' => strtolower($result['Null']), 'null' => strtolower($result['Null']),
'key' => strtolower($result['Key'] ?? ''),
'default' => $result['Default'], 'default' => $result['Default'],
'extra' => $result['Extra'], 'extra' => $result['Extra'],
]; ];
@@ -310,8 +295,7 @@ class OTS_DB_MySQL extends OTS_Base_DB
return []; return [];
} }
public function revalidateCache(): void 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);
} }
@@ -326,21 +310,6 @@ class OTS_DB_MySQL extends OTS_Base_DB
$this->hasColumnInternal($explode[0], $explode[1]); $this->hasColumnInternal($explode[0], $explode[1]);
} }
} }
foreach($this->get_column_info_cache as $key => $value) {
$explode = explode('.', $key);
if(!isset($this->has_table_cache[$explode[0]])) { // first check if table exist
$this->hasTableInternal($explode[0]);
}
if($this->has_table_cache[$explode[0]]) {
$this->hasColumnInternal($explode[0], $explode[1]);
}
if($this->has_table_cache[$explode[0]]) {
$this->getColumnInfoInternal($explode[0], $explode[1]);
}
}
} }
public function setClearCacheAfter($clearCache) public function setClearCacheAfter($clearCache)

View File

@@ -852,7 +852,13 @@ class OTS_Player extends OTS_Row_DAO
throw new E_OTS_NotLoaded(); throw new E_OTS_NotLoaded();
} }
return \OTS_Toolbox::getVocationFromPromotion($this->data['vocation'], $this->data['promotion'] ?? 0); if(isset($this->data['promotion'])) {
global $config;
if((int)$this->data['promotion'] > 0)
return ($this->data['vocation'] + ($this->data['promotion'] * $config['vocations_amount']));
}
return $this->data['vocation'];
} }

View File

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

View File

@@ -13,8 +13,6 @@
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/ */
use MyAAC\Server\XML\Vocations;
/** /**
* Toolbox for common operations. * Toolbox for common operations.
* *
@@ -112,21 +110,14 @@ class OTS_Toolbox
$list->setFilter($filter); $list->setFilter($filter);
return $list; return $list;
} }
public static function getVocationFromPromotion($id, $promotion = 0): int
public static function getVocationName($id, $promotion = 0): string
{ {
if($promotion > 0) { if($promotion > 0) {
for ($i = 0; $i < $promotion; $i++) { $id = ($id + ($promotion * config('vocations_amount')));
if ($_id = Vocations::getPromoted($id)) {
$id = $_id;
}
}
} }
return $id; return config('vocations')[$id] ?? 'Unknown';
}
public static function getVocationName($id, $promotion = 0): string {
return config('vocations')[self::getVocationFromPromotion($id, $promotion)] ?? 'Unknown';
} }
} }

View File

@@ -78,7 +78,6 @@ $locale['step_database_error_mysql_connect_3'] = 'MySQL ist nicht richtig konfig
$locale['step_database_error_mysql_connect_4'] = 'MySQL-Server läuft nicht.'; $locale['step_database_error_mysql_connect_4'] = 'MySQL-Server läuft nicht.';
$locale['step_database_error_schema'] = 'Fehler beim Importieren des Schemas:'; $locale['step_database_error_schema'] = 'Fehler beim Importieren des Schemas:';
$locale['step_database_success_schema'] = '$PREFIX$ Tabellen wurden erfolgreich installiert.'; $locale['step_database_success_schema'] = '$PREFIX$ Tabellen wurden erfolgreich installiert.';
$locale['step_database_success_import_data'] = 'Import von Daten für Tabellen was erfolgreich.';
$locale['step_database_error_file'] = '$FILE$ konnte nicht geöffnet werden. Bitte kopieren Sie diesen Inhalt und fügen Sie ihn dort ein:'; $locale['step_database_error_file'] = '$FILE$ konnte nicht geöffnet werden. Bitte kopieren Sie diesen Inhalt und fügen Sie ihn dort ein:';
$locale['step_database_adding_field'] = 'Folgendes Feld wurde hinzugefügt: '; $locale['step_database_adding_field'] = 'Folgendes Feld wurde hinzugefügt: ';
$locale['step_database_modifying_field'] = 'Folgendes Feld wurde geändert: '; $locale['step_database_modifying_field'] = 'Folgendes Feld wurde geändert: ';

View File

@@ -83,7 +83,6 @@ $locale['step_database_error_mysql_connect_3'] = 'MySQL is not configured proper
$locale['step_database_error_mysql_connect_4'] = 'MySQL server is not running.'; $locale['step_database_error_mysql_connect_4'] = 'MySQL server is not running.';
$locale['step_database_error_schema'] = 'Error while importing schema:'; $locale['step_database_error_schema'] = 'Error while importing schema:';
$locale['step_database_success_schema'] = 'Successfully installed $PREFIX$ tables.'; $locale['step_database_success_schema'] = 'Successfully installed $PREFIX$ tables.';
$locale['step_database_success_import_data'] = 'Successfully imported base data for tables.';
$locale['step_database_error_file'] = '$FILE$ couldn\'t be opened. Please copy this content and paste there:'; $locale['step_database_error_file'] = '$FILE$ couldn\'t be opened. Please copy this content and paste there:';
$locale['step_database_adding_field'] = 'Adding field'; $locale['step_database_adding_field'] = 'Adding field';
$locale['step_database_modifying_field'] = 'Modifying field'; $locale['step_database_modifying_field'] = 'Modifying field';

View File

@@ -81,8 +81,7 @@ $locale['step_database_error_mysql_connect_2'] = 'Możliwe przyczyny:';
$locale['step_database_error_mysql_connect_3'] = 'MySQL nie jest poprawnie skonfigurowane w <i>config.lua</i>.'; $locale['step_database_error_mysql_connect_3'] = 'MySQL nie jest poprawnie skonfigurowane w <i>config.lua</i>.';
$locale['step_database_error_mysql_connect_4'] = 'Serwer MySQL nie jest uruchomiony.'; $locale['step_database_error_mysql_connect_4'] = 'Serwer MySQL nie jest uruchomiony.';
$locale['step_database_error_schema'] = 'Błąd podczas importowania struktury bazy danych:'; $locale['step_database_error_schema'] = 'Błąd podczas importowania struktury bazy danych:';
$locale['step_database_success_schema'] = 'Pomyślnie zaimportowano tabele $PREFIX$.'; $locale['step_database_success_schema'] = 'Pomyślnie zainstalowano tabele $PREFIX$.';
$locale['step_database_success_import_data'] = 'Pomyślnie załadowano bazowe dane dla tabel.';
$locale['step_database_error_file'] = '$FILE$ nie mógł zostać otwarty. Proszę skopiować zawartość pola tekstowego i wkleić do tego pliku:'; $locale['step_database_error_file'] = '$FILE$ nie mógł zostać otwarty. Proszę skopiować zawartość pola tekstowego i wkleić do tego pliku:';
$locale['step_database_adding_field'] = 'Dodawanie pola'; $locale['step_database_adding_field'] = 'Dodawanie pola';
$locale['step_database_modifying_field'] = 'Modyfikacja pola'; $locale['step_database_modifying_field'] = 'Modyfikacja pola';

View File

@@ -34,10 +34,8 @@ if($logged) {
$twig->addGlobal('account_logged', $account_logged); $twig->addGlobal('account_logged', $account_logged);
} }
if (!defined('IGNORE_SET_LAST_VISIT') || !IGNORE_SET_LAST_VISIT) {
setSession('last_visit', time()); setSession('last_visit', time());
if(defined('PAGE')) { if(defined('PAGE')) {
setSession('last_page', PAGE); setSession('last_page', PAGE);
} }
setSession('last_uri', $_SERVER['REQUEST_URI']); setSession('last_uri', $_SERVER['REQUEST_URI']);
}

View File

@@ -9,8 +9,6 @@
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
global $db;
// database migrations // database migrations
$tmp = ''; $tmp = '';
if(fetchDatabaseConfig('database_version', $tmp)) { // we got version if(fetchDatabaseConfig('database_version', $tmp)) { // we got version

View File

@@ -1,8 +0,0 @@
CREATE TABLE `myaac_account_emails_verify`
(
`id` int NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL,
`hash` varchar(32) NOT NULL,
`sent_at` int NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;

View File

@@ -1,24 +0,0 @@
<?php
/**
* @var OTS_DB_MySQL $db
*/
$up = function () use ($db) {
if ($db->hasColumn('accounts', 'email_hash')) {
$db->dropColumn('accounts', 'email_hash');
}
if (!$db->hasTable(TABLE_PREFIX . 'account_emails_verify')) {
$db->query(file_get_contents(__DIR__ . '/46-account_emails_verify.sql'));
}
};
$down = function () use ($db) {
if (!$db->hasColumn('accounts', 'email_hash')) {
$db->addColumn('accounts', 'email_hash', "varchar(32) NOT NULL DEFAULT ''");
}
if ($db->hasTable(TABLE_PREFIX . 'account_emails_verify')) {
$db->dropTable(TABLE_PREFIX . 'account_emails_verify');
}
};

View File

@@ -1,42 +0,0 @@
<?php
/**
* @var OTS_DB_MySQL $db
*/
// 2025-02-27
// remove ipv6, change to ip (for both ipv4 + ipv6) as VARCHAR(45)
$up = function () use ($db) {
$accountActionsInfo = $db->getColumnInfo(TABLE_PREFIX . 'account_actions', 'account_id');
if ($accountActionsInfo && is_array($accountActionsInfo) && $accountActionsInfo['key'] == 'pri') {
$db->query("ALTER TABLE `myaac_account_actions` DROP KEY `account_id`;");
}
if (!$db->hasColumn(TABLE_PREFIX . 'account_actions', 'id')) {
$db->addColumn(TABLE_PREFIX . 'account_actions', 'id', 'INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`)');
}
$db->modifyColumn(TABLE_PREFIX . 'account_actions', 'ip', "VARCHAR(45) NOT NULL DEFAULT ''");
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET_NTOA(`ip`) WHERE `ip` != '0';");
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET6_NTOA(`ipv6`) WHERE `ip` = '0';");
if ($db->hasColumn(TABLE_PREFIX . 'account_actions', 'ipv6')) {
$db->dropColumn(TABLE_PREFIX . 'account_actions', 'ipv6');
}
};
$down = function () use ($db) {
if ($db->hasColumn(TABLE_PREFIX . 'account_actions', 'id')) {
$db->query("ALTER TABLE `" . TABLE_PREFIX . "account_actions` DROP `id`;");
}
$db->query("ALTER TABLE `" . TABLE_PREFIX . "account_actions` ADD KEY (`account_id`);");
if (!$db->hasColumn(TABLE_PREFIX . 'account_actions', 'ipv6')) {
$db->addColumn(TABLE_PREFIX . 'account_actions', 'ipv6', "BINARY(16) NOT NULL DEFAULT 0x00000000000000000000000000000000 AFTER ip");
}
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ipv6` = INET6_ATON(ip) WHERE NOT IS_IPV4(`ip`);");
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET_ATON(`ip`) WHERE IS_IPV4(`ip`);");
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = 0 WHERE `ipv6` != 0x00000000000000000000000000000000;");
$db->modifyColumn(TABLE_PREFIX . 'account_actions', 'ip', "INT(11) UNSIGNED NOT NULL DEFAULT 0;");
};

View File

@@ -9,7 +9,7 @@ $up = function () use ($db) {
} }
}; };
$down = function () use ($db) { $up = function () use ($db) {
if (!$db->hasColumn(TABLE_PREFIX . 'screenshots', 'name')) { if (!$db->hasColumn(TABLE_PREFIX . 'screenshots', 'name')) {
$db->addColumn(TABLE_PREFIX . 'screenshots', 'name', 'VARCHAR(30) NOT NULL'); $db->addColumn(TABLE_PREFIX . 'screenshots', 'name', 'VARCHAR(30) NOT NULL');
} }

View File

@@ -19,17 +19,18 @@ if(!$logged) {
csrfProtect(); csrfProtect();
$new_password = $_POST['new_password'] ?? null; $new_password = $_POST['newpassword'] ?? NULL;
$new_password_confirm = $_POST['new_password_confirm'] ?? null; $new_password_confirm = $_POST['newpassword_confirm'] ?? NULL;
$old_password = $_POST['old_password'] ?? null; $old_password = $_POST['oldpassword'] ?? NULL;
if(empty($new_password) && empty($new_password_confirm) && empty($old_password)) { if(empty($new_password) && empty($new_password_confirm) && empty($old_password)) {
$twig->display('account.change-password.html.twig'); $twig->display('account.change-password.html.twig');
} }
else { else
{
if(empty($new_password) || empty($new_password_confirm) || empty($old_password)){ if(empty($new_password) || empty($new_password_confirm) || empty($old_password)){
$errors[] = 'Please fill in form.'; $errors[] = 'Please fill in form.';
} }
$password_strlen = strlen($new_password);
if($new_password != $new_password_confirm) { if($new_password != $new_password_confirm) {
$errors[] = 'The new passwords do not match!'; $errors[] = 'The new passwords do not match!';
} }
@@ -40,13 +41,10 @@ else {
} }
/** @var OTS_Account $account_logged */ /** @var OTS_Account $account_logged */
$old_password_hashed = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $old_password); $old_password = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $old_password);
if($old_password_hashed != $account_logged->getPassword()) { if($old_password != $account_logged->getPassword()) {
$errors[] = 'Current password is incorrect!'; $errors[] = 'Current password is incorrect!';
} }
else if ($old_password == $new_password) {
$errors[] = 'The old password is same as the new password!';
}
$hooks->trigger(HOOK_ACCOUNT_CHANGE_PASSWORD_POST); $hooks->trigger(HOOK_ACCOUNT_CHANGE_PASSWORD_POST);
} }

View File

@@ -9,7 +9,6 @@
*/ */
use MyAAC\Models\Account; use MyAAC\Models\Account;
use MyAAC\Models\AccountEmailVerify;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
@@ -21,20 +20,16 @@ if(empty($hash)) {
return; return;
} }
// by default link is valid for 30 days if(!Account::where('email_hash', $hash)->exists()) {
$accountEmailVerify = AccountEmailVerify::where('hash', $hash)->where('sent_at', '>', time() - 30 * 24 * 60 * 60)->first(); note("Your email couldn't be verified. Please contact staff to do it manually.");
if(!$accountEmailVerify) {
note("Wrong link or link has expired.");
} }
else else
{ {
$accountModel = Account::where('id', $accountEmailVerify->account_id)->where('email_verified', 0)->first(); $accountModel = Account::where('email_hash', $hash)->where('email_verified', 0)->first();
if ($accountModel) { if ($accountModel) {
$accountModel->email_verified = 1; $accountModel->email_verified = 1;
$accountModel->save(); $accountModel->save();
AccountEmailVerify::where('account_id', $accountModel->id)->delete();
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>.'); 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>.');
$account = new OTS_Account(); $account = new OTS_Account();
@@ -44,6 +39,6 @@ else
} }
} }
else { else {
error('Your account is already verified.'); error('Link has expired.');
} }
} }

View File

@@ -10,7 +10,6 @@
*/ */
use MyAAC\CreateCharacter; use MyAAC\CreateCharacter;
use MyAAC\Models\AccountEmailVerify;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Create Account'; $title = 'Create Account';
@@ -245,12 +244,7 @@ if($save)
if(setting('core.mail_enabled') && setting('core.account_mail_verify')) if(setting('core.mail_enabled') && setting('core.account_mail_verify'))
{ {
$hash = md5(generateRandomString(16, true, true) . $email); $hash = md5(generateRandomString(16, true, true) . $email);
$new_account->setCustomField('email_hash', $hash);
AccountEmailVerify::create([
'account_id' => $new_account->getId(),
'hash' => $hash,
'sent_at' => time(),
]);
$verify_url = getLink('account/confirm-email/' . $hash); $verify_url = getLink('account/confirm-email/' . $hash);
$body_html = $twig->render('mail.account.verify.html.twig', array( $body_html = $twig->render('mail.account.verify.html.twig', array(
@@ -367,7 +361,7 @@ if(!empty($errors))
if (setting('core.account_country')) { if (setting('core.account_country')) {
$countries = array(); $countries = array();
foreach (setting('core.account_countries_most_popular') ?? [] as $c) foreach (array('pl', 'se', 'br', 'us', 'gb') as $c)
$countries[$c] = $config['countries'][$c]; $countries[$c] = $config['countries'][$c];
$countries['--'] = '----------'; $countries['--'] = '----------';

View File

@@ -48,9 +48,7 @@ if(!empty($login_account) && !empty($login_password))
) )
{ {
if (setting('core.account_mail_verify') && (int)$account_logged->getCustomField('email_verified') !== 1) { if (setting('core.account_mail_verify') && (int)$account_logged->getCustomField('email_verified') !== 1) {
$link = getLink('account/resend-email-verify'); $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.';
$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.<br/>' .
'You can resend the Email here: <a href="' . $link . '">' . $link . '</a>';
} else { } else {
session_regenerate_id(); session_regenerate_id();
setSession('account', $account_logged->getId()); setSession('account', $account_logged->getId());

View File

@@ -38,24 +38,15 @@ csrfProtect();
$groups = new OTS_Groups_List(); $groups = new OTS_Groups_List();
$freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS;
$dayOrDays = $account_logged->getPremDays() == 1 ? 'day' : 'days';
/** /**
* @var OTS_Account $account_logged * @var OTS_Account $account_logged
*/ */
$premDays = $account_logged->getPremDays(); if(!$account_logged->isPremium())
$freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $premDays == OTS_Account::GRATIS_PREMIUM_DAYS;
$dayOrDays = ($premDays == 1 ? 'day' : 'days');
$vipSystemEnabled = isset($config['lua']['vipSystemEnabled']) && getBoolean($config['lua']['vipSystemEnabled']);
$premiumLabel = $vipSystemEnabled ? 'VIP' : 'Premium Account';
if ($freePremium && !$vipSystemEnabled) {
$account_status = '<b><span style="color: green">Gratis Premium Account</span></b>';
} else if(!$account_logged->isPremium()) {
$account_status = '<b><span style="color: red">Free Account</span></b>'; $account_status = '<b><span style="color: red">Free Account</span></b>';
} else { else
$account_status = '<b><span style="color: green">' . $premiumLabel . ', ' . $premDays . ' '.$dayOrDays.' left</span></b>'; $account_status = '<b><span style="color: green">' . ($freePremium ? 'Gratis Premium Account' : 'Premium Account, ' . $account_logged->getPremDays() . ' '.$dayOrDays.' left') . '</span></b>';
}
$recovery_key = $account_logged->getCustomField('key'); $recovery_key = $account_logged->getCustomField('key');
if(empty($recovery_key)) if(empty($recovery_key))
@@ -96,8 +87,12 @@ if($email_new_time > 1)
} }
} }
$actions = $account_logged->getActionsLog(1000); $actions = array();
foreach($account_logged->getActionsLog(0, 1000) as $action) {
$actions[] = array('action' => $action['action'], 'date' => $action['date'], 'ip' => $action['ip'] != 0 ? long2ip($action['ip']) : inet_ntop($action['ipv6']));
}
$players = array();
/** @var OTS_Players_List $account_players */ /** @var OTS_Players_List $account_players */
$account_players = $account_logged->getPlayersList(); $account_players = $account_logged->getPlayersList();
$account_players->orderBy('id'); $account_players->orderBy('id');

View File

@@ -1,94 +0,0 @@
<?php
use MyAAC\Models\AccountEmailVerify;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Resend Email';
$errorWithBackButton = function ($msg) use ($twig) {
$errors = [$msg];
$twig->display('error_box.html.twig', ['errors' => $errors]);
$twig->display('account.back_button.html.twig', [
'action' => getLink('account/resend-email-verify'),
]);
};
if (!setting('core.mail_enabled') || !setting('core.account_mail_verify')) {
$errorWithBackButton('Resending email is not possible on this server.');
return;
}
$showForm = true;
if (isset($_POST['submit']) && $_POST['submit'] == '1') {
$email = $_REQUEST['email'];
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errorWithBackButton('Please enter valid Email.');
return;
}
$account = new OTS_Account();
$account->findByEMail($email);
if ($account->isLoaded()) {
if ($account->getCustomField('email_verified') == '1') {
$errorWithBackButton('This account is already verified! You can <a href=' . getLink('account/manage') . '>log in</a> on the website.');
return;
}
$accountEmailVerify = AccountEmailVerify::where('account_id', $account->getId())->orderBy('sent_at', 'DESC')->first();
if ($accountEmailVerify && time() - $accountEmailVerify->sent_at < 60) {
$errorWithBackButton('Only one Email per minute is allowed. Please try again later.');
return;
}
$tmp_account = $email;
if (!config('account_login_by_email')) {
$tmp_account = (USE_ACCOUNT_NAME ? $account->getName() : $account->getId());
}
$hash = md5(generateRandomString(16, true, true) . $email);
AccountEmailVerify::create([
'account_id' => $account->getId(),
'hash' => $hash,
'sent_at' => time(),
]);
$verify_url = getLink('account/confirm-email/' . $hash);
$body_html = $twig->render('mail.account.resend-email-verify.html.twig', array(
'account' => $tmp_account,
'verify_url' => generateLink($verify_url, $verify_url, true)
));
if (_mail($account->getEMail(), configLua('serverName') . ' - Verify Account', $body_html)) {
$message = "If account with this email exists - you will become an email with verification link.";
$showForm = false;
} else {
$message = "<p class='error'>An error occurred while sending email (<b>{$email}</b> )! Try again later. For Admin: More info can be found in system/logs/mailer-error.log</p>";
}
}
else {
$message = "<br />If account with this email exists - you will become an email with verification link.";
$showForm = false;
}
$twig->display('success.html.twig', array(
'title' => 'Verify Email Sent',
'description' => $message,
));
}
//show errors if not empty
if (!empty($errors)) {
$twig->display('error_box.html.twig', ['errors' => $errors]);
$twig->display('account.back_button.html.twig', [
'action' => getLink('account/resend-email-verify'),
]);
}
if ($showForm) {
$twig->display('account.resend-email-verify.html.twig');
}

View File

@@ -202,37 +202,35 @@ if($player->isLoaded() && !$player->isDeleted())
unset($storage); unset($storage);
} }
if ($db->hasTableAndColumns('player_items', ['pid', 'sid', 'itemtype'])) { if($db->hasTable('player_items') && $db->hasColumn('player_items', 'pid') && $db->hasColumn('player_items', 'sid') && $db->hasColumn('player_items', 'itemtype')) {
$eq_sql = $db->query('SELECT `pid`, `itemtype` FROM player_items WHERE player_id = '.$player->getId().' AND (`pid` >= 1 and `pid` <= 10)'); $eq_sql = $db->query('SELECT `pid`, `itemtype` FROM player_items WHERE player_id = '.$player->getId().' AND (`pid` >= 1 and `pid` <= 10)');
$equipment = []; $equipment = array();
foreach($eq_sql as $eq) { foreach($eq_sql as $eq)
$equipment[$eq['pid']] = $eq['itemtype']; $equipment[$eq['pid']] = $eq['itemtype'];
}
$empty_slots = ["", "no_helmet", "no_necklace", "no_backpack", "no_armor", "no_handleft", "no_handright", "no_legs", "no_boots", "no_ring", "no_ammo"]; $empty_slots = array("", "no_helmet", "no_necklace", "no_backpack", "no_armor", "no_handleft", "no_handright", "no_legs", "no_boots", "no_ring", "no_ammo");
for($i = 0; $i <= 10; $i++)
for($i = 0; $i <= 10; $i++) { {
if(!isset($equipment[$i]) || $equipment[$i] == 0) if(!isset($equipment[$i]) || $equipment[$i] == 0)
$equipment[$i] = $empty_slots[$i]; $equipment[$i] = $empty_slots[$i];
} }
for($i = 1; $i < 11; $i++) { for($i = 1; $i < 11; $i++)
if(Validator::number($equipment[$i])) { {
if(Validator::number($equipment[$i]))
$equipment[$i] = getItemImage($equipment[$i]); $equipment[$i] = getItemImage($equipment[$i]);
} else
else {
$equipment[$i] = '<img src="images/items/' . $equipment[$i] . '.gif" width="32" height="32" border="0" alt=" ' . $equipment[$i] . '" />'; $equipment[$i] = '<img src="images/items/' . $equipment[$i] . '.gif" width="32" height="32" border="0" alt=" ' . $equipment[$i] . '" />';
} }
}
}
$skulls = [ $skulls = array(
1 => 'yellow_skull', 1 => 'yellow_skull',
2 => 'green_skull', 2 => 'green_skull',
3 => 'white_skull', 3 => 'white_skull',
4 => 'red_skull', 4 => 'red_skull',
5 => 'black_skull', 5 => 'black_skull'
]; );
}
$dead_add_content = ''; $dead_add_content = '';
$deaths = array(); $deaths = array();
@@ -452,8 +450,10 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil
if($query->rowCount() > 0) { if($query->rowCount() > 0) {
echo 'Did you mean:<ul>'; echo 'Did you mean:<ul>';
foreach($query as $player) { foreach($query as $player) {
$player['vocation'] = OTS_Toolbox::getVocationFromPromotion($player['vocation'], $player['promotion'] ?? 0); if(isset($player['promotion'])) {
if((int)$player['promotion'] > 0)
$player['vocation'] += ($player['promotion'] * $config['vocations_amount']);
}
echo '<li>' . getPlayerLink($player['name']) . ' (<small><strong>level ' . $player['level'] . ', ' . $config['vocations'][$player['vocation']] . '</strong></small>)</li>'; echo '<li>' . getPlayerLink($player['name']) . ' (<small><strong>level ' . $player['level'] . ', ' . $config['vocations'][$player['vocation']] . '</strong></small>)</li>';
} }
echo '</ul>'; echo '</ul>';

View File

@@ -21,9 +21,6 @@ if(!$logged) {
$errors[] = 'You are not logged in. You can\'t create guild.'; $errors[] = 'You are not logged in. You can\'t create guild.';
} }
$configLuaFreePremium = configLua('freePremium');
$freePremium = (isset($configLuaFreePremium) && getBoolean($configLuaFreePremium));
$array_of_player_nig = array(); $array_of_player_nig = array();
if(empty($errors)) if(empty($errors))
{ {
@@ -34,7 +31,7 @@ if(empty($errors))
if(!$player_rank->isLoaded()) if(!$player_rank->isLoaded())
{ {
if($player->getLevel() >= setting('core.guild_need_level')) { if($player->getLevel() >= setting('core.guild_need_level')) {
if(!setting('core.guild_need_premium') || $account_logged->isPremium() || $freePremium) { if(!setting('core.guild_need_premium') || $account_logged->isPremium()) {
$array_of_player_nig[] = $player->getName(); $array_of_player_nig[] = $player->getName();
} }
} }
@@ -98,7 +95,7 @@ if($todo == 'save')
if($player->getLevel() < setting('core.guild_need_level')) { if($player->getLevel() < setting('core.guild_need_level')) {
$errors[] = 'Character <b>'.$name.'</b> has too low level. To create guild you need character with level <b>' . setting('core.guild_need_level') . '</b>.'; $errors[] = 'Character <b>'.$name.'</b> has too low level. To create guild you need character with level <b>' . setting('core.guild_need_level') . '</b>.';
} }
if(setting('core.guild_need_premium') && !$account_logged->isPremium() && !$freePremium) { if(setting('core.guild_need_premium') && !$account_logged->isPremium()) {
$errors[] = 'Character <b>'.$name.'</b> is on FREE account. To create guild you need PREMIUM account.'; $errors[] = 'Character <b>'.$name.'</b> is on FREE account. To create guild you need PREMIUM account.';
} }
} }

View File

@@ -91,18 +91,13 @@ $guild_owner = $guild->getOwner();
if($guild_owner->isLoaded()) if($guild_owner->isLoaded())
$guild_owner_name = $guild_owner->getName(); $guild_owner_name = $guild_owner->getName();
$deletedColumn = 'deleted';
if ($db->hasColumn('players', 'deletion')) {
$deletedColumn = 'deletion';
}
$guild_members = array(); $guild_members = array();
foreach($rank_list as $rank) foreach($rank_list as $rank)
{ {
if($db->hasTable(GUILD_MEMBERS_TABLE)) if($db->hasTable(GUILD_MEMBERS_TABLE))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `' . GUILD_MEMBERS_TABLE . '`.`rank_id` as `rank_id` FROM `players`, `' . GUILD_MEMBERS_TABLE . '` WHERE `' . GUILD_MEMBERS_TABLE . '`.`rank_id` = ' . $rank->getId() . ' AND `players`.`id` = `' . GUILD_MEMBERS_TABLE . '`.`player_id` AND `' . $deletedColumn . '` = 0 ORDER BY `name`;'); $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `' . GUILD_MEMBERS_TABLE . '`.`rank_id` as `rank_id` FROM `players`, `' . GUILD_MEMBERS_TABLE . '` WHERE `' . GUILD_MEMBERS_TABLE . '`.`rank_id` = ' . $rank->getId() . ' AND `players`.`id` = `' . GUILD_MEMBERS_TABLE . '`.`player_id` ORDER BY `name`;');
else if($db->hasColumn('players', 'rank_id')) else if($db->hasColumn('players', 'rank_id'))
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank->getId() . ' AND `' . $deletedColumn . '` = 0;'); $players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank->getId() . ' AND `deleted` = 0;');
$players_with_rank_number = $players_with_rank->rowCount(); $players_with_rank_number = $players_with_rank->rowCount();
if($players_with_rank_number > 0) if($players_with_rank_number > 0)

View File

@@ -13,7 +13,6 @@ use MyAAC\Cache\Cache;
use MyAAC\Models\Player; use MyAAC\Models\Player;
use MyAAC\Models\PlayerDeath; use MyAAC\Models\PlayerDeath;
use MyAAC\Models\PlayerKillers; use MyAAC\Models\PlayerKillers;
use MyAAC\Server\XML\Vocations;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Highscores'; $title = 'Highscores';
@@ -36,20 +35,24 @@ if(!is_numeric($page) || $page < 1 || $page > PHP_INT_MAX) {
$query = Player::query(); $query = Player::query();
$configVocations = config('vocations'); $configVocations = config('vocations');
$configVocationsAmount = config('vocations_amount');
$vocationId = null; $vocationId = null;
if($vocation !== 'all') { if($vocation !== 'all') {
foreach($configVocations as $id => $name) { foreach($configVocations as $id => $name) {
if(strtolower($name) == $vocation) { if(strtolower($name) == $vocation) {
$vocationId = $id; $vocationId = $id;
$filterVocations = [$id]; $add_vocs = [$id];
while($tmpVoc = Vocations::getPromoted($id)) { if ($id !== 0) {
$id = $tmpVoc; $i = $id + $configVocationsAmount;
$filterVocations[] = $tmpVoc; while (isset($configVocations[$i])) {
$add_vocs[] = $i;
$i += $configVocationsAmount;
}
} }
$query->whereIn('players.vocation', $filterVocations); $query->whereIn('players.vocation', $add_vocs);
break; break;
} }
} }
@@ -173,9 +176,7 @@ if (empty($highscores)) {
POT::SKILL_FISH => 'skill_fishing', POT::SKILL_FISH => 'skill_fishing',
); );
$query $query->addSelect($skill_ids[$skill] . ' as value');
->addSelect($skill_ids[$skill] . ' as value')
->orderByDesc($skill_ids[$skill] . '_tries');
} else { } else {
$query $query
->join('player_skills', 'player_skills.player_id', '=', 'players.id') ->join('player_skills', 'player_skills.player_id', '=', 'players.id')
@@ -197,11 +198,11 @@ if (empty($highscores)) {
if ($skill == POT::SKILL__MAGLEVEL) { if ($skill == POT::SKILL__MAGLEVEL) {
$query $query
->addSelect('players.maglevel as value', 'players.maglevel') ->addSelect('players.maglevel as value', 'players.maglevel')
->orderByDesc('manaspent'); ->orderBy('manaspent');
} else { // level } else { // level
$query $query
->addSelect('players.level as value', 'players.experience') ->addSelect('players.level as value', 'players.experience')
->orderByDesc('experience'); ->orderBy('experience');
$list = 'experience'; $list = 'experience';
} }
} }
@@ -322,5 +323,4 @@ $twig->display('highscores.html.twig', [
'page' => $page, 'page' => $page,
'baseLink' => $baseLink, 'baseLink' => $baseLink,
'updatedAt' => $updatedAt, 'updatedAt' => $updatedAt,
'baseVocations' => Vocations::getBase(true),
]); ]);

View File

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

View File

@@ -12,7 +12,6 @@
use MyAAC\Cache\Cache; use MyAAC\Cache\Cache;
use MyAAC\Models\ServerConfig; use MyAAC\Models\ServerConfig;
use MyAAC\Models\ServerRecord; use MyAAC\Models\ServerRecord;
use MyAAC\Server\XML\Vocations;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Who is online?'; $title = 'Who is online?';
@@ -57,14 +56,15 @@ $cached = Cache::remember("online_$order", setting('core.online_cache_ttl') * 60
$vocations = array_map(function ($name) { $vocations = array_map(function ($name) {
return 0; return 0;
}, config('vocations')); }, setting('core.vocations'));
if($db->hasTable('players_online')) // tfs 1.0 if($db->hasTable('players_online')) // tfs 1.0
$playersOnline = $db->query('SELECT `accounts`.`country`, `players`.`name`, `players`.`level`, `players`.`vocation`' . $outfit . ', `' . $skull_time . '` as `skulltime`, `' . $skull_type . '` as `skull` FROM `accounts`, `players`, `players_online` WHERE `players`.`id` = `players_online`.`player_id` AND `accounts`.`id` = `players`.`account_id` ORDER BY ' . $orderSql); $playersOnline = $db->query('SELECT `accounts`.`country`, `players`.`name`, `players`.`level`, `players`.`vocation`' . $outfit . ', `' . $skull_time . '` as `skulltime`, `' . $skull_type . '` as `skull` FROM `accounts`, `players`, `players_online` WHERE `players`.`id` = `players_online`.`player_id` AND `accounts`.`id` = `players`.`account_id` ORDER BY ' . $orderSql);
else else
$playersOnline = $db->query('SELECT `accounts`.`country`, `players`.`name`, `players`.`level`, `players`.`vocation`' . $outfit . ', ' . $promotion . ' `' . $skull_time . '` as `skulltime`, `' . $skull_type . '` as `skull` FROM `accounts`, `players` WHERE `players`.`online` > 0 AND `accounts`.`id` = `players`.`account_id` ORDER BY ' . $orderSql); $playersOnline = $db->query('SELECT `accounts`.`country`, `players`.`name`, `players`.`level`, `players`.`vocation`' . $outfit . ', ' . $promotion . ' `' . $skull_time . '` as `skulltime`, `' . $skull_type . '` as `skull` FROM `accounts`, `players` WHERE `players`.`online` > 0 AND `accounts`.`id` = `players`.`account_id` ORDER BY ' . $orderSql);
$configVocations = config('vocations'); $settingVocations = setting('core.vocations');
$settingVocationsAmount = setting('core.vocations_amount');
$players = []; $players = [];
foreach($playersOnline as $player) { foreach($playersOnline as $player) {
@@ -81,19 +81,22 @@ $cached = Cache::remember("online_$order", setting('core.online_cache_ttl') * 60
} }
} }
$player['vocation'] = OTS_Toolbox::getVocationFromPromotion($player['vocation'], $player['promotion'] ?? 0); if(isset($player['promotion'])) {
if((int)$player['promotion'] > 0)
$player['vocation'] += ($player['promotion'] * $settingVocationsAmount);
}
$players[] = array( $players[] = array(
'name' => getPlayerLink($player['name']), 'name' => getPlayerLink($player['name']),
'player' => $player, 'player' => $player,
'level' => $player['level'], 'level' => $player['level'],
'vocation' => $configVocations[$player['vocation']], 'vocation' => $settingVocations[$player['vocation']],
'skull' => $skull, 'skull' => $skull,
'country_image' => getFlagImage($player['country']), 'country_image' => getFlagImage($player['country']),
'outfit' => setting('core.outfit_images_url') . '?id=' . $player['looktype'] . ($outfit_addons ? '&addons=' . $player['lookaddons'] : '') . '&head=' . $player['lookhead'] . '&body=' . $player['lookbody'] . '&legs=' . $player['looklegs'] . '&feet=' . $player['lookfeet'], 'outfit' => setting('core.outfit_images_url') . '?id=' . $player['looktype'] . ($outfit_addons ? '&addons=' . $player['lookaddons'] : '') . '&head=' . $player['lookhead'] . '&body=' . $player['lookbody'] . '&legs=' . $player['looklegs'] . '&feet=' . $player['lookfeet'],
); );
$vocations[Vocations::getOriginal($player['vocation'])]++; $vocations[($player['vocation'] > $settingVocationsAmount ? $player['vocation'] - $settingVocationsAmount : $player['vocation'])]++;
} }
$record = ''; $record = '';
@@ -139,7 +142,6 @@ $twig->display('online.html.twig', array(
'vocations' => $cached['vocations'], 'vocations' => $cached['vocations'],
'vocs' => $cached['vocations'], // deprecated, to be removed 'vocs' => $cached['vocations'], // deprecated, to be removed
'order' => $order, 'order' => $order,
'baseVocations' => Vocations::getBase(false),
)); ));
// search bar // search bar

View File

@@ -88,10 +88,8 @@ if($logged && $account_logged && $account_logged->isLoaded()) {
/** /**
* Routes loading * Routes loading
*/ */
$routesFinal = [];
$dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) { $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) {
global $cache, $routesFinal; $routesFinal = [];
foreach(getDatabasePages() as $page) { foreach(getDatabasePages() as $page) {
$routesFinal[] = ['*', $page, '__database__/' . $page, 100]; $routesFinal[] = ['*', $page, '__database__/' . $page, 100];
} }
@@ -167,7 +165,7 @@ $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r)
echo '</pre>'; echo '</pre>';
die; die;
*/ */
foreach ($routesFinal as &$route) { foreach ($routesFinal as $route) {
if ($route[0] === '*') { if ($route[0] === '*') {
$route[0] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD']; $route[0] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'];
} }
@@ -200,10 +198,6 @@ $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r)
log_append('router.log', $warning); log_append('router.log', $warning);
} }
} }
if ($cache->enabled()) {
$cache->set('routes_final', serialize($routesFinal), 10 * 365 * 24 * 60 * 60); // 10 years / infinite
}
}, },
[ [
'cacheFile' => CACHE . 'route.cache', 'cacheFile' => CACHE . 'route.cache',
@@ -218,7 +212,7 @@ $found = true;
// old support for pages like /?subtopic=accountmanagement // old support for pages like /?subtopic=accountmanagement
$page = $_REQUEST['p'] ?? ($_REQUEST['subtopic'] ?? ''); $page = $_REQUEST['p'] ?? ($_REQUEST['subtopic'] ?? '');
if(!empty($page) && preg_match('/^[A-z0-9\/\-]+$/', $page)) { if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) {
if (isset($_REQUEST['p'])) { // some plugins may require this if (isset($_REQUEST['p'])) { // some plugins may require this
$_REQUEST['subtopic'] = $_REQUEST['p']; $_REQUEST['subtopic'] = $_REQUEST['p'];
} }
@@ -227,28 +221,11 @@ if(!empty($page) && preg_match('/^[A-z0-9\/\-]+$/', $page)) {
require SYSTEM . 'compat/pages.php'; require SYSTEM . 'compat/pages.php';
} }
$foundRoute = false;
$tmp = null;
if ($cache->enabled() && $cache->fetch('routes_final', $tmp)) {
$routesFinal = unserialize($tmp);
}
foreach ($routesFinal as $route) {
if ($page === $route[1]) {
$file = $route[2];
$foundRoute = true;
break;
}
}
if (!$foundRoute) {
$file = loadPageFromFileSystem($page, $found); $file = loadPageFromFileSystem($page, $found);
if(!$found) { if(!$found) {
$file = false; $file = false;
} }
} }
}
else { else {
$routeInfo = $dispatcher->dispatch($httpMethod, $uri); $routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) { switch ($routeInfo[0]) {

View File

@@ -219,14 +219,7 @@ return [
'cache_engine' => [ 'cache_engine' => [
'name' => 'Cache Engine', 'name' => 'Cache Engine',
'type' => 'options', 'type' => 'options',
'options' => [ 'options' => ['auto' => 'Auto', 'file' => 'Files', 'apc' => 'APC', 'apcu' => 'APCu', 'disable' => 'Disable'],
'auto' => 'Auto',
'file' => 'Files',
'apc' => 'APC',
'apcu' => 'APCu',
'php' => 'PHP',
'disable' => 'Disable',
],
'desc' => 'Auto is most reasonable. It will detect the best cache engine', 'desc' => 'Auto is most reasonable. It will detect the best cache engine',
'default' => 'auto', 'default' => 'auto',
'is_config' => true, 'is_config' => true,
@@ -319,6 +312,23 @@ return [
}, },
], ],
], ],
'vocations_amount' => [
'name' => 'Vocations Amount',
'type' => 'number',
'desc' => 'How much basic vocations your server got (without promotion)',
'default' => 4,
],
'vocations' => [
'name' => 'Vocation Names',
'type' => 'textarea',
'desc' => 'Separated by comma. Must be in the same order as in vocations.xml, starting with id: 0.',
'default' => 'None, Sorcerer, Druid, Paladin, Knight, Master Sorcerer, Elder Druid,Royal Paladin, Elite Knight',
'callbacks' => [
'get' => function ($value) {
return array_map('trim', explode(',', $value));
},
],
],
[ [
'type' => 'category', 'type' => 'category',
'title' => 'Database', 'title' => 'Database',
@@ -727,18 +737,6 @@ Sent by MyAAC,<br/>
'desc' => 'should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io', 'desc' => 'should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io',
'default' => true, 'default' => true,
], ],
'account_countries_most_popular' => [
'name' => 'Account Countries Most Popular',
'type' => 'text',
'desc' => 'Those countries will be display at the top of the list on the create account page. The short codes of countries can be found in file <i>system/countries.conf.php</i>',
'default' => 'pl,se,br,us,gb',
'callbacks' => [
'get' => function ($value) {
$tmp = array_map('trim', explode(',', $value));
return array_filter($tmp, function ($v) {return !empty($v); });
},
],
],
'characters_per_account' => [ 'characters_per_account' => [
'name' => 'Characters per Account', 'name' => 'Characters per Account',
'type' => 'number', 'type' => 'number',

View File

@@ -13,8 +13,8 @@ namespace MyAAC\Cache;
class APC class APC
{ {
private string $prefix; private $prefix;
private bool $enabled; private $enabled;
public function __construct($prefix = '') public function __construct($prefix = '')
{ {
@@ -22,14 +22,14 @@ class APC
$this->enabled = function_exists('apc_fetch'); $this->enabled = function_exists('apc_fetch');
} }
public function set($key, $var, $ttl = 0): void public function set($key, $var, $ttl = 0)
{ {
$key = $this->prefix . $key; $key = $this->prefix . $key;
apc_delete($key); apc_delete($key);
apc_store($key, $var, $ttl); apc_store($key, $var, $ttl);
} }
public function get($key): string public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($this->prefix . $key, $tmp)) { if ($this->fetch($this->prefix . $key, $tmp)) {
@@ -39,15 +39,18 @@ class APC
return ''; return '';
} }
public function fetch($key, &$var): bool { public function fetch($key, &$var)
{
return ($var = apc_fetch($this->prefix . $key)) !== false; return ($var = apc_fetch($this->prefix . $key)) !== false;
} }
public function delete($key): void { public function delete($key)
{
apc_delete($this->prefix . $key); apc_delete($this->prefix . $key);
} }
public function enabled(): bool { public function enabled()
{
return $this->enabled; return $this->enabled;
} }
} }

View File

@@ -13,8 +13,8 @@ namespace MyAAC\Cache;
class APCu class APCu
{ {
private string $prefix; private $prefix;
private bool $enabled; private $enabled;
public function __construct($prefix = '') public function __construct($prefix = '')
{ {
@@ -22,14 +22,14 @@ class APCu
$this->enabled = function_exists('apcu_fetch'); $this->enabled = function_exists('apcu_fetch');
} }
public function set($key, $var, $ttl = 0): void public function set($key, $var, $ttl = 0)
{ {
$key = $this->prefix . $key; $key = $this->prefix . $key;
apcu_delete($key); apcu_delete($key);
apcu_store($key, $var, $ttl); apcu_store($key, $var, $ttl);
} }
public function get($key): string public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($this->prefix . $key, $tmp)) { if ($this->fetch($this->prefix . $key, $tmp)) {
@@ -39,15 +39,18 @@ class APCu
return ''; return '';
} }
public function fetch($key, &$var): bool { public function fetch($key, &$var)
{
return ($var = apcu_fetch($this->prefix . $key)) !== false; return ($var = apcu_fetch($this->prefix . $key)) !== false;
} }
public function delete($key): void { public function delete($key)
{
apcu_delete($this->prefix . $key); apcu_delete($this->prefix . $key);
} }
public function enabled(): bool { public function enabled()
{
return $this->enabled; return $this->enabled;
} }
} }

View File

@@ -83,7 +83,7 @@ class Cache
/** /**
* @return string * @return string
*/ */
public static function detect(): string public static function detect()
{ {
if (function_exists('apc_fetch')) if (function_exists('apc_fetch'))
return 'apc'; return 'apc';
@@ -98,7 +98,8 @@ class Cache
/** /**
* @return bool * @return bool
*/ */
public function enabled(): bool { public function enabled()
{
return false; return false;
} }
@@ -114,11 +115,6 @@ class Cache
return unserialize($value); return unserialize($value);
} }
// -1 for infinite cache
if ($ttl == -1) {
$ttl = 10 * 365 * 24 * 60 * 60; // 10 years should be enough
}
$value = $callback(); $value = $callback();
$cache->set($key, serialize($value), $ttl); $cache->set($key, serialize($value), $ttl);
return $value; return $value;

View File

@@ -12,22 +12,18 @@ namespace MyAAC\Cache;
class File class File
{ {
private string $prefix; private $prefix;
private string $dir; private $dir;
private bool $enabled; private $enabled;
public function __construct($prefix = '', $dir = '') public function __construct($prefix = '', $dir = '')
{ {
$this->prefix = $prefix; $this->prefix = $prefix;
$this->dir = $dir; $this->dir = $dir;
ensureFolderExists($this->dir);
ensureIndexExists($this->dir);
$this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir)); $this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir));
} }
public function set($key, $var, $ttl = 0): void public function set($key, $var, $ttl = 0)
{ {
$file = $this->_name($key); $file = $this->_name($key);
file_put_contents($file, $var); file_put_contents($file, $var);
@@ -39,7 +35,7 @@ class File
touch($file, time() + $ttl); touch($file, time() + $ttl);
} }
public function get($key): string public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($key, $tmp)) { if ($this->fetch($key, $tmp)) {
@@ -49,7 +45,7 @@ class File
return ''; return '';
} }
public function fetch($key, &$var): bool public function fetch($key, &$var)
{ {
$file = $this->_name($key); $file = $this->_name($key);
if (!file_exists($file) || filemtime($file) < time()) { if (!file_exists($file) || filemtime($file) < time()) {
@@ -60,7 +56,7 @@ class File
return true; return true;
} }
public function delete($key): void public function delete($key)
{ {
$file = $this->_name($key); $file = $this->_name($key);
if (file_exists($file)) { if (file_exists($file)) {
@@ -68,11 +64,13 @@ class File
} }
} }
public function enabled(): bool { public function enabled()
{
return $this->enabled; return $this->enabled;
} }
private function _name($key): string { private function _name($key)
{
return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key)); return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key));
} }
} }

View File

@@ -12,40 +12,36 @@ namespace MyAAC\Cache;
class PHP class PHP
{ {
private string $prefix; private $prefix;
private string $dir; private $dir;
private bool $enabled; private $enabled;
public function __construct($prefix = '', $dir = '') public function __construct($prefix = '', $dir = '')
{ {
$this->prefix = $prefix; $this->prefix = $prefix;
$this->dir = $dir; $this->dir = $dir;
ensureFolderExists($this->dir);
ensureIndexExists($this->dir);
$this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir)); $this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir));
} }
public function set($key, $var, $ttl = 0): void public function set($key, $var, $ttl = 0)
{ {
$var = var_export($var, true); $var = var_export($var, true);
// Write to temp file first to ensure atomicity
$tmp = $this->dir . "tmp_$key." . uniqid('', true) . '.tmp';
file_put_contents($tmp, '<?php $var = ' . $var . ';', LOCK_EX);
$file = $this->_name($key);
rename($tmp, $file);
if ($ttl === 0) { if ($ttl === 0) {
$ttl = 365 * 24 * 60 * 60; // 365 days $ttl = 365 * 24 * 60 * 60; // 365 days
} }
$expires = time() + $ttl; touch($file, time() + $ttl);
// Write to temp file first to ensure atomicity
$tmp = $this->dir . "tmp_$key." . uniqid('', true) . '.tmp';
file_put_contents($tmp, "<?php return ['expires' => $expires, 'var' => $var];", LOCK_EX);
$file = $this->_name($key);
rename($tmp, $file);
} }
public function get($key): string public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($key, $tmp)) { if ($this->fetch($key, $tmp)) {
@@ -55,23 +51,19 @@ class PHP
return ''; return '';
} }
public function fetch($key, &$var): bool public function fetch($key, &$var)
{ {
$file = $this->_name($key); $file = $this->_name($key);
if (!file_exists($file)) { if (!file_exists($file) || filemtime($file) < time()) {
return false; return false;
} }
$content = include $file; @include $file;
if (!isset($content) || $content['expires'] < time()) { $var = isset($var) ? $var : null;
return false;
}
$var = $content['var'];
return true; return true;
} }
public function delete($key): void public function delete($key)
{ {
$file = $this->_name($key); $file = $this->_name($key);
if (file_exists($file)) { if (file_exists($file)) {
@@ -79,11 +71,13 @@ class PHP
} }
} }
public function enabled(): bool { public function enabled()
{
return $this->enabled; return $this->enabled;
} }
private function _name($key): string { private function _name($key)
{
return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key) . '.php'); return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key) . '.php');
} }
} }

View File

@@ -13,8 +13,8 @@ namespace MyAAC\Cache;
class XCache class XCache
{ {
private string $prefix; private $prefix;
private bool $enabled; private $enabled;
public function __construct($prefix = '') public function __construct($prefix = '')
{ {
@@ -22,14 +22,14 @@ class XCache
$this->enabled = function_exists('xcache_get') && ini_get('xcache.var_size'); $this->enabled = function_exists('xcache_get') && ini_get('xcache.var_size');
} }
public function set($key, $var, $ttl = 0): void public function set($key, $var, $ttl = 0)
{ {
$key = $this->prefix . $key; $key = $this->prefix . $key;
xcache_unset($key); xcache_unset($key);
xcache_set($key, $var, $ttl); xcache_set($key, $var, $ttl);
} }
public function get($key): string public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($this->prefix . $key, $tmp)) { if ($this->fetch($this->prefix . $key, $tmp)) {
@@ -39,7 +39,7 @@ class XCache
return ''; return '';
} }
public function fetch($key, &$var): bool public function fetch($key, &$var)
{ {
$key = $this->prefix . $key; $key = $this->prefix . $key;
if (!xcache_isset($key)) { if (!xcache_isset($key)) {
@@ -50,11 +50,13 @@ class XCache
return true; return true;
} }
public function delete($key): void { public function delete($key)
{
xcache_unset($this->prefix . $key); xcache_unset($this->prefix . $key);
} }
public function enabled(): bool { public function enabled()
{
return $this->enabled; return $this->enabled;
} }
} }

View File

@@ -1,33 +0,0 @@
<?php
namespace MyAAC\Commands;
use POT;
trait Env
{
protected function init(): void
{
global $config;
if (!isset($config['installed']) || !$config['installed']) {
throw new \RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.');
}
if(empty($config['server_path'])) {
throw new \RuntimeException('Server Path has been not set. Go to config.php and set it.');
}
// take care of trailing slash at the end
if($config['server_path'][strlen($config['server_path']) - 1] !== '/')
$config['server_path'] .= '/';
$config['lua'] = load_config_lua($config['server_path'] . 'config.lua');
// POT
require_once SYSTEM . 'libs/pot/OTS.php';
$ots = POT::getInstance();
$eloquentConnection = null;
require_once SYSTEM . 'database.php';
}
}

View File

@@ -9,8 +9,6 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class MigrateCommand extends Command class MigrateCommand extends Command
{ {
use Env;
protected function configure(): void protected function configure(): void
{ {
$this->setName('migrate') $this->setName('migrate')
@@ -19,19 +17,9 @@ class MigrateCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$this->init(); require SYSTEM . 'init.php';
$io = new SymfonyStyle($input, $output); $io = new SymfonyStyle($input, $output);
$tmp = '';
if(fetchDatabaseConfig('database_version', $tmp)) { // we got version
$tmp = (int)$tmp;
if ($tmp >= DATABASE_VERSION) {
$io->success('Already on latest version.');
return Command::SUCCESS;
}
}
require SYSTEM . 'migrate.php'; require SYSTEM . 'migrate.php';
$io->success('Migrated to latest version (' . DATABASE_VERSION . ')'); $io->success('Migrated to latest version (' . DATABASE_VERSION . ')');

View File

@@ -10,8 +10,6 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class MigrateRunCommand extends Command class MigrateRunCommand extends Command
{ {
use Env;
protected function configure(): void protected function configure(): void
{ {
$this->setName('migrate:run') $this->setName('migrate:run')
@@ -25,12 +23,12 @@ class MigrateRunCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int
{ {
require SYSTEM . 'init.php';
$io = new SymfonyStyle($input, $output); $io = new SymfonyStyle($input, $output);
$ids = $input->getArgument('id'); $ids = $input->getArgument('id');
$this->init();
// pre-check // pre-check
// in case one of the migrations doesn't exist - we won't execute any of them // in case one of the migrations doesn't exist - we won't execute any of them
foreach ($ids as $id) { foreach ($ids as $id) {

View File

@@ -11,8 +11,6 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class MigrateToCommand extends Command class MigrateToCommand extends Command
{ {
use Env;
protected function configure(): void protected function configure(): void
{ {
$this->setName('migrate:to') $this->setName('migrate:to')
@@ -34,7 +32,7 @@ class MigrateToCommand extends Command
return Command::FAILURE; return Command::FAILURE;
} }
$this->init(); $this->initEnv();
$currentVersion = Config::where('name', 'database_version')->first()->value; $currentVersion = Config::where('name', 'database_version')->first()->value;
if ($currentVersion > $versionDest) { if ($currentVersion > $versionDest) {
@@ -82,4 +80,29 @@ class MigrateToCommand extends Command
updateDatabaseConfig('database_version', ($_up ? $id : $id - 1)); updateDatabaseConfig('database_version', ($_up ? $id : $id - 1));
} }
private function initEnv()
{
global $config;
if (!isset($config['installed']) || !$config['installed']) {
throw new \RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.');
}
if(empty($config['server_path'])) {
throw new \RuntimeException('Server Path has been not set. Go to config.php and set it.');
}
// take care of trailing slash at the end
if($config['server_path'][strlen($config['server_path']) - 1] !== '/')
$config['server_path'] .= '/';
$config['lua'] = load_config_lua($config['server_path'] . 'config.lua');
// POT
require_once SYSTEM . 'libs/pot/OTS.php';
$ots = POT::getInstance();
$eloquentConnection = null;
require_once SYSTEM . 'database.php';
}
} }

View File

@@ -13,7 +13,6 @@ class PluginDisableCommand extends Command
protected function configure(): void protected function configure(): void
{ {
$this->setName('plugin:disable') $this->setName('plugin:disable')
->setAliases(['plugin:deactivate'])
->setDescription('This command disables plugin') ->setDescription('This command disables plugin')
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to disable'); ->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to disable');
} }

View File

@@ -13,7 +13,6 @@ class PluginEnableCommand extends Command
protected function configure(): void protected function configure(): void
{ {
$this->setName('plugin:enable') $this->setName('plugin:enable')
->setAliases(['plugin:activate'])
->setDescription('This command enables plugin') ->setDescription('This command enables plugin')
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to enable'); ->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to enable');
} }

View File

@@ -13,7 +13,6 @@ class PluginUninstallCommand extends Command
protected function configure(): void protected function configure(): void
{ {
$this->setName('plugin:uninstall') $this->setName('plugin:uninstall')
->setAliases(['plugin:remove', 'plugin:delete'])
->setDescription('This command uninstalls plugin') ->setDescription('This command uninstalls plugin')
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to uninstall'); ->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to uninstall');
} }

View File

@@ -76,11 +76,10 @@ class Items
public static function get($id) { public static function get($id) {
self::load(); self::load();
return self::$items[$id] ?? []; return isset(self::$items[$id]) ? self::$items[$id] : [];
} }
public static function getDescription($id, $count = 1): string public static function getDescription($id, $count = 1) {
{
$item = self::get($id); $item = self::get($id);
$attr = $item['attributes']; $attr = $item['attributes'];
@@ -113,15 +112,15 @@ class Items
$s .= 'an item of type ' . $item['id']; $s .= 'an item of type ' . $item['id'];
if(isset($attr['type']) && strtolower($attr['type']) == 'rune') { if(isset($attr['type']) && strtolower($attr['type']) == 'rune') {
$spell = Spell::where('item_id', $id)->first(); $item = Spell::where('item_id', $id)->first();
if($spell) { if($item) {
if($spell->level > 0 && $spell->maglevel > 0) { if($item->level > 0 && $item->maglevel > 0) {
$s .= '. ' . ($count > 1 ? 'They' : 'It') . ' can only be used by '; $s .= '. ' . ($count > 1 ? "They" : "It") . ' can only be used by ';
} }
$configVocations = config('vocations'); $configVocations = config('vocations');
if(!empty(trim($spell->vocations))) { if(!empty(trim($item->vocations))) {
$vocations = json_decode($spell->vocations); $vocations = json_decode($item->vocations);
if(count($vocations) > 0) { if(count($vocations) > 0) {
foreach($vocations as $voc => $show) { foreach($vocations as $voc => $show) {
$vocations[$configVocations[$voc]] = $show; $vocations[$configVocations[$voc]] = $show;
@@ -134,39 +133,8 @@ class Items
$s .= ' with'; $s .= ' with';
if ($spell->level > 0) {
$s .= ' level ' . $spell->level;
}
if ($spell->maglevel > 0) {
if ($spell->level > 0) {
$s .= ' and';
}
$s .= ' magic level ' . $spell->maglevel;
}
$s .= ' or higher';
} }
} }
if (!empty($item['weaponType'])) {
if ($item['weaponType'] == 'distance' && isset($item['ammoType'])) {
$s .= ' (Range:' . $item['range'];
}
if (isset($item['attack']) && $item['attack'] != 0) {
$s .= ', Atk ' . ($item['attack'] > 0 ? '+' . $item['attack'] : '-' . $item['attack']);
}
if (isset($item['hitChance']) && $item['hitChance'] != -1) {
$s .= ', Hit% ' . ($item['hitChance'] > 0 ? '+' . $item['hitChance'] : '-' . $item['hitChance']);
}
elseif ($item['weaponType'] != 'ammo') {
}
}
return $s; return $s;
} }
} }

View File

@@ -5,15 +5,11 @@ namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
/** /**
* @property integer $premium_ends_at
* @property integer $premend
* @property integer $lastday * @property integer $lastday
* @property integer $premdays * @property integer $premdays
*/ */
class Account extends Model { class Account extends Model {
const GRATIS_PREMIUM_DAYS = 65535;
protected $table = 'accounts'; protected $table = 'accounts';
public $timestamps = false; public $timestamps = false;
@@ -37,35 +33,32 @@ class Account extends Model {
public function getPremiumDaysAttribute() public function getPremiumDaysAttribute()
{ {
if(isset($this->premium_ends_at) || isset($this->premend) || if(isset($this->premium_ends_at) || isset($this->premend)) {
(isCanary() && isset($this->lastday))) { $col = isset($this->premium_ends_at) ? 'premium_ends_at' : 'premend';
$col = (isset($this->premium_ends_at) ? 'premium_ends_at' : (isset($this->lastday) ? 'lastday' : 'premend'));
$ret = ceil(($this->{$col}- time()) / (24 * 60 * 60)); $ret = ceil(($this->{$col}- time()) / (24 * 60 * 60));
return max($ret, 0); return $ret > 0 ? $ret : 0;
} }
if($this->premdays == 0) { if($this->premdays == 0) {
return 0; return 0;
} }
if($this->premdays == self::GRATIS_PREMIUM_DAYS){ if($this->premdays == 65535){
return self::GRATIS_PREMIUM_DAYS; return 65535;
} }
$ret = ceil($this->premdays - ((int)date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->lastday))) - date("z", $this->lastday))); $ret = ceil($this->premdays - ((int)date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->lastday))) - date("z", $this->lastday)));
return max($ret, 0); return max($ret, 0);
} }
public function getIsPremiumAttribute(): bool public function getIsPremiumAttribute()
{ {
if(isset($this->premium_ends_at) || isset($this->premend) || if(isset($this->premium_ends_at)) {
(isCanary() && isset($this->lastday))) { return $this->premium_ends_at > time();
$col = (isset($this->premium_ends_at) ? 'premium_ends_at' : (isset($this->lastday) ? 'lastday' : 'premend'));
return $this->{$col} > time();
} }
if($this->premdays == self::GRATIS_PREMIUM_DAYS){ if(isset($this->premend)) {
return true; return $this->premend > time();
} }
return ($this->premdays - (date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->lastday))) - date("z", $this->lastday)) > 0); return ($this->premdays - (date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->lastday))) - date("z", $this->lastday)) > 0);

View File

@@ -9,6 +9,6 @@ class AccountAction extends Model {
public $timestamps = false; public $timestamps = false;
protected $fillable = ['account_id', 'ip', 'date', 'action']; protected $fillable = ['account_id', 'ip', 'ipv6', 'date', 'action'];
} }

View File

@@ -1,15 +0,0 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class AccountEmailVerify extends Model
{
protected $table = TABLE_PREFIX . 'account_emails_verify';
public $timestamps = false;
protected $fillable = ['account_id', 'hash', 'sent_at'];
}

View File

@@ -18,16 +18,7 @@ class Changelog extends Model {
public $timestamps = false; public $timestamps = false;
protected $fillable = [
'body', 'type', 'where',
'date', 'player_id', 'hide',
];
public function scopeIsPublic($query) { public function scopeIsPublic($query) {
$query->where('hide', '!=', 1); $query->where('hide', '!=', 1);
} }
public function player() {
return $this->belongsTo(Player::class);
}
} }

View File

@@ -1,16 +0,0 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class ForumBoard extends Model {
protected $table = TABLE_PREFIX . 'forum_boards';
public $timestamps = false;
protected $fillable = [
'name', 'description', 'ordering',
'guild', 'access', 'closed', 'hide',
];
}

View File

@@ -10,9 +10,4 @@ class Gallery extends Model {
public $timestamps = false; public $timestamps = false;
protected $fillable = [
'comment', 'image', 'thumb',
'author', 'ordering', 'hide',
];
} }

View File

@@ -1,15 +0,0 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class NewsCategory extends Model {
protected $table = TABLE_PREFIX . 'news_categories';
public $timestamps = false;
protected $fillable = [
'name', 'description', 'icon_id', 'hide'
];
}

View File

@@ -46,8 +46,14 @@ class Player extends Model {
}); });
} }
public function getVocationNameAttribute() { public function getVocationNameAttribute()
return \OTS_Toolbox::getVocationName($this->vocation, $this->promotion ?? 0); {
$vocation = $this->vocation;
if (isset($this->promotion) && $this->promotion > 0) {
$vocation += ($this->promotion * setting('core.vocations_amount'));
}
return config('vocations')[$vocation] ?? 'Unknown';
} }
public function getIsDeletedAttribute() public function getIsDeletedAttribute()

View File

@@ -513,9 +513,6 @@ class Plugins {
return false; return false;
} }
ensureFolderExists($cachePlugins = CACHE . 'plugins');
ensureIndexExists($cachePlugins);
self::$error = 'There was a problem with extracting zip archive.'; self::$error = 'There was a problem with extracting zip archive.';
$file_name = $plugin_temp_dir . $json_file; $file_name = $plugin_temp_dir . $json_file;
if(!file_exists($file_name)) { if(!file_exists($file_name)) {
@@ -552,21 +549,21 @@ class Plugins {
if(isset($plugin_json['require'])) { if(isset($plugin_json['require'])) {
$require = $plugin_json['require']; $require = $plugin_json['require'];
$myaac_satisfied = true; $myaac_satified = true;
if(isset($require['myaac_'])) { if(isset($require['myaac_'])) {
$require_myaac = $require['myaac_']; $require_myaac = $require['myaac_'];
if(!Semver::satisfies(MYAAC_VERSION, $require_myaac)) { if(!Semver::satisfies(MYAAC_VERSION, $require_myaac)) {
$myaac_satisfied = false; $myaac_satified = false;
} }
} }
else if(isset($require['myaac'])) { else if(isset($require['myaac'])) {
$require_myaac = $require['myaac']; $require_myaac = $require['myaac'];
if(version_compare(MYAAC_VERSION, $require_myaac, '<')) { if(version_compare(MYAAC_VERSION, $require_myaac, '<')) {
$myaac_satisfied = false; $myaac_satified = false;
} }
} }
if(!$myaac_satisfied) { if(!$myaac_satified) {
self::$error = "Your AAC version doesn't meet the requirement of this plugin. Required version is: " . $require_myaac . ", and you're using version " . MYAAC_VERSION . "."; self::$error = "Your AAC version doesn't meet the requirement of this plugin. Required version is: " . $require_myaac . ", and you're using version " . MYAAC_VERSION . ".";
return false; return false;
} }

View File

@@ -1,93 +0,0 @@
<?php
namespace MyAAC\Server\XML;
use MyAAC\Cache\Cache;
class Vocations
{
private static array $vocations;
private static array $vocationsFrom;
public function __construct()
{
$cached = Cache::remember('vocations', 10 * 60, function () {
$this->load();
$from = $this->getFrom();
$amount = 0;
foreach ($from as $vocId => $fromVocation) {
if ($vocId != 0 && $vocId == $fromVocation) {
$amount++;
}
}
return ['vocations' => $this->get(), 'vocationsFrom' => $from, 'amount' => $amount];
});
self::$vocations = $cached['vocations'];
self::$vocationsFrom = $cached['vocationsFrom'];
config(['vocations', self::$vocations]);
config(['vocations_amount', $cached['amount']]);
}
public function load(): void
{
if(!class_exists('DOMDocument')) {
throw new \RuntimeException('Please install PHP xml extension. MyAAC will not work without it.');
}
$vocationsXML = new \DOMDocument();
$file = config('data_path') . 'XML/vocations.xml';
if(!@file_exists($file)) {
$file = config('data_path') . 'vocations.xml';
}
if(!$vocationsXML->load($file)) {
throw new \RuntimeException('ERROR: Cannot load <i>vocations.xml</i> - the file is malformed. Check the file with xml syntax validator.');
}
foreach($vocationsXML->getElementsByTagName('vocation') as $vocation) {
$id = $vocation->getAttribute('id');
self::$vocations[$id] = $vocation->getAttribute('name');
$fromVocation = (int) $vocation->getAttribute('fromvoc');
self::$vocationsFrom[$id] = $fromVocation;
}
}
public static function get(): array {
return self::$vocations;
}
public static function getFrom(): array {
return self::$vocationsFrom;
}
public static function getPromoted(int $id): ?int {
foreach (self::$vocationsFrom as $vocId => $fromVocation) {
if ($id == $fromVocation && $vocId != $id) {
return $vocId;
}
}
return null;
}
public static function getOriginal(int $id): ?int {
return self::$vocationsFrom[$id] ?? null;
}
public static function getBase($includingRook = true): array {
$vocations = [];
foreach (self::$vocationsFrom as $vocId => $fromVoc) {
if ($vocId == $fromVoc && ($vocId != 0 || $includingRook)) {
$vocations[] = $vocId;
}
}
return $vocations;
}
}

View File

@@ -248,7 +248,7 @@ class Settings implements \ArrayAccess
echo '<div class="input-group" id="show-hide-' . $key . '">'; echo '<div class="input-group" id="show-hide-' . $key . '">';
} }
echo '<input class="form-control" type="' . $setting['type'] . '" name="settings[' . $key . ']" value="' . escapeHtml($settingsDb[$key] ?? ($setting['default'] ?? '')) . '" id="' . $key . '"' . $min . $max . $step . '/>'; echo '<input class="form-control" type="' . $setting['type'] . '" name="settings[' . $key . ']" value="' . ($settingsDb[$key] ?? ($setting['default'] ?? '')) . '" id="' . $key . '"' . $min . $max . $step . '/>';
if ($setting['type'] === 'password') { if ($setting['type'] === 'password') {
echo '<div class="input-group-append input-group-text"><a href=""><i class="fas fa-eye-slash" ></i></a></div></div>'; echo '<div class="input-group-append input-group-text"><a href=""><i class="fas fa-eye-slash" ></i></a></div></div>';
@@ -266,7 +266,7 @@ class Settings implements \ArrayAccess
if ($rows < 2) { if ($rows < 2) {
$rows = 2; // always min 2 rows for textarea $rows = 2; // always min 2 rows for textarea
} }
echo '<textarea class="form-control" rows="' . $rows . '" name="settings[' . $key . ']" id="' . $key . '">' . escapeHtml($value) . '</textarea>'; echo '<textarea class="form-control" rows="' . $rows . '" name="settings[' . $key . ']" id="' . $key . '">' . $value . '</textarea>';
} }
else if ($setting['type'] === 'options') { else if ($setting['type'] === 'options') {

View File

@@ -342,16 +342,6 @@ class Validator
} }
} }
global $hooks;
$params = ['name' => $name, 'error' => ''];
$hooks->triggerFilter(HOOK_FILTER_VALIDATE_CHARACTER_NEW_NAME, $params);
if (!empty($params['error'])) {
self::$lastError = $params['error'];
return false;
}
return true; return true;
} }

View File

@@ -28,8 +28,6 @@ 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_CHANGE_PASSWORD_AFTER_OLD_PASSWORD', ++$i);
define('HOOK_ACCOUNT_CHANGE_PASSWORD_AFTER_NEW_PASSWORD', ++$i);
define('HOOK_ACCOUNT_CHANGE_PASSWORD_POST', ++$i); define('HOOK_ACCOUNT_CHANGE_PASSWORD_POST', ++$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);
@@ -108,7 +106,6 @@ define('HOOK_FILTER_ROUTES', ++$i);
define('HOOK_FILTER_TWIG_DISPLAY', ++$i); define('HOOK_FILTER_TWIG_DISPLAY', ++$i);
define('HOOK_FILTER_TWIG_RENDER', ++$i); define('HOOK_FILTER_TWIG_RENDER', ++$i);
define('HOOK_FILTER_THEME_FOOTER', ++$i); define('HOOK_FILTER_THEME_FOOTER', ++$i);
define('HOOK_FILTER_VALIDATE_CHARACTER_NEW_NAME', ++$i);
const HOOK_FIRST = HOOK_INIT; const HOOK_FIRST = HOOK_INIT;
define('HOOK_LAST', $i); define('HOOK_LAST', $i);

View File

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

View File

@@ -9,29 +9,23 @@ Please enter your current password and a new password. For your security, please
<span>Current Password:</span> <span>Current Password:</span>
</td> </td>
<td> <td>
<input form="form" type="password" id="old_password" name="old_password" size="30" maxlength="29"> <input form="form" type="password" name="oldpassword" size="30" maxlength="29">
</td> </td>
</tr> </tr>
{{ hook('HOOK_ACCOUNT_CHANGE_PASSWORD_AFTER_OLD_PASSWORD') }}
<tr> <tr>
<td class="LabelV"> <td class="LabelV">
<span>New Password:</span> <span>New Password:</span>
</td> </td>
<td style="width:90%;"> <td style="width:90%;">
<input form="form" type="password" id="new_password" name="new_password" size="30" maxlength="29"> <input form="form" type="password" name="newpassword" size="30" maxlength="29">
</td> </td>
</tr> </tr>
{{ hook('HOOK_ACCOUNT_CHANGE_PASSWORD_AFTER_NEW_PASSWORD') }}
<tr> <tr>
<td class="LabelV"> <td class="LabelV">
<span>New Password Again:</span> <span>New Password Again:</span>
</td> </td>
<td> <td>
<input form="form" type="password" id="new_password_confirm" name="new_password_confirm" size="30" maxlength="29"> <input form="form" type="password" name="newpassword_confirm" size="30" maxlength="29">
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -1,45 +0,0 @@
Please enter your account Email address.<br/><br/>
{% set title = 'Resend Email' %}
{% set background = config('darkborder') %}
{% set content %}
<table style="width:100%;">
<tr>
<td class="LabelV" >
<span><label for="email">Email Address:</label></span>
</td>
<td style="width:90%;">
<input type="email" form="form" id="email" name="email" size="30" maxlength="50" autofocus/>
</td>
</tr>
</table>
{% endset %}
{% include 'tables.headline.html.twig' %}
<br/>
<table style="width:100%;">
<tr align="center">
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td style="border:0;">
<form id="form" action="{{ getLink('account/resend-email-verify') }}" method="post">
{{ csrf() }}
<input type="hidden" name="submit" value="1"/>
{{ include('buttons.submit.html.twig') }}
</form>
</td>
<tr>
</table>
</td>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td style="border:0;">
<form action="{{ getLink('news') }}" method="post">
{{ include('buttons.back.html.twig') }}
</form>
</td>
</tr>
</table>
</td>
</tr>
</table>

View File

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

View File

@@ -18,7 +18,7 @@
<label for="vocationFilter">Choose a vocation</label> <label for="vocationFilter">Choose a vocation</label>
<select onchange="location = this.value;" id="vocationFilter"> <select onchange="location = this.value;" id="vocationFilter">
<option value="{{ getLink('highscores') }}/{{ list|urlencode }}" class="size_xs">[ALL]</option> <option value="{{ getLink('highscores') }}/{{ list|urlencode }}" class="size_xs">[ALL]</option>
{% for i in baseVocations %} {% for i in 0..config.vocations_amount %}
<option value="{{ getLink('highscores') }}/{{ list|urlencode }}/{{ config.vocations[i]|lower|urlencode }}" class="size_xs" {% if vocationId is not null and vocationId == i %}selected{% endif %}>{{ config.vocations[i]}}</option> <option value="{{ getLink('highscores') }}/{{ list|urlencode }}/{{ config.vocations[i]|lower|urlencode }}" class="size_xs" {% if vocationId is not null and vocationId == i %}selected{% endif %}>{{ config.vocations[i]}}</option>
{% endfor %} {% endfor %}
</select> </select>
@@ -120,7 +120,7 @@
<tr bgcolor="{{ config.lightborder }}"> <tr bgcolor="{{ config.lightborder }}">
<td> <td>
<a href="{{ getLink('highscores') }}/{{ list|urlencode }}" class="size_xs">[ALL]</a><br/> <a href="{{ getLink('highscores') }}/{{ list|urlencode }}" class="size_xs">[ALL]</a><br/>
{% for i in baseVocations %} {% for i in 0..config.vocations_amount %}
<a href="{{ getLink('highscores') }}/{{ list|urlencode }}/{{ config.vocations[i]|lower|urlencode }}" class="size_xs">{{ config.vocations[i]}}</a><br/> <a href="{{ getLink('highscores') }}/{{ list|urlencode }}/{{ config.vocations[i]|lower|urlencode }}" class="size_xs">{{ config.vocations[i]}}</a><br/>
{% endfor %} {% endfor %}
</td> </td>

View File

@@ -1,7 +0,0 @@
Hello {{ account }}!<br/>
<br/>
You requested to resend the verify Email on {{ config.lua.serverName }}!<br/>
<br/>
To verify your email address please click the link below:<br/>
{{ verify_url|raw }}

View File

@@ -10,19 +10,22 @@
{% if setting('core.online_vocations_images') %} {% if setting('core.online_vocations_images') %}
<table width="200" cellspacing="1" cellpadding="0" border="0" align="center"> <table width="200" cellspacing="1" cellpadding="0" border="0" align="center">
<tr bgcolor="{{ config.darkborder }}"> <tr bgcolor="{{ config.darkborder }}">
{% for vocationId in baseVocations %} <td><img src="images/sorcerer.png" /></td>
<td><img src="images/{{ config('vocations')[vocationId]|lower }}.png" width="150" height="200"/></td> <td><img src="images/druid.png" /></td>
{% endfor %} <td><img src="images/paladin.png" /></td>
<td><img src="images/knight.png" /></td>
</tr> </tr>
<tr bgcolor="{{ config.vdarkborder }}"> <tr bgcolor="{{ config.vdarkborder }}">
{% for vocationId in baseVocations %} <td class="white" style="text-align: center;"><strong>Sorcerers</strong></td>
<td class="white" style="text-align: center;"><strong>{{ config('vocations')[vocationId] }}s</strong></td> <td class="white" style="text-align: center;"><strong>Druids</strong></td>
{% endfor %} <td class="white" style="text-align: center;"><strong>Paladins</strong></td>
<td class="white" style="text-align: center;"><strong>Knights</strong></td>
</tr> </tr>
<tr bgcolor="{{ config.lightborder }}"> <tr bgcolor="{{ config.lightborder }}">
{% for vocationId in baseVocations %} <td style="text-align: center;">{{ vocs[1] }}</td>
<td style="text-align: center;">{{ vocs[vocationId] }}</td> <td style="text-align: center;">{{ vocs[2] }}</td>
{% endfor %} <td style="text-align: center;">{{ vocs[3] }}</td>
<td style="text-align: center;">{{ vocs[4] }}</td>
</tr> </tr>
</table> </table>
<div style="text-align: center;">&nbsp;</div> <div style="text-align: center;">&nbsp;</div>
@@ -32,14 +35,11 @@
<td class="white" colspan="2"><b>Vocation statistics</b></td> <td class="white" colspan="2"><b>Vocation statistics</b></td>
</tr> </tr>
{% set i = 0 %} {% for i in 1..config.vocations_amount %}
{% for vocationId in baseVocations %}
<tr bgcolor="{{ getStyle(i) }}"> <tr bgcolor="{{ getStyle(i) }}">
<td width="25%">{{ config.vocations[vocationId] }}</td> <td width="25%">{{ config.vocations[i] }}</td>
<td width="75%">{{ vocs[vocationId] }}</td> <td width="75%">{{ vocs[i] }}</td>
</tr> </tr>
{% set i = i + 1 %}
{% endfor %} {% endfor %}
</table> </table>
<br/> <br/>
@@ -101,7 +101,7 @@
<tr> <tr>
<td class="LabelV150"><b>Location Datacenter:</b></td> <td class="LabelV150"><b>Location Datacenter:</b></td>
<td>{{ setting('core.online_datacenter')|raw }} <small>(Server date & time: - {{ "now"|date("d/m/Y H:i:s") }})</small></td> <td>{{ setting('core.online_datacenter') }} <small>(Server date & time: - {{ "now"|date("d/m/Y H:i:s") }})</small></td>
</tr> </tr>
<tr> <tr>
<td class="LabelV150"><b>PvP Type:</b></td> <td class="LabelV150"><b>PvP Type:</b></td>

View File

@@ -101,9 +101,7 @@ $twig->addFunction($function);
$function = new TwigFunction('hook', function ($context, $hook, array $params = []) { $function = new TwigFunction('hook', function ($context, $hook, array $params = []) {
global $hooks; global $hooks;
if (config('hooks_debug')) { //note($hook);
note($hook);
}
if(is_string($hook)) { if(is_string($hook)) {
if (defined($hook)) { if (defined($hook)) {

View File

@@ -27,7 +27,14 @@ if(isset($config['boxes']))
var loginStatus="<?php echo ($logged ? 'true' : 'false'); ?>"; var loginStatus="<?php echo ($logged ? 'true' : 'false'); ?>";
<?php <?php
if(PAGE !== 'news') { if(PAGE !== 'news') {
$tmp = str_replace('/', '_', isset($_REQUEST['subtopic']) ? escapeHtml($_REQUEST['subtopic']) : PAGE); if(isset($_REQUEST['subtopic'])) {
$tmp = escapeHtml($_REQUEST['subtopic']);
if($tmp === 'accountmanagement') {
$tmp = 'accountmanage';
}
}
else {
$tmp = str_replace('/', '_', PAGE);
$exp = explode('/', PAGE); $exp = explode('/', PAGE);
if(PAGE !== 'account/create' && PAGE !== 'account/lost' && isset($exp[1])) { if(PAGE !== 'account/create' && PAGE !== 'account/lost' && isset($exp[1])) {
if ($exp[0] === 'account' && $exp[1] === 'lost') { if ($exp[0] === 'account' && $exp[1] === 'lost') {
@@ -42,6 +49,7 @@ if(isset($config['boxes']))
} }
} }
} }
}
else { else {
$tmp = 'news'; $tmp = 'news';
} }

View File

@@ -9,8 +9,6 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
const IGNORE_SET_LAST_VISIT = true;
// we need some functions // we need some functions
require '../common.php'; require '../common.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';

View File

@@ -53,9 +53,6 @@
exit; exit;
} }
ensureFolderExists(SIGNATURES_CACHE);
ensureIndexExists(SIGNATURES_CACHE);
$cached = SIGNATURES_CACHE.$player->getId() . '.png'; $cached = SIGNATURES_CACHE.$player->getId() . '.png';
if(file_exists($cached) && (time() < (filemtime($cached) + (60 * setting('core.signature_cache_time'))))) if(file_exists($cached) && (time() < (filemtime($cached) + (60 * setting('core.signature_cache_time')))))
{ {

View File

@@ -1,7 +1,4 @@
<?php <?php
const IGNORE_SET_LAST_VISIT = true;
require '../common.php'; require '../common.php';
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';

View File

@@ -12,8 +12,6 @@
use MyAAC\CreateCharacter; use MyAAC\CreateCharacter;
use MyAAC\Models\Account; use MyAAC\Models\Account;
const IGNORE_SET_LAST_VISIT = true;
// we need some functions // we need some functions
require '../common.php'; require '../common.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';