Compare commits

..

26 Commits

Author SHA1 Message Date
slawkens
9c327336d3 Release v1.8.5 2025-11-21 14:51:28 +01:00
slawkens
1d21f4d682 Update create.php 2025-11-18 12:24:22 +01:00
slawkens
603d860b56 Detect "deletion" column in guilds delete 2025-11-18 09:56:07 +01:00
slawkens
6775a061be Detect "deletion" column in guilds show 2025-11-18 00:16:26 +01:00
slawkens
e440c0d6a6 Update .gitignore 2025-11-13 19:14:59 +01:00
slawkens
780d4ccef7 Server Status: Write to status-error.log if there is connection error 2025-11-06 22:06:05 +01:00
slawkens
0a6d44bf21 Fix $status['uptimeReadable'], was totally wrong 2025-11-06 13:47:09 +01:00
slawkens
4d17001a0b Add some popular network images (Facebook, Instagram, WhatsApp) 2025-11-06 12:48:33 +01:00
slawkens
946364f59d New Setting: Account Countries Most Popular 2025-11-06 12:01:33 +01:00
slawkens
5861efdbe9 Settings: escapeHtml in values (support for html code) 2025-11-06 11:48:42 +01:00
slawkens
175e97828b Don't display hidden news for admin - it's confusing 2025-11-05 22:21:42 +01:00
slawkens
9ce55db44c Display error message after failed settings save - just in case 2025-11-05 22:02:11 +01:00
slawkens
88532b0ebb Better message than "Access denied" 2025-11-05 19:32:31 +01:00
slawkens
1c7af30997 Revert "Just testing something, excuse me"
This reverts commit 7ca05e47ff.
2025-11-04 22:17:00 +01:00
slawkens
7ca05e47ff Just testing something, excuse me 2025-11-04 22:01:55 +01:00
slawkens
baec6c9ebf plugin:activate/deactivate alias 2025-11-04 08:17:41 +01:00
slawkens
6367054487 Add plugin:remove + plugin:delete as alias for plugin:uninstall 2025-11-03 21:06:27 +01:00
slawkens
ae7a47464f Update menus.php 2025-11-03 20:37:14 +01:00
slawkens
d201e75b11 Revert "Try to fix "VirtualProtect() failed [87] The parameter is incorrect" in php logs"
This reverts commit 4924696943.
2025-11-02 13:38:15 +01:00
slawkens
4924696943 Try to fix "VirtualProtect() failed [87] The parameter is incorrect" in php logs 2025-11-02 13:23:30 +01:00
slawkens
25a3db68e6 Use $db->hasTableAndColumns + move $skulls to correct place 2025-11-02 13:10:09 +01:00
slawkens
730a0f2912 Ensure some cache folders & index.html exists 2025-11-02 12:21:29 +01:00
slawkens
fd729242ff Fix typo -> satisfied 2025-11-02 12:05:47 +01:00
slawkens
26c5aa2e51 Added more code into Items::getDescription
Is not ready yet
2025-10-31 06:52:56 +01:00
slawkens
bc4107bd16 Ignore only top-most Lua folder 2025-10-30 18:54:11 +01:00
slawkens
d24bde2c1d Start v1.8.5-dev 2025-10-27 21:45:34 +01:00
26 changed files with 196 additions and 54 deletions

3
.gitignore vendored
View File

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

View File

@@ -1,5 +1,21 @@
# Changelog
## [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

View File

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

View File

@@ -12,7 +12,7 @@ require SYSTEM . 'login.php';
if(!admin()) {
http_response_code(500);
die('Access denied.');
die('You are not logged in. Probably session expired. Please login again.');
}
csrfProtect();
@@ -40,3 +40,6 @@ if (count($errors) > 0) {
if ($success) {
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

@@ -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.8.4';
const MYAAC_VERSION = '1.8.5';
const DATABASE_VERSION = 46;
const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true));

