Compare commits

...

56 Commits

Author SHA1 Message Date
slawkens
bb830bce44 Release v1.7 2025-06-22 08:55:29 +02:00
slawkens
566c2a9151 Move out of $cache->enabled 2025-06-22 08:48:24 +02:00
slawkens
0f48f12e2e Update admin.plugins.outdated.html.twig 2025-06-19 18:53:11 +02:00
Slawomir Boczek
0ea247ce7e Feature/plugins versions check (#310)
* Check plugins versions from plugins.my-aac.org/api

* Improve plugin update check messaging

Updated the success message when checking for plugin updates to clarify the source. Added an informational message when outdated plugins are found to improve user feedback.

* Use configurable API URI for plugin updates

Replaces hardcoded plugin API URI with a configurable value from config, defaulting to the official API. Also fixes a typo in the success message.
2025-06-19 16:46:22 +02:00
slawkens
b329da52aa Use apcu_clear_cache 2025-06-17 17:52:23 +02:00
slawkens
c720ccc451 Add missing csrf() 2025-06-15 19:35:12 +02:00
slawkens
8dc42b6544 Nothing important: just formatting 2025-06-15 19:05:47 +02:00
slawkens
dca904e61d Add missing csrf() 2025-06-15 19:05:19 +02:00
slawkens
29faa4f695 Add missing csrf() in success.html.twig 2025-06-15 19:03:03 +02:00
slawkens
4767120043 Update online.html.twig 2025-06-14 21:19:52 +02:00
slawkens
9a90e4aae2 Revamped online page 2025-06-14 21:12:47 +02:00
slawkens
ba4ed6a04b Add LabelV120, LabelV150, LabelV200 2025-06-14 20:52:38 +02:00
slawkens
a7efacdbac Delete online.form, use revamped characters.form 2025-06-14 20:50:54 +02:00
Goosey
577037becc fix: boostedcreatures for 13.40 (#307)
* boostedcreatures fix for 13.40

Fixes the boosted boss/creature display on the login page for 13.40 running the default cipsoft client.

* Adjust version

---------

Co-authored-by: slawkens <slawkens@gmail.com>
2025-06-14 15:58:08 +02:00
slawkens
b8abc11b96 Update list.php 2025-06-14 11:33:47 +02:00
slawkens
4def6a6cae Style 2025-06-14 10:39:45 +02:00
slawkens
e6100a1b72 New hook: HOOK_GUILDS_AFTER_MANAGE_BUTTON 2025-06-14 10:36:38 +02:00
slawkens
522f6c11d8 Add OTS_Player->isNameLocked() 2025-06-14 08:26:43 +02:00
slawkens
00c3635c5f Add $config['site']['serverPath'] for better compatibility with Gesior 2025-06-14 00:59:10 +02:00
slawkens
c074a48f24 New hook: HOOK_ACCOUNT_MANAGE_AFTER_CHARACTERS 2025-06-14 00:44:00 +02:00
slawkens
e222957893 OTS_Toolbox::getVocationName($id, $promotion); 2025-06-13 22:25:36 +02:00
slawkens
d423ddd07a Nothing important: convert to tabs 2025-06-13 22:14:20 +02:00
slawkens
4d4f7759d3 Update visitors.php 2025-06-13 21:31:04 +02:00
slawkens
9510640ba9 Ignore empty values 2025-06-13 21:25:13 +02:00
slawkens
98b13c91a4 Update notice about how to enable Visitors Counter 2025-06-13 21:24:52 +02:00
slawkens
0c95bcfd06 Better $title inventing 2025-06-13 21:03:09 +02:00
slawkens
524e982a0e Release v1.6.1 2025-06-11 05:51:39 +02:00
slawkens
fffb427eae Update account.generate_recovery_key.html.twig 2025-06-09 21:18:45 +02:00
slawkens
10cd71a663 Add missing csrf() into account manage actions 2025-06-09 21:18:42 +02:00
slawkens
0812fe025d Update settings_save.php 2025-06-09 21:14:44 +02:00
slawkens
309c1fb715 Remove deprecated TinyMCE plugin - template 2025-06-09 14:24:36 +02:00
slawkens
8d29fdb98b Set TinyMCE license key to gpl (Avoid warning message in browser console) 2025-06-09 14:24:22 +02:00
slawkens
f782850307 Move counter & visitors code before router
In case someone wants to include that info on page
2025-06-06 22:10:13 +02:00
slawkens
835dda9659 Remove duplicated code - account redirect, already in account/manage 2025-06-05 19:08:53 +02:00
slawkens
dcc703b1eb Remove optional param, make it required for few routes 2025-06-05 18:11:44 +02:00
slawkens
9d8e9d27bd Ignore duplicated route exception 2025-06-05 18:11:31 +02:00
slawkens
db09980de1 Start v1.6.1-dev 2025-06-03 22:57:33 +02:00
slawkens
2dba778167 Update example.json 2025-06-03 18:38:02 +02:00
slawkens
ce2af2bb7a Update CHANGELOG-1.x.md 2025-06-03 17:33:17 +02:00
slawkens
dc839abfbb Release v1.6 2025-06-03 16:59:55 +02:00
slawkens
01d49692ed Update CHANGELOG-1.x.md 2025-06-03 16:59:20 +02:00
slawkens
de6603a513 Allow [] in character name (again), example: [God] Test 2025-06-03 16:49:45 +02:00
slawkens
dd731fd49b Revert previous commit partially 2025-06-03 16:43:43 +02:00
slawkens
064b929841 Allow [] in character name (for :string) 2025-06-03 16:39:02 +02:00
slawkens
c61747dc75 Update coins.html.twig 2025-06-03 10:17:08 +02:00
slawkens
207d6bc691 feat: AutoLoad plugins init.php, by default disabled 2025-06-03 08:52:33 +02:00
slawkens
8fdea94376 Add globals into $hooks->executeFIlter 2025-06-03 08:39:48 +02:00
slawkens
c961a1ebf8 Two new hooks for pages loaded from database (custom pages)
HOOK_BEFORE_PAGE_CUSTOM,
HOOK_AFTER_PAGE_CUSTOM
2025-06-03 06:21:44 +02:00
slawkens
770ffcfc52 Fix warnings in CLI (part 2) 2025-05-29 16:10:46 +02:00
slawkens
756d94bb3e Fix warning from CLI 2025-05-29 16:08:23 +02:00
slawkens
6e0f591383 Do not allow access to tools/ folder after install 2025-05-29 12:22:16 +02:00
slawkens
fb91281140 Fix phpstan workflow 2025-05-29 09:35:20 +02:00
slawkens
d8a6090be3 Add new setting/configurable: site_url, prevents domain spoofing 2025-05-29 09:27:29 +02:00
slawkens
52109f5cca Another solution 2025-05-28 14:13:04 +02:00
slawkens
4b7b121550 Try fix workflow 2025-05-28 14:08:50 +02:00
slawkens
28886551e8 feat: Add new account coins setting 2025-05-28 13:33:36 +02:00
55 changed files with 1279 additions and 364 deletions

View File

@@ -1,5 +1,55 @@
# Changelog
## [1.7 - 22.06.2025]
### Added
* Feature: plugins versions check (#310)
* New hooks: HOOK_ACCOUNT_MANAGE_AFTER_CHARACTERS, HOOK_GUILDS_AFTER_MANAGE_BUTTON (https://github.com/slawkens/myaac/commit/c074a48f245df55646b6705737f667b6a84149b2, https://github.com/slawkens/myaac/commit/e6100a1b72de8695bba1dae9ba4e28bfdce47b10)
* Add OTS_Toolbox::getVocationName(id, promotion) + OTS_Player->isNameLocked() (https://github.com/slawkens/myaac/commit/e222957893c4a1de0dc8dbba55bce1a43418d275, https://github.com/slawkens/myaac/commit/522f6c11d835afd36fd07a07074d96d7e219b488)
* Add missing csrf in more places, causing white page with error about Request (https://github.com/slawkens/myaac/commit/dca904e61d21d856bf809070e7652803a2df0f58, https://github.com/slawkens/myaac/commit/c720ccc451ff90ef40b2a1595468d061ffd7e1e4)
### Changed
* Revamped online page (https://github.com/slawkens/myaac/commit/9a90e4aae280e607430511c6727d9a714b11f4c5, https://github.com/slawkens/myaac/commit/4767120043b09141870383e249f3729638d53dc2)
* Better $title inventing (https://github.com/slawkens/myaac/commit/0c95bcfd06b68b21512e477646ef7bd3a0d4912b)
### Fixed
* Use apcu cache clear (https://github.com/slawkens/myaac/commit/b329da52aae9d0e21120a6444d3caf442420ce50, https://github.com/slawkens/myaac/commit/566c2a9151ab6392286f74e26853faa19a1b4f24)
* fix: boostedcreatures for 13.40 (by @GooseWithAKnife) (#307)
## [1.6.1 - 11.06.2025]
### Fixed
* Fixed "Request has been cancelled due to security reasons", cause of missing csrf() in twig files (https://github.com/slawkens/myaac/commit/10cd71a6630ffec91b43a26a6d685b66c5836a6a)
* Fix: Ignore duplicated route exception (https://github.com/slawkens/myaac/commit/9d8e9d27bd87167d8d4005942a6af62bfe4c0892)
### Changed
* Move counter & visitors code before router (In case someone wants to include that info on page) (https://github.com/slawkens/myaac/commit/f78285030708ad3c74ab048711f73bbf3ee5281e)
* Set TinyMCE license key to gpl (Avoid warning message in browser console) (https://github.com/slawkens/myaac/commit/8d29fdb98b92dbc3d2853ef88a185c67036b4a77)
### Removed
* Remove deprecated TinyMCE plugin - template (https://github.com/slawkens/myaac/commit/309c1fb715b882e67cb673b1544a03befbf64a22)
## [1.6 - 03.06.2025]
### Added
* Add new setting/configurable: site_url, prevents domain spoofing (https://github.com/slawkens/myaac/commit/d8a6090be382c35c19117cfef964b594ed02b8d4)
* Add new account coins setting (https://github.com/slawkens/myaac/commit/28886551e86fe562172c4c7f2afb89a2e7672c2e)
* autoload: settings/install/init.php (https://github.com/slawkens/myaac/commit/e5749437074c3b3556628a2aeb5bad2edf97bde0, https://github.com/slawkens/myaac/commit/7d213f479a7e40c6254069b5fc4e578dc32bf8d9, https://github.com/slawkens/myaac/commit/207d6bc69120aba1af2b51808f17e0059b571fed)
* Protect against csrf in more places (accounts & guilds & forums pages) (https://github.com/slawkens/myaac/commit/6eda38603c8ed7e99b92a78a4600b1245377f74d, https://github.com/slawkens/myaac/commit/e776bd52beb3064a9e694efd1b9021ec972ee2f6, https://github.com/slawkens/myaac/commit/84d502bf105f2a789481fba1acc820d236b4de66)
* Added two new hooks for pages loaded from database (custom pages): HOOK_BEFORE_PAGE_CUSTOM, HOOK_AFTER_PAGE_CUSTOM (https://github.com/slawkens/myaac/commit/c961a1ebf837f2ab1734a825ff2c57b4937610c9)
* Add global variables into $hooks->executeFilter (https://github.com/slawkens/myaac/commit/8fdea943768b20193eede99d60313ee84511a0be)
* Add getNPCsCount() to OTS_InfoRespond (https://github.com/slawkens/myaac/commit/7d435ff6433ef1fb2295ee79ed043ee10dc725e9)
### Fixed
* Allow [] in character name (https://github.com/slawkens/myaac/commit/de6603a51347b9e656c58637ed9971fffdd7cedd)
* Do not allow access to tools/ folder after install (https://github.com/slawkens/myaac/commit/6e0f5913831f8dba69fd2d1505be3e2a303c6324)
* Fix CHANGELOG-1.x.md loading in admin panel (https://github.com/slawkens/myaac/commit/4a30fb495dbfbe1d434e8d52419eaf44fe517aee)
* Fix links not working in admin dashboard modules (https://github.com/slawkens/myaac/commit/be7b27c31aa3bbd6c0289c34d1e61139a3fe015c)
* Fix twig variables: logged + account_logged being not set directly after login (https://github.com/slawkens/myaac/commit/1e9b10d6489c488cadf7f6ed17b42f1ea6c767a8)
### Changed
* OTS_ServerInfo -> move setTimeout out of class - Possibility to use the class without MyAAC (https://github.com/slawkens/myaac/commit/40d65a6613149fda51bdceb82c807e5301a3388b)
## [1.5 - 14.05.2025]
### Added

View File

@@ -19,7 +19,7 @@
{% set i = i + 1 %}
<tr>
<th>{{ i }}</th>
<td><a href="?p=accounts&id={{ result.id }}">{{ result.name }}</a></td>
<td><a href="?p=accounts&id={{ result.id }}">{{ result.name ?? result.id }}</a></td>
<td>{{ result.coins }}</td>
</tr>
{% endfor %}

View File

@@ -51,6 +51,56 @@ else {
} else {
error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError());
}
}
else if (isset($_GET['check-updates'])) {
$repoUri = $config['admin_plugins_api_uri'] ?? 'https://plugins.my-aac.org/api/';
success("Fetching latest info from $repoUri..");
$adminPlugins = new \MyAAC\Admin\Plugins();
$adminPlugins->setApiBaseUri($repoUri);
try {
$plugins = $adminPlugins->getLatestVersions();
}
catch (Exception $e) {
error($e->getMessage());
}
if (isset($plugins) && count($plugins) > 0) {
$outdated = [];
foreach (get_plugins(true) as $plugin) {
$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json');
$plugin_info = json_decode($string, true);
if (!$plugin_info) {
continue;
}
$disabled = (str_contains($plugin, 'disabled.'));
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
$info = $plugins[$pluginOriginal] ?? false;
if ($info && version_compare($info['version'], $plugin_info['version'], '>')) {
$outdated[] = [
'name' => $pluginOriginal,
'yourVersion' => $plugin_info['version'],
'latestVersion' => $info['version'],
'link' => $info['link'] ?? 'Unknown',
'download_link' => $info['download_link'] ?? 'Unknown',
];
}
}
if (count($outdated) > 0) {
info('Following updates have been found for your plugins:');
$twig->display('admin.plugins.outdated.html.twig', ['plugins' => $outdated]);
}
else {
success('All plugins up to date!');
}
}
} else if (isset($_FILES['plugin']['name'])) {
$file = $_FILES['plugin'];
$filename = $file['name'];

View File

@@ -19,8 +19,7 @@ $use_datatable = true;
if (!setting('core.visitors_counter')): ?>
Visitors counter is disabled.<br/>
You can enable it by editing this configurable in <b>config.local.php</b> file:<br/>
<p style="margin-left: 3em;"><b>$config['visitors_counter'] = true;</b></p>
You can enable it in Settings -> General -> Visitors Counter.<br/>
<?php
return;
endif;
@@ -46,7 +45,7 @@ foreach ($tmp as &$visitor) {
if ($dd->isBot()) {
$bot = $dd->getBot();
$message = '(Bot) %s, <a href="%s" target="_blank">%s</a>';
$browser = sprintf($message, $bot['category'], $bot['url'], $bot['name']);
$browser = sprintf($message, $bot['category'] ?? 'Unknown', $bot['url'] ?? '', $bot['name'] ?? 'Unknown name');
}
else {
$osFamily = OperatingSystem::getOsFamily($dd->getOs('name'));

View File

@@ -1,6 +1,5 @@
<?php
use MyAAC\Hooks;
use MyAAC\Settings;
const MYAAC_ADMIN = true;

View File

@@ -26,7 +26,7 @@
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
const MYAAC = true;
const MYAAC_VERSION = '1.5.1-dev';
const MYAAC_VERSION = '1.7';
const DATABASE_VERSION = 45;
const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true));
@@ -122,38 +122,30 @@ if (!IS_CLI) {
session_start();
}
// basedir
$basedir = '';
$tmp = explode('/', $_SERVER['SCRIPT_NAME']);
$size = count($tmp) - 1;
for($i = 1; $i < $size; $i++)
$basedir .= '/' . $tmp[$i];
$basedir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $basedir);
define('BASE_DIR', $basedir);
if(!IS_CLI) {
if (isset($_SERVER['HTTP_HOST'][0])) {
$baseHost = $_SERVER['HTTP_HOST'];
} else {
if (isset($_SERVER['SERVER_NAME'][0])) {
$baseHost = $_SERVER['SERVER_NAME'];
} else {
$baseHost = $_SERVER['SERVER_ADDR'];
}
}
define('SERVER_URL', 'http' . (isHttps() ? 's' : '') . '://' . $baseHost);
define('BASE_URL', SERVER_URL . BASE_DIR . '/');
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/');
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
}
if (file_exists(BASE . 'config.local.php')) {
require BASE . 'config.local.php';
}
require SYSTEM . 'base.php';
define('BASE_DIR', $baseDir);
if(!IS_CLI) {
if (isset($config['site_url'])) {
$hasSlashAtEnd = ($config['site_url'][strlen($config['site_url']) - 1] == '/');
define('SERVER_URL', $config['site_url']);
define('BASE_URL', SERVER_URL . ($hasSlashAtEnd ? '' : '/'));
define('ADMIN_URL', SERVER_URL . ($hasSlashAtEnd ? '' : '/') . ADMIN_PANEL_FOLDER . '/');
}
else {
define('SERVER_URL', 'http' . (isHttps() ? 's' : '') . '://' . $baseHost);
define('BASE_URL', SERVER_URL . BASE_DIR . '/');
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/');
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
}
}
/** @var array $config */
ini_set('log_errors', 1);
if(@$config['env'] === 'dev' || defined('MYAAC_INSTALL')) {

View File

@@ -18,7 +18,8 @@
"symfony/string": "^6.4",
"symfony/var-dumper": "^6.4",
"filp/whoops": "^2.15",
"maximebf/debugbar": "1.*"
"maximebf/debugbar": "1.*",
"guzzlehttp/guzzle": "7.9.3"
},
"require-dev": {
"phpstan/phpstan": "^1.10"

537
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "be4d1489a53a9cd8eec6bcaa7a096f30",
"content-hash": "5317e97a5025ebc2a977214bd3fa964c",
"packages": [
{
"name": "brick/math",
@@ -493,6 +493,331 @@
],
"time": "2024-09-25T12:00:00+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "7.9.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
"reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
"guzzlehttp/psr7": "^2.7.0",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"provide": {
"psr/http-client-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*",
"guzzle/client-integration-tests": "3.0.2",
"php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.39 || ^9.6.20",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"suggest": {
"ext-curl": "Required for CURL handler support",
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Jeremy Lindblom",
"email": "jeremeamia@gmail.com",
"homepage": "https://github.com/jeremeamia"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
}
],
"description": "Guzzle is a PHP HTTP client library",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"psr-18",
"psr-7",
"rest",
"web service"
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.9.3"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
"type": "tidelift"
}
],
"time": "2025-03-27T13:37:11+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c",
"reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/2.2.0"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
"type": "tidelift"
}
],
"time": "2025-03-27T13:27:01+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "2.7.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16",
"reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.1 || ^2.0",
"ralouphie/getallheaders": "^3.0"
},
"provide": {
"psr/http-factory-implementation": "1.0",
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "0.9.0",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://sagikazarmark.hu"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
"uri",
"url"
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.7.1"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
"type": "tidelift"
}
],
"time": "2025-03-27T12:30:47+00:00"
},
{
"name": "illuminate/collections",
"version": "v10.48.25",
@@ -1472,6 +1797,166 @@
},
"time": "2021-11-05T16:47:00+00:00"
},
{
"name": "psr/http-client",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-client.git",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP clients",
"homepage": "https://github.com/php-fig/http-client",
"keywords": [
"http",
"http-client",
"psr",
"psr-18"
],
"support": {
"source": "https://github.com/php-fig/http-client"
},
"time": "2023-09-23T14:17:50+00:00"
},
{
"name": "psr/http-factory",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-factory.git",
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"shasum": ""
},
"require": {
"php": ">=7.1",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
"keywords": [
"factory",
"http",
"message",
"psr",
"psr-17",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-factory"
},
"time": "2024-04-15T12:06:14+00:00"
},
{
"name": "psr/http-message",
"version": "2.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/2.0"
},
"time": "2023-04-04T09:54:51+00:00"
},
{
"name": "psr/log",
"version": "3.0.2",
@@ -1573,6 +2058,50 @@
},
"time": "2021-10-29T13:26:27+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"support": {
"issues": "https://github.com/ralouphie/getallheaders/issues",
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
},
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "symfony/console",
"version": "v6.4.17",
@@ -2910,7 +3439,7 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
@@ -2921,6 +3450,6 @@
"ext-xml": "*",
"ext-dom": "*"
},
"platform-dev": [],
"plugin-api-version": "2.3.0"
"platform-dev": {},
"plugin-api-version": "2.6.0"
}

BIN
images/order_asc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 B

BIN
images/order_desc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 B

View File

@@ -93,6 +93,7 @@ if(setting('core.backward_support')) {
if($logged && $account_logged)
$group_id_of_acc_logged = $account_logged->getGroupId();
$config['serverPath'] = $config['server_path'];
$config['site'] = &$config;
$config['server'] = &$config['lua'];
$config['site']['shop_system'] = setting('core.gifts_system');
@@ -117,6 +118,14 @@ if(setting('core.backward_support')) {
$config['status']['serverStatus_' . $key] = $value;
}
if(setting('core.views_counter')) {
require_once SYSTEM . 'counter.php';
}
if(setting('core.visitors_counter')) {
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
}
require_once SYSTEM . 'router.php';
// anonymous usage statistics
@@ -153,13 +162,6 @@ if(setting('core.anonymous_usage_statistics')) {
}
}
if(setting('core.views_counter'))
require_once SYSTEM . 'counter.php';
if(setting('core.visitors_counter')) {
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
}
/**
* @var OTS_Account $account_logged
*/

View File

@@ -10,6 +10,14 @@ foreach($config['clients'] as $client) {
$clients[$client] = $client_version;
}
if (empty($_SESSION['var_site_url'])) {
//require SYSTEM . 'base.php';
$serverUrl = 'http' . (isHttps() ? 's' : '') . '://' . $baseHost;
$siteURL = $serverUrl . $baseDir;
$_SESSION['var_site_url'] = $siteURL;
}
$twig->display('install.config.html.twig', array(
'clients' => $clients,
'timezones' => DateTimeZone::listIdentifiers(),

View File

@@ -195,13 +195,4 @@ if(!isset($_SESSION['installed'])) {
$_SESSION['installed'] = true;
}
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') !== false)
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
$hooks->trigger(HOOK_INSTALL_FINISH_END);

View File

@@ -7,6 +7,11 @@ require SYSTEM . 'functions.php';
require BASE . 'install/includes/functions.php';
require BASE . 'install/includes/locale.php';
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
return;
}
$error = false;
require BASE . 'install/includes/config.php';

View File

@@ -17,11 +17,11 @@ ini_set('max_execution_time', 300);
ob_implicit_flush();
header('X-Accel-Buffering: no');
/*
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
return;
}*/
}
require SYSTEM . 'init.php';
@@ -94,6 +94,17 @@ $hooks->trigger(HOOK_INSTALL_FINISH);
$db->setClearCacheAfter(true);
// cleanup
foreach($_SESSION as $key => $value) {
if(str_contains($key, 'var_')) {
unset($_SESSION[$key]);
}
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
$locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(str_replace('tools/', '', BASE_URL), $locale['step_finish_homepage'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$LINK$', generateLink('https://my-aac.org', 'https://my-aac.org', true), $locale['step_finish_desc']);

View File

@@ -88,8 +88,8 @@ switch ($action) {
case 'boostedcreature':
$clientVersion = (int)setting('core.client');
// 14.00 and up
if ($clientVersion >= 1400) {
// 13.40 and up
if ($clientVersion >= 1340) {
$creatureBoost = $db->query("SELECT * FROM " . $db->tableName('boosted_creature'))->fetchAll();
$bossBoost = $db->query("SELECT * FROM " . $db->tableName('boosted_boss'))->fetchAll();
die(json_encode([

View File

@@ -51,5 +51,8 @@
"themes": true,
"admin-pages": true,
"admin-pages-sub-folders": true,
"settings": true,
"install": true,
"init": false
}
}

21
system/base.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
$baseDir = '';
$tmp = explode('/', $_SERVER['SCRIPT_NAME']);
$size = count($tmp) - 1;
for($i = 1; $i < $size; $i++)
$baseDir .= '/' . $tmp[$i];
$baseDir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $baseDir);
if(!IS_CLI) {
if (isset($_SERVER['HTTP_HOST'][0])) {
$baseHost = $_SERVER['HTTP_HOST'];
} else {
if (isset($_SERVER['SERVER_NAME'][0])) {
$baseHost = $_SERVER['SERVER_NAME'];
} else {
$baseHost = $_SERVER['SERVER_ADDR'];
}
}
}

View File

@@ -1265,6 +1265,10 @@ function clearCache()
$db->setClearCacheAfter(true);
}
if (function_exists('apcu_clear_cache')) {
apcu_clear_cache();
}
deleteDirectory(CACHE . 'signatures', ['index.html'], true);
deleteDirectory(CACHE . 'twig', ['index.html'], true);
deleteDirectory(CACHE . 'plugins', ['index.html'], true);

View File

@@ -12,6 +12,7 @@ use DebugBar\StandardDebugBar;
use MyAAC\Cache\Cache;
use MyAAC\CsrfToken;
use MyAAC\Hooks;
use MyAAC\Plugins;
use MyAAC\Models\Town;
use MyAAC\Settings;
@@ -46,6 +47,11 @@ if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HT
global $cache;
$cache = Cache::getInstance();
// load plugins init.php
foreach (Plugins::getInits() as $init) {
require $init;
}
// event system
global $hooks;
$hooks = new Hooks();

View File

@@ -2919,6 +2919,32 @@ class OTS_Player extends OTS_Row_DAO
$this->data['banned'] = $ban['active'];
$this->data['banned_time'] = $ban['expires'];
}
public function isNameLocked(): bool
{
// nothing can't be banned
if( !$this->isLoaded() ) {
throw new E_OTS_NotLoaded();
}
if($this->db->hasTable('player_namelocks')) {
$ban = $this->db->query('SELECT 1 FROM `player_namelocks` WHERE `player_id` = ' . $this->data['id'])->fetch(PDO::FETCH_ASSOC);
return (isset($ban['1']));
}
else if($this->db->hasTable('bans')) {
if($this->db->hasColumn('bans', 'active')) {
$ban = $this->db->query('SELECT `active`, `expires` FROM `bans` WHERE `type` = 2 AND `active` = 1 AND `value` = ' . $this->data['id'] . ' AND (`expires` > ' . time() .' OR `expires` = -1) ORDER BY `expires` DESC')->fetch();
return isset($ban['active']);
}
else { // tfs 0.2
$ban = $this->db->query('SELECT `time` FROM `bans` WHERE `type` = 2 AND `account` = ' . $this->data['account_id'] . ' AND (`time` > ' . time() .' OR `time` = -1) ORDER BY `time` DESC')->fetch();
return isset($ban['time']) && ($ban['time'] == -1 || $ban['time'] > 0);
}
}
return false;
}
/**
* Deletes player.
*
@@ -2953,21 +2979,14 @@ class OTS_Player extends OTS_Row_DAO
* @return string Player proffesion name.
* @throws E_OTS_NotLoaded If player is not loaded or global vocations list is not loaded.
*/
public function getVocationName()
public function getVocationName(): string
{
if( !isset($this->data['vocation']) )
{
throw new E_OTS_NotLoaded();
}
global $config;
$voc = $this->getVocation();
if(!isset($config['vocations'][$voc])) {
return 'Unknown';
}
return $config['vocations'][$voc];
//return POT::getInstance()->getVocationsList()->getVocationName($this->data['vocation']);
return OTS_Toolbox::getVocationName($this->data['vocation'], $this->data['promotion'] ?? 0);
}
/**

View File

@@ -15,7 +15,7 @@
/**
* Toolbox for common operations.
*
*
* @package POT
* @version 0.1.5
*/
@@ -23,41 +23,41 @@ class OTS_Toolbox
{
/**
* Calculates experience points needed for given level.
*
*
* @param int $level Level for which experience should be calculated.
* @param int $experience Current experience points.
* @return int Experience points for level.
*/
public static function experienceForLevel($level, $experience = 0)
{
//return 50 * ($level - 1) * ($level * $level - 5 * $level + 12) / 3 - $experience;
{
//return 50 * ($level - 1) * ($level * $level - 5 * $level + 12) / 3 - $experience;
$level = $level - 1;
return ((50 * $level * $level * $level) - (150 * $level * $level) + (400 * $level)) / 3;
}
}
/**
* Finds out which level user have basing on his/her experience.
*
*
* <p>
* PHP doesn't support complex numbers natively so solving third-level polynomials would be quite hard. Rather then doing this, this method iterates calculating experience for next levels until it finds one which requires enought experience we have. Because of that, for high experience values this function can take relatively long time to be executed.
* </p>
*
*
* @param int $experience Current experience points.
* @return int Experience level.
*/
public static function levelForExperience($experience)
{
// default level
$level = 1;
public static function levelForExperience($experience)
{
// default level
$level = 1;
// until we will find level which requires more experience then we have we will step to next
while( self::experienceForLevel($level + 1) <= $experience)
{
$level++;
}
// until we will find level which requires more experience then we have we will step to next
while( self::experienceForLevel($level + 1) <= $experience)
{
$level++;
}
return $level;
}
return $level;
}
/**
* @version 0.1.5
@@ -65,25 +65,25 @@ class OTS_Toolbox
* @return OTS_Players_List Filtered list.
* @deprecated 0.1.5 Use OTS_PlayerBans_List.
*/
public static function bannedPlayers()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_PLAYER);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'players') );
public static function bannedPlayers()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_PLAYER);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'players') );
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// creates list and aplies filter
$list = new OTS_Players_List();
$list->setFilter($filter);
return $list;
}
// creates list and aplies filter
$list = new OTS_Players_List();
$list->setFilter($filter);
return $list;
}
/**
* @version 0.1.5
@@ -91,25 +91,34 @@ class OTS_Toolbox
* @return OTS_Accounts_List Filtered list.
* @deprecated 0.1.5 Use OTS_AccountBans_List.
*/
public static function bannedAccounts()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_ACCOUNT);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'accounts') );
public static function bannedAccounts()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_ACCOUNT);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'accounts') );
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// creates list and aplies filter
$list = new OTS_Accounts_List();
$list->setFilter($filter);
return $list;
}
// creates list and aplies filter
$list = new OTS_Accounts_List();
$list->setFilter($filter);
return $list;
}
public static function getVocationName($id, $promotion = 0): string
{
if($promotion > 0) {
$id = ($id + ($promotion * config('vocations_amount')));
}
return config('vocations')[$id] ?? 'Unknown';
}
}
/**#@-*/

View File

@@ -48,6 +48,8 @@ $locale['step_config'] = 'Konfiguration';
$locale['step_config_title'] = 'Grundkonfiguration';
$locale['step_config_server_path'] = 'Serverpfad';
$locale['step_config_server_path_desc'] = 'Pfad zu Ihrem TFS-Hauptverzeichnis, in dem sich die config.lua befinden.';
$locale['step_config_site_url'] = 'Website URL';
$locale['step_config_site_url_desc'] = 'Ihre Website-Adresse.';
$locale['step_config_mail_admin'] = 'Admin E-Mail';
$locale['step_config_mail_admin_desc'] = 'Adresse, an die E-Mails aus dem Kontaktformular gesendet werden, z. B. admin@gmail.com';
$locale['step_config_mail_admin_error'] = 'Admin E-Mail ist nicht korrekt.';

View File

@@ -52,6 +52,8 @@ $locale['step_config'] = 'Configuration';
$locale['step_config_title'] = 'Basic configuration';
$locale['step_config_server_path'] = 'Server path';
$locale['step_config_server_path_desc'] = 'Path to your TFS main directory, where you have config.lua located.';
$locale['step_config_site_url'] = 'Website URL';
$locale['step_config_site_url_desc'] = 'Your website address.';
$locale['step_config_mail_admin'] = 'Admin Email';
$locale['step_config_mail_admin_desc'] = 'Address where emails from contact form will be delivered, for example admin@gmail.com';
$locale['step_config_mail_admin_error'] = 'Admin Email is not correct.';

View File

@@ -52,6 +52,8 @@ $locale['step_config'] = 'Konfiguracja';
$locale['step_config_title'] = 'Podstawowa konfiguracja';
$locale['step_config_server_path'] = 'Ścieżka do serwera';
$locale['step_config_server_path_desc'] = 'Ścieżka do Twojego folderu z TFS, gdzie znajduje się plik config.lua.';
$locale['step_config_server_url'] = 'Adres strony';
$locale['step_config_server_url_desc'] = 'Adres tej strony www.';
$locale['step_config_mail_admin'] = 'E-Mail admina';
$locale['step_config_mail_admin_desc'] = 'Na ten adres będą dostarczane E-Maile z formularza kontaktowego, przykładowo admin@gmail.com';
$locale['step_config_mail_admin_error'] = 'E-Mail admina jest niepoprawny.';

View File

@@ -166,7 +166,7 @@ if(isset($_POST['emailchangecancel']) && $_POST['emailchangecancel'] == 1) {
$account_logged->setCustomField("email_new", "");
$account_logged->setCustomField("email_new_time", 0);
$custom_buttons = '<div style="text-align:center"><table border="0" cellspacing="0" cellpadding="0" ><form action="' . getLink('account/manage') . '" method="post" ><tr><td style="border:0px;" >' . $twig->render('buttons.back.html.twig') . '</td></tr></form></table></div>';
$custom_buttons = '<div style="text-align:center"><table border="0" cellspacing="0" cellpadding="0" ><form action="' . getLink('account/manage') . '" method="post" >' . csrf(true) . '<tr><td style="border:0px;" >' . $twig->render('buttons.back.html.twig') . '</td></tr></form></table></div>';
$twig->display('success.html.twig', array(
'title' => 'Email Address Change Cancelled',

View File

@@ -221,8 +221,14 @@ if($save)
}
}
if(setting('core.account_premium_points') && setting('core.account_premium_points') > 0) {
$new_account->setCustomField('premium_points', setting('core.account_premium_points'));
$accountDefaultPremiumPoints = setting('core.account_premium_points');
if($accountDefaultPremiumPoints > 0) {
$new_account->setCustomField('premium_points', $accountDefaultPremiumPoints);
}
$accountDefaultCoins = setting('core.account_coins');
if($db->hasColumn('accounts', 'coins') && $accountDefaultCoins > 0) {
$new_account->setCustomField('coins', $accountDefaultCoins);
}
$tmp_account = $email;

View File

@@ -1,23 +0,0 @@
<?php
/**
* Change comment
*
* @package MyAAC
* @author Gesior <jerzyskalski@wp.pl>
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$redirect = urldecode($_REQUEST['redirect']);
// should never happen, unless hacker modify the URL
if (!str_contains($redirect, BASE_URL)) {
error('Fatal error: Cannot redirect outside the website.');
return;
}
$twig->display('account.redirect.html.twig', array(
'redirect' => $redirect
));

View File

@@ -36,10 +36,9 @@ if(count($guilds_list) > 0) {
$guildName = $guild->getName();
$guilds[] = array('name' => $guildName, 'logo' => $guild_logo, 'link' => getGuildLink($guildName, false), 'description' => $description);
}
};
}
$twig->display('guilds.list.html.twig', array(
'guilds' => $guilds,
'logged' => $logged ?? false,
'isAdmin' => admin(),
));

View File

@@ -22,13 +22,16 @@ $promotion = '';
if($db->hasColumn('players', 'promotion'))
$promotion = '`promotion`,';
$order = $_GET['order'] ?? 'name';
if(!in_array($order, array('country', 'name', 'level', 'vocation')))
$order = $db->fieldName('name');
else if($order == 'country')
$order = $db->tableName('accounts') . '.' . $db->fieldName('country');
else if($order == 'vocation')
$order = $promotion . 'vocation ASC';
$order = $_GET['order'] ?? 'name_asc';
if(!in_array($order, ['country_asc', 'country_desc', 'name_asc', 'name_desc', 'level_asc', 'level_desc', 'vocation_asc', 'vocation_desc'])) {
$order = 'name_asc';
}
else if($order == 'vocation_asc' || $order == 'vocation_desc') {
$order = $promotion . 'vocation_' . (str_contains($order, 'asc') ? 'asc' : 'desc');
}
$orderExplode = explode('_', $order);
$orderSql = $orderExplode[0] . ' ' . $orderExplode[1];
$skull_type = 'skull';
if($db->hasColumn('players', 'skull_type')) {
@@ -58,11 +61,11 @@ if (setting('core.online_vocations')) {
}
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 ' . $order);
$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
$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 ' . $order);
$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);
$players_data = array();
$players_data = [];
$players = 0;
$data = '';
foreach($playersOnline as $player) {
@@ -115,7 +118,7 @@ if(count($players_data) > 0) {
}
if($result) {
$record = 'The maximum on this game world was ' . $result['record'] . ' players' . ($timestamp ? ' on ' . date("M d Y, H:i:s", $result['timestamp']) . '.' : '.');
$record = $result['record'] . ' player' . ($result['record'] > 1 ? 's' : '') . ($timestamp ? ' (on ' . date("M d Y, H:i:s", $result['timestamp']) . ')' : '');
}
}
}
@@ -124,8 +127,9 @@ $twig->display('online.html.twig', array(
'players' => $players_data,
'record' => $record,
'vocs' => $vocs,
'order' => $order,
));
//search bar
$twig->display('online.form.html.twig');
$twig->display('characters.form.html.twig');
?>

View File

@@ -129,14 +129,14 @@ $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r)
return ($a[3] < $b[3]) ? -1 : 1;
});
$aliases = [
[':int', ':string', ':alphanum'],
[':\d+', ':[A-Za-z0-9-_%+\' ]+', ':[A-Za-z0-9]+'],
];
// remove duplicates
// if same route pattern, but different priority
$routesFinal = array_filter($routesFinal, function ($a) {
$aliases = [
[':int', ':string', ':alphanum'],
[':\d+', ':[A-Za-z0-9-_%+\' ]+', ':[A-Za-z0-9]+'],
];
$routesFinal = array_filter($routesFinal, function ($a) use ($aliases) {
// apply aliases
$a[1] = str_replace($aliases[0], $aliases[1], $a[1]);
@@ -171,15 +171,15 @@ $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r)
$route[0] = array_map($toUpperCase, $route[0]);
}
$aliases = [
[':int', ':string', ':alphanum'],
[':\d+', ':[A-Za-z0-9-_%+\' ]+', ':[A-Za-z0-9]+'],
];
// apply aliases
$route[1] = str_replace($aliases[0], $aliases[1], $route[1]);
$r->addRoute($route[0], $route[1], $route[2]);
try {
$r->addRoute($route[0], $route[1], $route[2]);
}
catch (\Exception $e) {
// duplicated route, just ignore
}
}
if (config('env') === 'dev') {
@@ -252,7 +252,7 @@ else {
$success = false;
$tmp_content = getCustomPage($pageName, $success);
if ($success) {
if ($success && $hooks->trigger(HOOK_BEFORE_PAGE_CUSTOM)) {
$content .= $tmp_content;
if (hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) {
$pageInfo = getCustomPageInfo($pageName);
@@ -260,6 +260,8 @@ else {
) . $content;
}
$hooks->trigger(HOOK_AFTER_PAGE_CUSTOM);
$page = $pageName;
$file = false;
}
@@ -324,7 +326,9 @@ if (isset($_REQUEST['_page_only'])) {
if(!isset($title)) {
$title = str_replace('index.php/', '', $page);
$title = ucfirst($title);
$title = str_replace(['_', '-', '/'], ' ', $page);
$title = ucwords($title);
}
if(setting('core.backward_support')) {

View File

@@ -22,11 +22,11 @@ return [
['GET', 'account/confirm-email/{hash:alphanum}', 'account/confirm-email.php'],
['GET', 'bans/{page:int}', 'bans.php'],
[['GET', 'POST'], 'characters[/{name:string}]', 'characters.php'],
['GET', 'changelog[/{page:int}]', 'changelog.php'],
[['GET', 'POST'], 'monsters[/{name:string}]', 'monsters.php'],
[['GET', 'POST'], 'characters/{name:[A-Za-z0-9-_%+\' \[\]]+}', 'characters.php'],
['GET', 'changelog/{page:int}', 'changelog.php'],
[['GET', 'POST'], 'monsters/{name:string}', 'monsters.php'],
[['GET', 'POST'], 'faq[/{action:string}]', 'faq.php'],
[['GET', 'POST'], 'faq/{action:string}', 'faq.php'],
[['GET', 'POST'], 'forum/{action:string}', 'forum.php'],
['GET', 'forum/board/{id:int}', 'forum/show_board.php'],

View File

@@ -19,6 +19,15 @@ $templates = Cache::remember('templates', 5 * 60, function () {
});
$defaultTemplate = in_array('kathrine', $templates) ? 'kathrine' : $templates[0];
global $db;
if (!IS_CLI) {
require SYSTEM . 'base.php';
$serverUrl = 'http' . (isHttps() ? 's' : '') . '://' . $baseHost;
$siteURL = $serverUrl . $baseDir;
}
return [
'name' => 'MyAAC',
'settings' => [
@@ -30,6 +39,13 @@ return [
'type' => 'section',
'title' => 'General'
],
'site_url' => [
'name' => 'Website URL',
'type' => 'text',
'desc' => 'Website address of this MyAAC instance',
'default' => IS_CLI ? '' : $siteURL,
'is_config' => true,
],
'env' => [
'name' => 'App Environment',
'type' => 'options',
@@ -674,6 +690,13 @@ Sent by MyAAC,<br/>
'desc' => 'Default premium points on new account',
'default' => 0,
],
'account_coins' => [
'name' => 'Default Account Coins',
'type' => 'number',
'desc' => 'Default coins on new account',
'hidden' => ($db && !$db->hasColumn('accounts', 'coins')),
'default' => 0,
],
'account_mail_change' => [
'name' => 'Account Mail Change Days',
'type' => 'number',
@@ -1241,6 +1264,12 @@ Sent by MyAAC,<br/>
'desc' => '',
'default' => false,
],
'online_datacenter' => [
'name' => 'Data Center',
'type' => 'text',
'desc' => 'Server Location, will be shown on online page',
'default' => 'Frankfurt - Germany',
],
[
'type' => 'section',
'title' => 'Team Page'

View File

@@ -0,0 +1,49 @@
<?php
namespace MyAAC\Admin;
use GuzzleHttp\Client;
class Plugins
{
private string $api_base_uri = 'https://plugins.my-aac.org/api/';
public function getLatestVersions(): array
{
$client = new Client([
// Base URI is used with relative requests
'base_uri' => $this->api_base_uri,
// You can set any number of default request options.
'timeout' => 3.0,
]);
$plugins = get_plugins(true);
foreach ($plugins as &$plugin) {
if (str_contains($plugin, 'disabled.')) {
$plugin = str_replace('disabled.', '', $plugin);
}
}
try {
$response = $client->get('get-latest-versions', [
'json' => ['plugins' => $plugins],
]);
}
catch (\Exception $e) {
error('API Error. Please try again later.');
return [];
}
$statusCode = $response->getStatusCode();
if ($statusCode != 200) {
throw new \Exception('Error getting info from plugins repository. Please try again later.');
}
$data = $response->getBody();
return json_decode($data, true);
}
public function setApiBaseUri(string $uri): void {
$this->api_base_uri = $uri;
}
}

View File

@@ -38,6 +38,8 @@ class Hook
}
public function executeFilter(&$args) {
global $db, $config, $template_path, $ots, $content, $twig;
return include BASE . $this->_file;
}

View File

@@ -11,6 +11,25 @@ class Plugins {
private static $error = null;
private static $plugin_json = [];
public static function getInits()
{
return Cache::remember('plugins_inits', 10 * 60, function () {
$inits = [];
foreach(self::getAllPluginsJson() as $plugin) {
if (!self::getAutoLoadOption($plugin, 'init', false)) {
continue;
}
$pluginInits = glob(PLUGINS . $plugin['filename'] . '/init.php');
foreach ($pluginInits as $path) {
$inits[] = $path;
}
}
return $inits;
});
}
public static function getAdminPages()
{
return Cache::remember('plugins_admin_pages', 10 * 60, function () {

View File

@@ -8,7 +8,9 @@ $i = 0;
define('HOOK_INIT', ++$i);
define('HOOK_STARTUP', ++$i);
define('HOOK_BEFORE_PAGE', ++$i);
define('HOOK_BEFORE_PAGE_CUSTOM', ++$i);
define('HOOK_AFTER_PAGE', ++$i);
define('HOOK_AFTER_PAGE_CUSTOM', ++$i);
define('HOOK_FINISH', ++$i);
define('HOOK_TIBIACOM_ARTICLE', ++$i);
define('HOOK_TIBIACOM_BORDER_3', ++$i);
@@ -52,6 +54,7 @@ define('HOOK_ACCOUNT_MANAGE_BEFORE_GENERAL_INFORMATION', ++$i);
define('HOOK_ACCOUNT_MANAGE_BEFORE_PUBLIC_INFORMATION', ++$i);
define('HOOK_ACCOUNT_MANAGE_BEFORE_ACCOUNT_LOGS', ++$i);
define('HOOK_ACCOUNT_MANAGE_BEFORE_CHARACTERS', ++$i);
define('HOOK_ACCOUNT_MANAGE_AFTER_CHARACTERS', ++$i);
define('HOOK_ACCOUNT_LOGIN_BEFORE_PAGE', ++$i);
define('HOOK_ACCOUNT_LOGIN_BEFORE_ACCOUNT', ++$i);
define('HOOK_ACCOUNT_LOGIN_AFTER_ACCOUNT', ++$i);
@@ -90,6 +93,7 @@ define('HOOK_EMAIL_CONFIRMED', ++$i);
define('HOOK_GUILDS_BEFORE_GUILD_HEADER', ++$i);
define('HOOK_GUILDS_AFTER_GUILD_HEADER', ++$i);
define('HOOK_GUILDS_AFTER_GUILD_INFORMATION', ++$i);
define('HOOK_GUILDS_AFTER_MANAGE_BUTTON', ++$i);
define('HOOK_GUILDS_AFTER_GUILD_MEMBERS', ++$i);
define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i);
define('HOOK_TWIG', ++$i);

View File

@@ -28,7 +28,7 @@ Please enter your password and the new email address. Make sure that you enter a
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td style="border:0px;">
<td style="border:0;">
<form id="form" action="{{ getLink('account/change-email') }}" method="post">
{{ csrf() }}
<input type="hidden" name="changeemailsave" value="1"/>
@@ -40,14 +40,14 @@ Please enter your password and the new email address. Make sure that you enter a
</td>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
{{ include('buttons.back.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</td>
</tr>

View File

@@ -88,7 +88,7 @@ If you do not want to specify a certain field, just leave it blank.<br/><br/>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td style="border:0px;">
<td style="border:0;">
<input type="hidden" name="name" value="{{ player.name }}">
<input type="hidden" name="changecommentsave" value="1">
{{ include('buttons.submit.html.twig') }}
@@ -99,15 +99,15 @@ If you do not want to specify a certain field, just leave it blank.<br/><br/>
</td>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
{{ include('buttons.back.html.twig') }}
</td>
</tr>
</form>
</table>
</form>
</td>
</tr>
</table>
</td>
</tr>
</table>

View File

@@ -24,7 +24,7 @@ To delete a character enter the name of the character and your password.<br/><br
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td style="border:0px;">
<td style="border:0;">
<form id="form" action="{{ getLink('account/characters/delete') }}" method="post">
{{ csrf() }}
<input type="hidden" name="deletecharactersave" value="1"/>
@@ -36,14 +36,14 @@ To delete a character enter the name of the character and your password.<br/><br
</td>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
{{ include('buttons.back.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</td>
</tr>

View File

@@ -32,14 +32,14 @@ To generate recovery key for your account please enter your password.<br/><br/>
</td>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
<tr>
<td style="border: 0;">
<tr>
<td style="border: 0;">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
{{ include('buttons.back.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</td>
</tr>

View File

@@ -228,5 +228,7 @@
</td>
</tr>
</table>
<br/>
{{ hook('HOOK_ACCOUNT_MANAGE_AFTER_CHARACTERS') }}
</div>
</div>

View File

@@ -1,7 +1,9 @@
<div id="install_plugin">
<div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0">Install plugin</h5>
<h5 class="m-0">Install plugin
<a href="?p=plugins&check-updates" class="btn btn-primary float-right">Check for updates</a>
</h5>
</div>
<form enctype="multipart/form-data" method="post" action="{{ constant('ADMIN_URL') }}?p=plugins">
{{ csrf() }}

View File

@@ -0,0 +1,18 @@
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Plugin Name</th>
<th>Your Version</th>
<th>Latest Version</th>
<th>Download Link</th>
</tr>
</thead>
{% for plugin in plugins %}
<tr>
<td>{{ plugin.name }}</td>
<td>{{ plugin.yourVersion }}</td>
<td>{{ plugin.latestVersion }}</td>
<td><a href="{{ plugin.download_link }}" target="_blank">{{ plugin.download_link }}</a></td>
</tr>
{% endfor %}
</table>

View File

@@ -1,17 +1,23 @@
<form action="{{ link }}" method="post">
<table width="100%" border="0" cellspacing="1" cellpadding="4">
<tr><td bgcolor="{{ config.vdarkborder }}" class="white"><B>Search Character</B></TD></TR>
<tr>
<td bgcolor="{{ config.darkborder }}">
<table border="0" cellpadding="1">
<tr>
<td>Name:</td><td><input name="name" value="" size="29" maxlength="29"{% if autofocus %} autofocus{% endif %}></TD>
<td>
{{ include('buttons.submit.html.twig') }}
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<br/>
<form action="{{ getLink('characters') }}" method="post">
{% set title = 'Search Character' %}
{% set tableClass = 'Table1' %}
{% set background = config('darkborder') %}
{% set content %}
<table width="100%">
<tr>
<td style="vertical-align:middle" class="LabelV150">
Character Name:
</td>
<td style="width:170px">
<input style="width:165px" name="name" value="" size="29" maxlength="29"/>
</td>
<td>
{% set button_name = 'Submit' %}
{{ include('buttons.base.html.twig') }}
</td>
</tr>
</table>
{% endset %}
{{ include('tables.headline.html.twig') }}
</form>

View File

@@ -49,6 +49,7 @@
{% include('buttons.base.html.twig') %}
</a>
{% endif %}
{{ hook('HOOK_GUILDS_AFTER_MANAGE_BUTTON') }}
</div>
</td>
</tr>
@@ -61,6 +62,7 @@
{{ hook('HOOK_GUILDS_AFTER_GUILD_INFORMATION') }}
{% set title = 'Guild Members' %}
{% set background = config('lightborder') %}
{% set content %}
<table style="width:100%;">
<tbody>
@@ -151,6 +153,7 @@
{{ hook('HOOK_GUILDS_AFTER_GUILD_MEMBERS') }}
{% set title = 'Invited Characters' %}
{% set background = config('lightborder') %}
{% set content %}
<table style="width:100%;">
<tbody>

View File

@@ -9,7 +9,7 @@
<form action="{{ constant('BASE_URL') }}install/" method="post" autocomplete="off">
<input type="hidden" name="step" id="step" value="database" />
{% for value in ['server_path'] %}
{% for value in ['site_url', 'server_path'] %}
<div class="form-group mb-2">
<label for="vars_{{ value }}">{{ locale['step_config_' ~ value] }}</label>
<input class="form-control" type="{% if value == 'mail_admin' %}email{% else %}text{% endif %}" name="vars[{{ value }}]" id="vars_{{ value }}"{% if session['var_' ~ value] is not null %} value="{{ session['var_' ~ value] }}"{% endif %}/>

View File

@@ -1,25 +0,0 @@
<br/>
<form action="{{ getLink('characters') }}" method=post>
<table width="100%" border="0" cellspacing="1" cellpadding="4">
<tr>
<td bgcolor="{{ config.vdarkborder }}" class="white">
<b>Search Character</b>
</td>
</tr>
<tr>
<td bgcolor="{{ config.darkborder }}">
<table border="0" cellpadding="1">
<tr>
<td>Name:</td>
<td>
<input name="name" value=""size=29 maxlength=29>
</td>
<td>
{{ include('buttons.submit.html.twig') }}
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>

View File

@@ -1,39 +1,7 @@
<table border="0" cellspacing="1" cellpadding="4" width="100%">
<tr bgcolor="{{ config.vdarkborder }}">
<td class="white"><b>Server Status</b></td>
</tr>
{% if players|length == 0 %}
<tr bgcolor="{{ config.darkborder }}"><td>Currently no one is playing on {{ config.lua.serverName }}.</td></tr></table>
{% else %}
<tr bgcolor="{{ config.darkborder }}">
<td>
{% if not status.online %}
Server is offline.<br/>
{% else %}
{% if setting('core.online_afk') %}
{% set players_count = players|length %}
{% set afk = players_count - status.players %}
{% if afk < 0 %}
{% set players_count = players_count + afk|abs %}
{% set afk = 0 %}
{% endif %}
Currently there are <b>{{ status.players }}</b> active and <b>{{ afk }}</b> AFK players.<br/>
Total number of players: <b>{{ players_count }}</b>.<br/>
{% else %}
Currently {{ players|length }} players are online.<br/>
{% endif %}
{% endif %}
{% if setting('core.online_record') %}
{{ record }}
{% endif %}
</td>
</tr>
</table>
{# vocation statistics #}
{% if setting('core.online_vocations') %}
<br/>
{# vocation statistics #}
{% if setting('core.online_vocations') %}
<br/>
{% if setting('core.online_vocations_images') %}
{% if setting('core.online_vocations_images') %}
<table width="200" cellspacing="1" cellpadding="0" border="0" align="center">
<tr bgcolor="{{ config.darkborder }}">
<td><img src="images/sorcerer.png" /></td>
@@ -69,11 +37,13 @@
{% endfor %}
</table>
<br/>
{% endif %}
{% endif %}
{% endif %}
{# show skulls #}
{% if setting('core.online_skulls') %}
<br/>
{# show skulls #}
{% if setting('core.online_skulls') %}
<table width="100%" cellspacing="1">
<tr>
<td style="background: {{ config.darkborder }};" align="center">
@@ -83,34 +53,114 @@
</td>
</tr>
</table>
{% endif %}
<br/>
{% set title = 'World Information' %}
{% set tableClass = 'Table3' %}
{% set background = config('darkborder') %}
{% set content %}
<table width="100%">
<tr>
<td class="LabelV150"><b>Status:</b></td>
<td>{% if not status.online %}Offline{% else %}Online{% endif %}</td>
</tr>
<tr>
<td class="LabelV150"><b>Players Online:</b></td>
<td>
{% if setting('core.online_afk') %}
{% set players_count = players|length %}
{% set afk = players_count - status.players %}
{% if afk < 0 %}
{% set players_count = players_count + afk|abs %}
{% set afk = 0 %}
{% endif %}
Currently there are <b>{{ status.players }}</b> active and <b>{{ afk }}</b> AFK players.<br/>
Total number of players: <b>{{ players_count }}</b>.<br/>
{% else %}
{{ players|length }}
{% endif %}
</td>
</tr>
{% if setting('core.online_record') %}
<tr>
<td class="LabelV150"><b>Online Record:</b></td>
<td>
{{ record }}
</td>
</tr>
{% endif %}
<table border="0" cellspacing="1" cellpadding="4" width="100%">
<tr bgcolor="{{ config.vdarkborder }}">
<tr>
<td class="LabelV150"><b>Location Datacenter:</b></td>
<td>{{ setting('core.online_datacenter') }} <small>(Server date & time: - {{ "now"|date("d/m/Y H:i:s") }})</small></td>
</tr>
<tr>
<td class="LabelV150"><b>PvP Type:</b></td>
<td>
{% set worldType = config('lua')['worldType']|lower %}
{% if worldType in ['pvp','2','normal','open','openpvp'] %}
Open PvP
{% elseif worldType in ['no-pvp','nopvp','non-pvp','nonpvp','1','safe','optional','optionalpvp'] %}
Optional PvP
{% elseif worldType in ['pvp-enforced','pvpenforced','pvp-enfo','pvpenfo','pvpe','enforced','enfo','3','war','hardcore','hardcorepvp'] %}
Hardcore PvP
{% endif %}
</td>
</tr>
</table>
{% endset %}
{% include 'tables.headline.html.twig' %}
<br/>
<br/>
{% set title = 'Players Online' %}
{% set tableClass = 'Table2' %}
{% set content %}
<table width="100%">
<tr class="LabelH" style="position: relative; z-index: 20;">
{% if setting('core.account_country') %}
<td width="11px"><a href="{{ getLink('online?order=country') }}" class="white">#</A></td>
<td width="11px"><a href="{{ getLink('online')}}?order=country_{{ order == 'country_asc' ? 'desc' : 'asc' }}">#&#160;&#160;</a>
</td>
{% endif %}
{% if setting('core.online_outfit') %}
<td class="white"><b>Outfit</b></td>
<td><b>Outfit</b></td>
{% endif %}
<td width="60%"><a href="{{ getLink('online?order=name') }}" class="white">Name</A></td>
<td width="20%"><a href="{{ getLink('online?order=level') }}" class="white">Level</A></td>
<td width="20%"><a href="{{ getLink('online?order=vocation') }}" class="white">Vocation</td>
<td style="text-align:left; width:50%">Name&#160;&#160;
<small style="font-weight:normal">[<a href="{{ getLink('online')}}?order=name_{{ order == 'name_asc' ? 'desc' : 'asc' }}">sort</a>]</small>
<img class="sortarrow" src="images/{{ order == 'name_asc' ? 'order_desc' : (order == 'name_desc' ? 'order_asc' : 'news/blank') }}.gif"/></td>
<td style="text-align:left;width:30%">Level&#160;&#160;
<small style="font-weight:normal">[<a href="{{ getLink('online')}}?order=level_{{ order == 'level_asc' ? 'desc' : 'asc' }}">sort</a>]</small>
<img class="sortarrow" src="images/{{ order == 'level_asc' ? 'order_desc' : (order == 'level_desc' ? 'order_asc' : 'news/blank') }}.gif"/>
</td>
<td style="text-align:left;width:50%">Vocation&#160;&#160;
<small style="font-weight:normal">[<a href="{{ getLink('online')}}?order=vocation_{{ order == 'vocation_asc' ? 'desc' : 'asc' }}">sort</a>]</small>
<img class="sortarrow" src="images/{{ order == 'vocation_asc' ? 'order_desc' : (order == 'vocation_desc' ? 'order_asc' : 'news/blank') }}.gif"/>
</td>
</tr>
{% set i = 0 %}
{% for player in players %}
{% set i = i + 1 %}
<tr bgcolor="{{ getStyle(i) }}">
{% if setting('core.account_country') %}
<td>{{ player.country_image|raw }}</td>
{% endif %}
{% if setting('core.online_outfit') %}
<td width="5%"><img style="position:absolute;margin-top:{% if player.player.looktype in setting('core.outfit_images_wrong_looktypes') %}-20px;margin-left:-0px;{% else %}-45px;margin-left:-25px;{% endif %}" src="{{ player.outfit }}" alt="player outfit"/></td>
{% endif %}
<td>{{ player.name|raw }}{{ player.skull }}</td>
<td>{{ player.level }}</td>
<td>{{ player.vocation }}</td>
<tr style="background: {{ getStyle(i) }}; text-align: right; height: 40px;">
{% if setting('core.account_country') %}
<td>{{ player.country_image|raw }}</td>
{% endif %}
{% if setting('core.online_outfit') %}
<td width="5%"><img style="position:absolute;margin-top:-48px;margin-left:-70px;" src="{{ player.outfit }}" alt="player outfit"/></td>
{% endif %}
<td style="width:70%; text-align:left">
{{ player.name|raw }}{{ player.skull }}
</td>
<td style="width:10%">{{ player.level }}</td>
<td style="width:20%">{{ player.vocation }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% endset %}
{{ include('tables.headline.html.twig') }}

View File

@@ -18,13 +18,14 @@
{% else %}
<div style="text-align:center">
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/manage') }}" method="post">
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
{{ include('buttons.back.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</div>
{% endif %}

View File

@@ -8,7 +8,7 @@
selector: "#editor",
content_css: '{{ constant('ADMIN_URL') }}template/style.css',
theme: "silver",
plugins: 'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help code emoticons',
plugins: 'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help code emoticons',
toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | emoticons link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat code',
resize: 'both',
image_advtab: true,
@@ -23,6 +23,8 @@
{title: 'Colored Table', value: 'myaac-table'},
],
license_key: 'gpl',
setup: function (ed) {
ed.on('NodeChange', function (e) {
if (ed.getContent() !== lastContent) {

View File

@@ -453,6 +453,27 @@ a:hover
white-space: nowrap;
vertical-align: top;
}
.LabelV120 {
font-weight: bold;
padding-right: 10px;
white-space: nowrap;
vertical-align: top;
width: 120px;
}
.LabelV150 {
font-weight: bold;
padding-right: 10px;
white-space: nowrap;
vertical-align: top;
width: 150px;
}
.LabelV200 {
font-weight: bold;
padding-right: 10px;
white-space: nowrap;
vertical-align: top;
width: 200px;
}
.LabelH {
font-weight: bold;
padding-right: 10px;

View File

@@ -11,13 +11,14 @@
<td width="100%"></td>
<td>
<table border="0" cellspacing="0" cellpadding="0" >
<form action="{{ getLink('account/logout') }}" method="post" >
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/logout') }}" method="post" >
{{ csrf() }}
{{ include('buttons.logout.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</td>
</tr>
@@ -59,13 +60,14 @@
</table>
<div style="text-align:center">
<table border="0" cellspacing="0" cellpadding="0" style="margin-left: auto; margin-right: auto;">
<form action="{{ getLink('account/register') }}" method="post">
<tr>
<td style="border:0;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/register') }}" method="post">
{{ csrf() }}
{{ include('buttons.register_account.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</div>
</div>
@@ -94,13 +96,14 @@
</table>
<div style="text-align:center">
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/change-email') }}" method="post">
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/change-email') }}" method="post">
{{ csrf() }}
{{ include('buttons.edit.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</div>
</div>
@@ -177,26 +180,29 @@
<tr>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/change-password') }}" method="post">
<tr>
<td style="border:0px;" >
<tr>
<td style="border:0;" >
<form action="{{ getLink('account/change-password') }}" method="post">
{{ csrf() }}
{{ include('buttons.change_password.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</td>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/change-email') }}" method="post">
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/change-email') }}" method="post">
{{ csrf() }}
<input type="hidden" name="newemail" value=""/>
<input type="hidden" name="newemaildate" value="0">
{{ include('buttons.change_email.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</td>
<td width="100%"></td>
@@ -204,13 +210,14 @@
{% if recovery_key is empty %}
<td>
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/register') }}" method="post">
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/register') }}" method="post">
{{ csrf() }}
{{ include('buttons.register_account.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</td>
{% endif %}
@@ -258,13 +265,14 @@
</td>
<td align=right>
<table border="0" cellspacing="0" cellpadding="0">
<form action="{{ getLink('account/change-info') }}" method="post">
<tr>
<td style="border:0px;">
<tr>
<td style="border:0;">
<form action="{{ getLink('account/change-info') }}" method="post">
{{ csrf() }}
{{ include('buttons.edit.html.twig') }}
</td>
</tr>
</form>
</form>
</td>
</tr>
</table>
</td>
</tr>
@@ -398,8 +406,9 @@
<td>
<table border="0" cellspacing="0" cellpadding="0" >
<tr>
<td style="border:0px;">
<td style="border:0;">
<form action="{{ getLink('account/characters/create') }}" method="post" >
{{ csrf() }}
{{ include('buttons.create_character.html.twig') }}
</form>
</td>
@@ -410,8 +419,9 @@
<td>
<table border="0" cellspacing="0" cellpadding="0" >
<tr>
<td style="border:0px;">
<td style="border:0;">
<form action="{{ getLink('account/characters/change-name') }}" method="post" >
{{ csrf() }}
{{ include('buttons.change_name.html.twig') }}
</form>
</td>
@@ -423,8 +433,9 @@
<td>
<table border="0" cellspacing="0" cellpadding="0" >
<tr>
<td style="border:0px;">
<td style="border:0;">
<form action="{{ getLink('account/characters/change-sex') }}" method="post">
{{ csrf() }}
{{ include('buttons.change_sex.html.twig') }}
</form>
</td>
@@ -436,8 +447,9 @@
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td style="border: 0px;">
<td style="border: 0;">
<form action="{{ getLink('account/characters/delete') }}" method="post">
{{ csrf() }}
{{ include('buttons.delete_character.html.twig') }}
</form>
</td>
@@ -451,4 +463,7 @@
</table>
{% endset %}
{% include 'tables.headline.html.twig' %}
<br/><br/>
<br/>
{{ hook('HOOK_ACCOUNT_MANAGE_AFTER_CHARACTERS') }}
<br/>

View File

@@ -1446,6 +1446,27 @@ img {
white-space: nowrap;
vertical-align: top;
}
.LabelV120 {
font-weight: bold;
padding-right: 10px;
white-space: nowrap;
vertical-align: top;
width: 120px;
}
.LabelV150 {
font-weight: bold;
padding-right: 10px;
white-space: nowrap;
vertical-align: top;
width: 150px;
}
.LabelV200 {
font-weight: bold;
padding-right: 10px;
white-space: nowrap;
vertical-align: top;
width: 200px;
}
.LabelH {
font-weight: bold;
padding-right: 10px;

View File

@@ -35,6 +35,7 @@
<tr>
<td style="border:0;">
<form action="{{ getLink('account/manage') }}" method="post">
{{ csrf() }}
{{ include('buttons.back.html.twig') }}
</form>
</td>