diff --git a/CHANGELOG-1.x.md b/CHANGELOG-1.x.md
index 4c231dad..3efc7ad7 100644
--- a/CHANGELOG-1.x.md
+++ b/CHANGELOG-1.x.md
@@ -1,5 +1,18 @@
# Changelog
+## [1.8.9 - 06.04.2026]
+### Added
+* Settings: Possibility to add custom HTML for the head and body tags like Google Analytics code etc. (https://github.com/slawkens/myaac/commit/108e83806df5686a06826931ed5e243c19cbe130)
+* Add command: give-admin (https://github.com/slawkens/myaac/commit/9fa9ec746c4b344387a21f21886c2251319806fc)
+ * Usage: php aac give:admin slawkens@gmail.com
+ Parameter: account email, name or id
+ * It's admin for the website, not the GM for the game! For that, go into the admin panel and change the group manually
+* Add page load time to an Admin Panel footer (https://github.com/slawkens/myaac/commit/4ae2fdd0dfcd56697612395c14aecc2dfd33b1c3)
+
+### Changed
+* Better character name validation, like in the original game website (#356)
+* Install: don't suggest deleting of install folder - it's not required (https://github.com/slawkens/myaac/commit/5fcde4708a39255cf68edc8c43f2ac6597e2601d)
+
## [1.8.8 - 31.01.2026]
### Added
* Change Comment: Add missing hooks - patched from 0.8 (https://github.com/slawkens/myaac/commit/a60a23b84f61d41d1503073b52e01e3120f6d92a)
diff --git a/admin/template/template.php b/admin/template/template.php
index cdb20519..318e14f1 100644
--- a/admin/template/template.php
+++ b/admin/template/template.php
@@ -172,7 +172,8 @@
-
+ = base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?>
+ = 'Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.'; ?>
diff --git a/login.php b/login.php
index 438754e2..8f821ba0 100644
--- a/login.php
+++ b/login.php
@@ -93,9 +93,9 @@ switch ($action) {
$creatureBoost = $db->query("SELECT * FROM " . $db->tableName('boosted_creature'))->fetchAll();
$bossBoost = $db->query("SELECT * FROM " . $db->tableName('boosted_boss'))->fetchAll();
die(json_encode([
- 'boostedcreature' => true,
+ //'boostedcreature' => true,
+ 'bossraceid' => intval($bossBoost[0]['raceid']),
'creatureraceid' => intval($creatureBoost[0]['raceid']),
- 'bossraceid' => intval($bossBoost[0]['raceid'])
]));
}
diff --git a/package-lock.json b/package-lock.json
index 901e9c59..2a675da8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1431,9 +1431,9 @@
}
},
"node_modules/lodash": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
- "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"dev": true,
"license": "MIT"
},
diff --git a/system/pages/account/create.php b/system/pages/account/create.php
index 5d9edf59..093c2707 100644
--- a/system/pages/account/create.php
+++ b/system/pages/account/create.php
@@ -171,7 +171,7 @@ if($save)
}
if(setting('core.account_create_character_create')) {
- $character_name = isset($_POST['name']) ? stripslashes(ucwords(strtolower($_POST['name']))) : null;
+ $character_name = isset($_POST['name']) ? trim(stripslashes($_POST['name'])) : null;
$character_sex = isset($_POST['sex']) ? (int)$_POST['sex'] : null;
$character_vocation = isset($_POST['vocation']) ? (int)$_POST['vocation'] : null;
$character_town = isset($_POST['town']) ? (int)$_POST['town'] : null;
diff --git a/system/src/Commands/GiveAdminCommand.php b/system/src/Commands/GiveAdminCommand.php
index d2565783..61070a95 100644
--- a/system/src/Commands/GiveAdminCommand.php
+++ b/system/src/Commands/GiveAdminCommand.php
@@ -39,7 +39,7 @@ class GiveAdminCommand extends Command
}
if (!$account->isLoaded()) {
- $io->error('Cannot find account mit supplied parameter: ' . $accountParam);
+ $io->error('Cannot find account with supplied parameter: ' . $accountParam);
return self::FAILURE;
}
diff --git a/system/src/Hooks.php b/system/src/Hooks.php
index 8dac8eda..75ad0fe4 100644
--- a/system/src/Hooks.php
+++ b/system/src/Hooks.php
@@ -14,6 +14,26 @@ class Hooks
self::$_hooks[$hook->type()][] = $hook;
}
+ public function unregister($name, $type, $file): void
+ {
+ if (is_string($type)) {
+ $type = constant($type);
+ }
+
+ if(!isset(self::$_hooks[$type])) {
+ return;
+ }
+
+ foreach(self::$_hooks[$type] as $id => $hook) {
+ if($name == $hook->name()
+ && $type == $hook->type()
+ && $file == $hook->file()
+ ) {
+ unset(self::$_hooks[$type][$id]);
+ }
+ }
+ }
+
public function trigger($type, $params = []): bool
{
$ret = true;
diff --git a/system/src/Plugins.php b/system/src/Plugins.php
index c6651679..6a88fcab 100644
--- a/system/src/Plugins.php
+++ b/system/src/Plugins.php
@@ -868,6 +868,11 @@ class Plugins {
}
}
+ global $hooks;
+ foreach($plugin_info['hooks'] ?? [] as $name => $info) {
+ $hooks->unregister($name, $info['type'], $info['file']);
+ }
+
clearCache();
return true;
}
diff --git a/system/src/Validator.php b/system/src/Validator.php
index 7261454e..8857f07b 100644
--- a/system/src/Validator.php
+++ b/system/src/Validator.php
@@ -183,7 +183,7 @@ class Validator
return false;
}
- // installer doesn't know config.php yet
+ // installer doesn't know settings yet
// that's why we need to ignore the nulls
if(defined('MYAAC_INSTALL')) {
$minLength = 4;
@@ -207,21 +207,15 @@ class Validator
return false;
}
- if(strspn($name, "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM- [ ] '") != $length)
+ if(strspn($name, "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM ") != $length)
{
- self::$lastError = "Invalid name format. Use only A-Z, spaces and '.";
+ self::$lastError = "This name contains invalid letters. Please use only A-Z, a-z and space!";
return false;
}
if(preg_match('/ {2,}/', $name))
{
- self::$lastError = 'Invalid character name format. Use only A-Z and no double spaces.';
- return false;
- }
-
- if(!preg_match("/[A-z ']/", $name))
- {
- self::$lastError = "Invalid name format. Use only A-Z, spaces and '.";
+ self::$lastError = 'Invalid character name format. Use only A-Z, a-z and no double spaces.';
return false;
}
@@ -230,17 +224,23 @@ class Validator
/**
* Validate new character name.
- * Name lenght must be 3-25 chars
+ * Name length must be 3-25 chars
*
* @param string $name Name to check
* @return bool Is name valid?
*/
public static function newCharacterName($name)
{
- global $db, $config;
+ global $db;
+ $name = trim($name);
$name_lower = strtolower($name);
+ if(strlen($name) < 1) {
+ self::$lastError = 'Please enter a name.';
+ return false;
+ }
+
$first_words_blocked = array_merge(["'", '-'], setting('core.create_character_name_blocked_prefix'));
foreach($first_words_blocked as $word) {
if($word == substr($name_lower, 0, strlen($word))) {
@@ -249,11 +249,6 @@ class Validator
}
}
- if(str_ends_with($name_lower, "'") || str_ends_with($name_lower, "-")) {
- self::$lastError = 'Your name contains illegal characters.';
- return false;
- }
-
if(substr($name_lower, 1, 1) == ' ') {
self::$lastError = 'Your name contains illegal space.';
return false;
@@ -265,11 +260,36 @@ class Validator
}
if(preg_match('/ {2,}/', $name)) {
- self::$lastError = 'Invalid character name format. Use only A-Z and numbers 0-9 and no double spaces.';
+ self::$lastError = 'Invalid character name format. Use only A-Z and no double spaces.';
return false;
}
- if(strtolower($config['lua']['serverName']) == $name_lower) {
+ if (substr($name[0], 0, 1) !== strtoupper(substr($name[0], 0, 1))) {
+ self::$lastError = 'The first letter of a name has to be a capital letter.';
+ return false;
+ }
+
+ foreach (explode(' ', $name) as $word) {
+ $wordCut = substr($word, 1, strlen($word));
+ $hasUpperCase = preg_match('/[A-Z]/', $wordCut);
+ if ($hasUpperCase) {
+ self::$lastError = 'In names capital letters are only allowed at the beginning of a word.';
+ return false;
+ }
+
+ if (strlen($word) == 1) {
+ self::$lastError = 'This name contains a word with only one letter. Please use more than one letter for each word.';
+ return false;
+ }
+
+ $hasVowel = preg_match('/[aeiouAEIOU]/', $word);
+ if (!$hasVowel) {
+ self::$lastError = 'This name contains a word without vowels. Please choose another name.';
+ return false;
+ }
+ }
+
+ if(strtolower(configLua('serverName')) == $name_lower) {
self::$lastError = 'Your name cannot be same as server name.';
return false;
}
diff --git a/tools/validate.php b/tools/validate.php
index 66b39581..bf362131 100644
--- a/tools/validate.php
+++ b/tools/validate.php
@@ -63,10 +63,7 @@ else if(isset($_GET['email']))
}
else if(isset($_GET['name']))
{
- $name = $_GET['name'];
- if(!admin()) {
- $name = strtolower(stripslashes($name));
- }
+ $name = trim(stripslashes($_GET['name']));
if(!Validator::characterName($name)) {
error_(Validator::getLastError());
@@ -81,7 +78,12 @@ else if(isset($_GET['name']))
error_($errors['name']);
}
- success_('Good. Your name will be:
' . (admin() ? $name : ucwords($name)) . '');
+ $extraText = '';
+ if (admin()) {
+ $extraText = "
Note: You are logged in as admin, so you can create almost any name without rules.";
+ }
+
+ success_("Good. Your name will be:
$name$extraText");
}
else if(isset($_GET['password']) && isset($_GET['password_confirm'])) {
$password = $_GET['password'];