BIN
images/facebook_16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

BIN
images/instagram_16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

BIN
images/whatsapp_16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

View File

@@ -433,16 +433,22 @@ function delete_guild($id)
$rank_list->orderBy('level');
global $db;
$deletedColumn = 'deleted';
if ($db->hasColumn('players', 'deletion')) {
$deletedColumn = 'deletion';
}
/**
* @var OTS_GuildRank $rank_in_guild
*/
foreach($rank_list as $rank_in_guild) {
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` 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` AND `' . $deletedColumn . '` = 0 ORDER BY `name`;');
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` 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` AND `' . $deletedColumn . '` = 0 ORDER BY `name`;');
else
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `deleted` = 0;');
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `' . $deletedColumn . '` = 0;');
$players_with_rank_number = $players_with_rank->rowCount();
if($players_with_rank_number > 0) {
@@ -1177,7 +1183,8 @@ function getTopPlayers($limit = 5, $skill = 'level') {
});
}
function deleteDirectory($dir, $ignore = array(), $contentOnly = false) {
function deleteDirectory($dir, $ignore = array(), $contentOnly = false): bool
{
if(!file_exists($dir)) {
return true;
}
@@ -1203,6 +1210,21 @@ function deleteDirectory($dir, $ignore = array(), $contentOnly = false) {
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) {
global $config;
if (is_array($key)) {
@@ -1712,6 +1734,43 @@ function isCanary(): bool
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
require_once SYSTEM . 'compat/base.php';

View File

@@ -18,6 +18,9 @@ use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!');
ensureIndexExists(CACHE);
ensureIndexExists(CACHE . 'twig/');
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.');

View File

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

View File

@@ -367,7 +367,7 @@ if(!empty($errors))
if (setting('core.account_country')) {
$countries = array();
foreach (array('pl', 'se', 'br', 'us', 'gb') as $c)
foreach (setting('core.account_countries_most_popular') ?? [] as $c)
$countries[$c] = $config['countries'][$c];
$countries['--'] = '----------';

View File

@@ -202,35 +202,37 @@ if($player->isLoaded() && !$player->isDeleted())
unset($storage);
}
if($db->hasTable('player_items') && $db->hasColumn('player_items', 'pid') && $db->hasColumn('player_items', 'sid') && $db->hasColumn('player_items', 'itemtype')) {
if ($db->hasTableAndColumns('player_items', ['pid', 'sid', 'itemtype'])) {
$eq_sql = $db->query('SELECT `pid`, `itemtype` FROM player_items WHERE player_id = '.$player->getId().' AND (`pid` >= 1 and `pid` <= 10)');
$equipment = array();
foreach($eq_sql as $eq)
$equipment = [];
foreach($eq_sql as $eq) {
$equipment[$eq['pid']] = $eq['itemtype'];
}
$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++)
{
$empty_slots = ["", "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++) {
if(!isset($equipment[$i]) || $equipment[$i] == 0)
$equipment[$i] = $empty_slots[$i];
}
for($i = 1; $i < 11; $i++)
{
if(Validator::number($equipment[$i]))
for($i = 1; $i < 11; $i++) {
if(Validator::number($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] . '" />';
}
}
}
$skulls = array(
$skulls = [
1 => 'yellow_skull',
2 => 'green_skull',
3 => 'white_skull',
4 => 'red_skull',
5 => 'black_skull'
);
}
5 => 'black_skull',
];
$dead_add_content = '';
$deaths = array();

View File

@@ -22,7 +22,7 @@ if(!$logged) {
}
$configLuaFreePremium = configLua('freePremium');
$freePremium = (isset($configLuaFreePremium) && getBoolean($configLuaFreePremium)) || ($logged && $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS);
$freePremium = (isset($configLuaFreePremium) && getBoolean($configLuaFreePremium));
$array_of_player_nig = array();
if(empty($errors))

View File

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

View File

@@ -122,7 +122,7 @@ if(!$news_cached)
);
}
$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_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_content = '';
if($tickers_db->rowCount() > 0)
{
@@ -142,7 +142,8 @@ if(!$news_cached)
if($cache->enabled() && !$canEdit)
$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 . ($canEdit ? '' : ' 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 . ' AND `hide` != 1 ORDER BY `date` DESC LIMIT 1');
$article = '';
if($featured_article_db->rowCount() > 0) {
$article = $featured_article_db->fetch();
@@ -175,7 +176,7 @@ else {
if(!$news_cached)
{
ob_start();
$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'));
$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'));
if($newses->rowCount() > 0)
{
foreach($newses as $news)

View File

@@ -737,6 +737,18 @@ 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',
'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' => [
'name' => 'Characters per Account',
'type' => 'number',

View File

@@ -27,6 +27,9 @@ class PHP
{
$var = var_export($var, true);
ensureFolderExists($this->dir);
ensureIndexExists($this->dir);
// 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);

View File

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

View File

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

View File

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

View File

@@ -76,10 +76,11 @@ class Items
public static function get($id) {
self::load();
return isset(self::$items[$id]) ? self::$items[$id] : [];
return self::$items[$id] ?? [];
}
public static function getDescription($id, $count = 1) {
public static function getDescription($id, $count = 1): string
{
$item = self::get($id);
$attr = $item['attributes'];
@@ -112,15 +113,15 @@ class Items
$s .= 'an item of type ' . $item['id'];
if(isset($attr['type']) && strtolower($attr['type']) == 'rune') {
$item = Spell::where('item_id', $id)->first();
if($item) {
if($item->level > 0 && $item->maglevel > 0) {
$s .= '. ' . ($count > 1 ? "They" : "It") . ' can only be used by ';
$spell = Spell::where('item_id', $id)->first();
if($spell) {
if($spell->level > 0 && $spell->maglevel > 0) {
$s .= '. ' . ($count > 1 ? 'They' : 'It') . ' can only be used by ';
}
$configVocations = config('vocations');
if(!empty(trim($item->vocations))) {
$vocations = json_decode($item->vocations);
if(!empty(trim($spell->vocations))) {
$vocations = json_decode($spell->vocations);
if(count($vocations) > 0) {
foreach($vocations as $voc => $show) {
$vocations[$configVocations[$voc]] = $show;
@@ -133,8 +134,39 @@ class Items
$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;
}
}

View File

@@ -513,6 +513,9 @@ class Plugins {
return false;
}
ensureFolderExists($cachePlugins = CACHE . 'plugins');
ensureIndexExists($cachePlugins);
self::$error = 'There was a problem with extracting zip archive.';
$file_name = $plugin_temp_dir . $json_file;
if(!file_exists($file_name)) {
@@ -549,21 +552,21 @@ class Plugins {
if(isset($plugin_json['require'])) {
$require = $plugin_json['require'];
$myaac_satified = true;
$myaac_satisfied = true;
if(isset($require['myaac_'])) {
$require_myaac = $require['myaac_'];
if(!Semver::satisfies(MYAAC_VERSION, $require_myaac)) {
$myaac_satified = false;
$myaac_satisfied = false;
}
}
else if(isset($require['myaac'])) {
$require_myaac = $require['myaac'];
if(version_compare(MYAAC_VERSION, $require_myaac, '<')) {
$myaac_satified = false;
$myaac_satisfied = false;
}
}
if(!$myaac_satified) {
if(!$myaac_satisfied) {
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;
}

View File

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

View File

@@ -145,13 +145,7 @@ function updateStatus() {
}
$uptime = $status['uptime'] = $serverStatus->getUptime();
$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['uptimeReadable'] = getStatusUptimeReadable($uptime);
$status['monsters'] = $serverStatus->getMonstersCount();
$status['motd'] = $serverStatus->getMOTD();

View File

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