Compare commits

..

17 Commits
v1.8 ... main

Author SHA1 Message Date
slawkens
4b948e9510 Option to change/set plugin settings by plugin name 2025-08-22 18:20:37 +02:00
slawkens
17ca93d020 Same with default 2025-08-22 17:51:19 +02:00
slawkens
bcc4b48eb0 Settings: Option to set boolean values as "yes" 2025-08-22 17:39:14 +02:00
slawkens
f8c4332e03 Option to reset plugin settings by plugin name 2025-08-22 17:27:53 +02:00
slawkens
235e0f394d Refactor code to use Cache::remember 2025-08-22 16:04:52 +02:00
slawkens
3451715e96 Settings class: Add type hints 2025-08-22 15:30:19 +02:00
slawkens
d85681880e Rename file name to PluginSetupCommand 2025-08-21 21:12:55 +02:00
slawkens
4701461b1f Add some comment about optional sorting, into migrate:run command 2025-08-21 20:54:58 +02:00
slawkens
482f4067b2 Menus should be saved for each template separately
Trying to fix some weird bug
2025-08-17 18:45:49 +02:00
slawkens
2f26748112 ❤️ 2025-08-17 18:19:07 +02:00
slawkens
98073a110a Fix online skulls display (Fix #320) 2025-08-17 17:50:16 +02:00
slawkens
11dae90fa9 Fix MenuBotton display if some elements are removed
From menu_categories
2025-08-12 17:42:06 +02:00
slawkens
20f99903ae Fix submenu initialization for missing elements
Added a check in InitializeMenu to skip submenu items if their corresponding DOM element does not exist, preventing potential JavaScript errors.
2025-08-12 12:46:39 +02:00
slawkens
b6e1620f14 Fix #318 (online.php throws error in one scenario) 2025-08-07 21:17:25 +02:00
dependabot[bot]
9cb7792623
Bump tmp from 0.2.3 to 0.2.4 (#317)
Bumps [tmp](https://github.com/raszi/node-tmp) from 0.2.3 to 0.2.4.
- [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/raszi/node-tmp/compare/v0.2.3...v0.2.4)

---
updated-dependencies:
- dependency-name: tmp
  dependency-version: 0.2.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-07 16:21:22 +02:00
dependabot[bot]
0db908be18
Bump form-data from 4.0.2 to 4.0.4 (#315)
Bumps [form-data](https://github.com/form-data/form-data) from 4.0.2 to 4.0.4.
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](https://github.com/form-data/form-data/compare/v4.0.2...v4.0.4)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-02 14:15:13 +02:00
slawkens
785d38312b Start 1.8.1-dev 2025-08-02 12:41:35 +02:00
13 changed files with 95 additions and 63 deletions

View File

@ -1,6 +1,6 @@
# Changelog # Changelog
## [1.8 - 01.08.2025] ## [1.8 - 02.08.2025]
### Added ### Added
* Templates - Kathrine: Possibility to add custom menu categories (https://github.com/slawkens/myaac/commit/ec11c1402417c25980582467546d1c1e9bb8267f) * Templates - Kathrine: Possibility to add custom menu categories (https://github.com/slawkens/myaac/commit/ec11c1402417c25980582467546d1c1e9bb8267f)

View File

@ -26,7 +26,7 @@
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
const MYAAC = true; const MYAAC = true;
const MYAAC_VERSION = '1.8'; const MYAAC_VERSION = '1.8.1-dev';
const DATABASE_VERSION = 45; const DATABASE_VERSION = 45;
const TABLE_PREFIX = 'myaac_'; const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true)); define('START_TIME', microtime(true));

13
package-lock.json generated
View File

@ -976,15 +976,16 @@
} }
}, },
"node_modules/form-data": { "node_modules/form-data": {
"version": "4.0.2", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
"combined-stream": "^1.0.8", "combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0", "es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12" "mime-types": "^2.1.12"
}, },
"engines": { "engines": {
@ -2084,9 +2085,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/tmp": { "node_modules/tmp": {
"version": "0.2.3", "version": "0.2.4",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz",
"integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {

View File

@ -105,8 +105,17 @@ $cached = Cache::remember("online_$order", setting('core.online_cache_ttl') * 60
$result = null; $result = null;
$timestamp = false; $timestamp = false;
if($db->hasTable('server_record')) { if($db->hasTable('server_record')) {
$timestamp = true; $timestamp = $db->hasColumn('server_record', 'timestamp');
$result = ServerRecord::where('world_id', configLua('worldId'))->orderByDesc('record')->first()->toArray(); $serverRecordQuery = ServerRecord::query();
if ($db->hasColumn('server_record', 'world_id')) {
$serverRecordQuery->where('world_id', configLua('worldId'));
}
$result = $serverRecordQuery->orderByDesc('record')->first();
if ($result) {
$result = $result->toArray();
}
} else if($db->hasTable('server_config')) { // tfs 1.0 } else if($db->hasTable('server_config')) { // tfs 1.0
$row = ServerConfig::where('config', 'players_record')->first(); $row = ServerConfig::where('config', 'players_record')->first();
if ($row) { if ($row) {

View File

@ -1295,7 +1295,7 @@ Sent by MyAAC,<br/>
'name' => 'Data Center', 'name' => 'Data Center',
'type' => 'text', 'type' => 'text',
'desc' => 'Server Location, will be shown on online page', 'desc' => 'Server Location, will be shown on online page',
'default' => 'Frankfurt - Germany', 'default' => 'Poland - Warsaw',
], ],
[ [
'type' => 'section', 'type' => 'section',

View File

@ -45,6 +45,22 @@ class MigrateRunCommand extends Command
$down = $input->getOption('down') ?? false; $down = $input->getOption('down') ?? false;
/**
* Sort according to $down option.
* Do we really want it?
* Or should we use order provided by user,
* even when it's not sorted correctly?
* Leaving it for consideration.
*/
/*
if ($down) {
rsort($ids);
}
else {
sort($ids);
}
*/
foreach ($ids as $id) { foreach ($ids as $id) {
$this->executeMigration($id, $io, !$down); $this->executeMigration($id, $io, !$down);
} }

View File

@ -8,7 +8,7 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Style\SymfonyStyle;
class PluginInstallInstallCommand extends Command class PluginSetupCommand extends Command
{ {
protected function configure(): void protected function configure(): void
{ {

View File

@ -3,6 +3,7 @@
namespace MyAAC\Commands; namespace MyAAC\Commands;
use MyAAC\Models\Settings as SettingsModel; use MyAAC\Models\Settings as SettingsModel;
use MyAAC\Plugins;
use MyAAC\Settings; use MyAAC\Settings;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@ -34,7 +35,14 @@ class SettingsResetCommand extends Command
return Command::FAILURE; return Command::FAILURE;
} }
if (!$name) { // find by plugin name
foreach (Plugins::getAllPluginsSettings() as $key => $setting) {
if ($setting['pluginFilename'] === $name) {
$name = $key;
}
}
if (empty($name)) {
SettingsModel::truncate(); SettingsModel::truncate();
} }
else { else {

View File

@ -3,6 +3,7 @@
namespace MyAAC\Commands; namespace MyAAC\Commands;
use MyAAC\Models\Settings as SettingsModel; use MyAAC\Models\Settings as SettingsModel;
use MyAAC\Plugins;
use MyAAC\Settings; use MyAAC\Settings;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@ -17,7 +18,7 @@ class SettingsSetCommand extends Command
->setDescription('Updates the setting specified by argument in database') ->setDescription('Updates the setting specified by argument in database')
->addArgument('key', ->addArgument('key',
InputArgument::REQUIRED, InputArgument::REQUIRED,
'Setting name/key' 'Setting key in format name.key'
) )
->addArgument('value', ->addArgument('value',
InputArgument::REQUIRED, InputArgument::REQUIRED,
@ -34,6 +35,18 @@ class SettingsSetCommand extends Command
$key = $input->getArgument('key'); $key = $input->getArgument('key');
$value = $input->getArgument('value'); $value = $input->getArgument('value');
// format settings_name.key
// example: core.template
$explode = explode('.', $key);
// find by plugin name
foreach (Plugins::getAllPluginsSettings() as $_key => $setting) {
if ($setting['pluginFilename'] === $explode[0]) {
$explode[0] = $_key;
$key = implode('.', $explode);
}
}
$settings = Settings::getInstance(); $settings = Settings::getInstance();
$settings->clearCache(); $settings->clearCache();
$settings->load(); $settings->load();
@ -44,10 +57,6 @@ class SettingsSetCommand extends Command
return Command::FAILURE; return Command::FAILURE;
} }
// format plugin_name.key
// example: core.template
$explode = explode('.', $key);
$settings->updateInDatabase($explode[0], $explode[1], $value); $settings->updateInDatabase($explode[0], $explode[1], $value);
$settings->clearCache(); $settings->clearCache();

View File

@ -7,16 +7,13 @@ use MyAAC\Models\Settings as ModelsSettings;
class Settings implements \ArrayAccess class Settings implements \ArrayAccess
{ {
static private $instance; static private ?Settings $instance = null;
private $settingsFile = []; private array $settingsFile = [];
private $settingsDatabase = []; private array $settingsDatabase = [];
private $cache = []; private array $cache = [];
private $valuesAsked = []; private array $valuesAsked = [];
private $errors = []; private array $errors = [];
/**
* @return Settings
*/
public static function getInstance(): Settings public static function getInstance(): Settings
{ {
if (!self::$instance) { if (!self::$instance) {
@ -26,28 +23,21 @@ class Settings implements \ArrayAccess
return self::$instance; return self::$instance;
} }
public function load() public function load(): void
{ {
$cache = Cache::getInstance(); $this->settingsDatabase = Cache::remember('settings', 10 * 60, function () {
if ($cache->enabled()) { $settingsDatabase = [];
$tmp = '';
if ($cache->fetch('settings', $tmp)) {
$this->settingsDatabase = unserialize($tmp);
return;
}
}
$settings = ModelsSettings::all(); $settings = ModelsSettings::all();
foreach ($settings as $setting) { foreach ($settings as $setting) {
$this->settingsDatabase[$setting->name][$setting->key] = $setting->value; $settingsDatabase[$setting->name][$setting->key] = $setting->value;
} }
if ($cache->enabled()) { return $settingsDatabase;
$cache->set('settings', serialize($this->settingsDatabase), 600); });
}
} }
public function save($pluginName, $values) public function save($pluginName, $values): bool
{ {
$this->loadPlugin($pluginName); $this->loadPlugin($pluginName);
@ -104,7 +94,7 @@ class Settings implements \ArrayAccess
return true; return true;
} }
public function updateInDatabase($pluginName, $key, $value) public function updateInDatabase($pluginName, $key, $value): void
{ {
if (ModelsSettings::where(['name' => $pluginName, 'key' => $key])->exists()) { if (ModelsSettings::where(['name' => $pluginName, 'key' => $key])->exists()) {
ModelsSettings::where(['name' => $pluginName, 'key' => $key])->update(['value' => $value]); ModelsSettings::where(['name' => $pluginName, 'key' => $key])->update(['value' => $value]);
@ -117,7 +107,7 @@ class Settings implements \ArrayAccess
$this->clearCache(); $this->clearCache();
} }
public function deleteFromDatabase($pluginName, $key = null) public function deleteFromDatabase($pluginName, $key = null): void
{ {
if (!isset($key)) { if (!isset($key)) {
ModelsSettings::where('name', $pluginName)->delete(); ModelsSettings::where('name', $pluginName)->delete();
@ -217,7 +207,7 @@ class Settings implements \ArrayAccess
if (isset($setting['hidden']) && $setting['hidden']) { if (isset($setting['hidden']) && $setting['hidden']) {
$value = ''; $value = '';
if ($setting['type'] === 'boolean') { if ($setting['type'] === 'boolean') {
$value = ($setting['default'] ? 'true' : 'false'); $value = (getBoolean($setting['default']) ? 'true' : 'false');
} }
else if (in_array($setting['type'], ['text', 'number', 'float', 'double', 'email', 'password', 'textarea'])) { else if (in_array($setting['type'], ['text', 'number', 'float', 'double', 'email', 'password', 'textarea'])) {
$value = $setting['default']; $value = $setting['default'];
@ -230,12 +220,7 @@ class Settings implements \ArrayAccess
} }
else if ($setting['type'] === 'boolean') { else if ($setting['type'] === 'boolean') {
if(isset($settingsDb[$key])) { if(isset($settingsDb[$key])) {
if($settingsDb[$key] === 'true') { $value = getBoolean($settingsDb[$key]);
$value = true;
}
else {
$value = false;
}
} }
else { else {
$value = ($setting['default'] ?? false); $value = ($setting['default'] ?? false);
@ -383,7 +368,7 @@ class Settings implements \ArrayAccess
} }
#[\ReturnTypeWillChange] #[\ReturnTypeWillChange]
public function offsetSet($offset, $value) public function offsetSet($offset, $value): void
{ {
if (is_null($offset)) { if (is_null($offset)) {
throw new \RuntimeException("Settings: You cannot set empty offset with value: $value!"); throw new \RuntimeException("Settings: You cannot set empty offset with value: $value!");
@ -423,7 +408,7 @@ class Settings implements \ArrayAccess
} }
#[\ReturnTypeWillChange] #[\ReturnTypeWillChange]
public function offsetUnset($offset) public function offsetUnset($offset): void
{ {
$this->loadPlugin($offset); $this->loadPlugin($offset);
@ -455,7 +440,7 @@ class Settings implements \ArrayAccess
* @return array|mixed * @return array|mixed
*/ */
#[\ReturnTypeWillChange] #[\ReturnTypeWillChange]
public function offsetGet($offset) public function offsetGet($offset): mixed
{ {
// try cache hit // try cache hit
if(isset($this->cache[$offset])) { if(isset($this->cache[$offset])) {
@ -521,7 +506,7 @@ class Settings implements \ArrayAccess
return $ret; return $ret;
} }
private function updateValuesAsked($offset) private function updateValuesAsked($offset): void
{ {
$pluginKeyName = $offset; $pluginKeyName = $offset;
if (strpos($offset, '.')) { if (strpos($offset, '.')) {
@ -537,7 +522,7 @@ class Settings implements \ArrayAccess
} }
} }
private function loadPlugin($offset) private function loadPlugin($offset): void
{ {
$this->updateValuesAsked($offset); $this->updateValuesAsked($offset);
@ -566,7 +551,7 @@ class Settings implements \ArrayAccess
} }
} }
public static function saveConfig($config, $filename, &$content = '') public static function saveConfig($config, $filename, &$content = ''): bool|int
{ {
$content = "<?php" . PHP_EOL; $content = "<?php" . PHP_EOL;

View File

@ -148,7 +148,7 @@ function get_template_menus(): array
{ {
global $template_name; global $template_name;
$result = Cache::remember('template_menus', 10 * 60, function () use ($template_name) { $result = Cache::remember('template_menus_' . $template_name, 10 * 60, function () use ($template_name) {
$result = Menu::select(['name', 'link', 'blank', 'color', 'category']) $result = Menu::select(['name', 'link', 'blank', 'color', 'category'])
->where('template', $template_name) ->where('template', $template_name)
->orderBy('category') ->orderBy('category')

View File

@ -90,7 +90,7 @@
</td> </td>
</tr> </tr>
{% if setting('core.online_record') %} {% if setting('core.online_record') and record|length > 0 %}
<tr> <tr>
<td class="LabelV150"><b>Online Record:</b></td> <td class="LabelV150"><b>Online Record:</b></td>
<td> <td>
@ -161,7 +161,7 @@
{% endif %} {% endif %}
<td style="width:70%; text-align:left"> <td style="width:70%; text-align:left">
{{ player.name|raw }}{{ player.skull }} {{ player.name|raw }}{{ player.skull|raw }}
</td> </td>
<td style="width:10%">{{ player.level }}</td> <td style="width:10%">{{ player.level }}</td>
<td style="width:20%">{{ player.vocation }}</td> <td style="width:20%">{{ player.vocation }}</td>

View File

@ -164,6 +164,10 @@ if(isset($config['boxes']))
function InitializeMenu() function InitializeMenu()
{ {
for(menuItemName in menu[0]) { for(menuItemName in menu[0]) {
if (!document.getElementById(menuItemName+"_Submenu")) {
continue;
}
if(menu[0][menuItemName] == "0") { if(menu[0][menuItemName] == "0") {
document.getElementById(menuItemName+"_Submenu").style.visibility = "hidden"; document.getElementById(menuItemName+"_Submenu").style.visibility = "hidden";
document.getElementById(menuItemName+"_Submenu").style.display = "none"; document.getElementById(menuItemName+"_Submenu").style.display = "none";
@ -387,7 +391,7 @@ foreach($config['menu_categories'] as $id => $cat) {
?> ?>
</div> </div>
<?php <?php
if($id == MENU_CATEGORY_SHOP || (!setting('core.gifts_system') && $i == $countElements)) { if ($i == $countElements) {
?> ?>
<div id='MenuBottom' style='background-image:url(<?php echo $template_path; ?>/images/general/box-bottom.gif);'></div> <div id='MenuBottom' style='background-image:url(<?php echo $template_path; ?>/images/general/box-bottom.gif);'></div>
<?php <?php