mirror of
https://github.com/slawkens/myaac.git
synced 2025-12-15 05:19:47 +01:00
Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5d3d3a25f | ||
|
|
9ed06782e6 | ||
|
|
18a1178e4b | ||
|
|
c86257e6da | ||
|
|
fd74f01291 | ||
|
|
3011b969a4 | ||
|
|
8e6749c599 | ||
|
|
e1197515f3 | ||
|
|
ae5df2b704 | ||
|
|
9c327336d3 | ||
|
|
1d21f4d682 | ||
|
|
603d860b56 | ||
|
|
6775a061be | ||
|
|
eebfc600cb | ||
|
|
9a99018dce | ||
|
|
e440c0d6a6 | ||
|
|
780d4ccef7 | ||
|
|
0a6d44bf21 | ||
|
|
4d17001a0b | ||
|
|
946364f59d | ||
|
|
5861efdbe9 | ||
|
|
175e97828b | ||
|
|
9ce55db44c | ||
|
|
88532b0ebb | ||
|
|
1c7af30997 | ||
|
|
7ca05e47ff | ||
|
|
baec6c9ebf | ||
|
|
6367054487 | ||
|
|
ae7a47464f | ||
|
|
d201e75b11 | ||
|
|
4924696943 | ||
|
|
25a3db68e6 | ||
|
|
730a0f2912 | ||
|
|
fd729242ff | ||
|
|
6479546c22 | ||
|
|
effb23f367 | ||
|
|
08657c1599 | ||
|
|
1379c93439 | ||
|
|
19b1cfdd34 | ||
|
|
26c5aa2e51 | ||
|
|
bc4107bd16 | ||
|
|
d24bde2c1d | ||
|
|
e719725841 | ||
|
|
bb3e90110d | ||
|
|
2f0758e351 | ||
|
|
6667c8c364 | ||
|
|
c13a540878 | ||
|
|
869ec035d9 | ||
|
|
9d696d31d8 | ||
|
|
8cc4caf587 | ||
|
|
e1d1c7d5db | ||
|
|
320733c2c1 | ||
|
|
c1809a98d1 | ||
|
|
46ed541015 | ||
|
|
29207361b7 | ||
|
|
25013ae91b | ||
|
|
5d630ba9dd | ||
|
|
feadf1314d | ||
|
|
08b8a716d4 | ||
|
|
cc26b5c744 | ||
|
|
cb6e9a6a88 | ||
|
|
4adb0758c5 | ||
|
|
7312383f73 | ||
|
|
3c1210fefa |
2
.github/workflows/cypress.yml
vendored
2
.github/workflows/cypress.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
php-versions: [ '8.1', '8.2', '8.3', '8.4' ]
|
php-versions: [ '8.1', '8.2', '8.3', '8.4', '8.5' ]
|
||||||
ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration)
|
ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration)
|
||||||
name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }})
|
name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }})
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,7 +4,7 @@ Thumbs.db
|
|||||||
|
|
||||||
#
|
#
|
||||||
/.htaccess
|
/.htaccess
|
||||||
lua
|
/lua
|
||||||
|
|
||||||
# composer
|
# composer
|
||||||
composer.phar
|
composer.phar
|
||||||
@@ -24,6 +24,7 @@ releases
|
|||||||
tmp
|
tmp
|
||||||
|
|
||||||
config.local.php
|
config.local.php
|
||||||
|
config2.local.php
|
||||||
|
|
||||||
# all custom templates
|
# all custom templates
|
||||||
templates/*
|
templates/*
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
# Changelog
|
# 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]
|
## [1.8.4 - 27.10.2025]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
4
CHANGELOG-2.x.md
Normal file
4
CHANGELOG-2.x.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
## [2.0-dev - x.x.2025]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* Reworked account action logs to use single IP column as varchar(45) for both ipv4 and ipv6 (https://github.com/slawkens/myaac/pull/289)
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use MyAAC\Models\Account as AccountModel;
|
use MyAAC\Models\Account as AccountModel;
|
||||||
|
use MyAAC\Models\AccountAction;
|
||||||
use MyAAC\Models\Player;
|
use MyAAC\Models\Player;
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
defined('MYAAC') or die('Direct access not allowed!');
|
||||||
@@ -481,9 +482,8 @@ else if (isset($_REQUEST['search'])) {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
$accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
|
$accountActions = AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
|
||||||
foreach ($accountActions as $i => $log):
|
foreach ($accountActions as $i => $log):
|
||||||
$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6));
|
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?php echo $i + 1; ?></td>
|
<td><?php echo $i + 1; ?></td>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ usort($menus, function ($a, $b) {
|
|||||||
|
|
||||||
foreach ($menus as $i => $menu) {
|
foreach ($menus as $i => $menu) {
|
||||||
if (isset($menu['link']) && is_array($menu['link'])) {
|
if (isset($menu['link']) && is_array($menu['link'])) {
|
||||||
usort($menus[$i]['link'], function ($a, $b) {
|
usort($menu['link'], function ($a, $b) {
|
||||||
return $a['order'] - $b['order'];
|
return $a['order'] - $b['order'];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ require SYSTEM . 'login.php';
|
|||||||
|
|
||||||
if(!admin()) {
|
if(!admin()) {
|
||||||
http_response_code(500);
|
http_response_code(500);
|
||||||
die('Access denied.');
|
die('You are not logged in. Probably session expired. Please login again.');
|
||||||
}
|
}
|
||||||
|
|
||||||
csrfProtect();
|
csrfProtect();
|
||||||
@@ -40,3 +40,6 @@ if (count($errors) > 0) {
|
|||||||
if ($success) {
|
if ($success) {
|
||||||
echo 'Saved at ' . date('H:i');
|
echo 'Saved at ' . date('H:i');
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
echo 'Something unexpected happened - it was impossible to save the settings, please try again later. If problem persists - contact MyAAC developers.';
|
||||||
|
}
|
||||||
|
|||||||
17
common.php
17
common.php
@@ -26,8 +26,8 @@
|
|||||||
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
|
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
|
||||||
|
|
||||||
const MYAAC = true;
|
const MYAAC = true;
|
||||||
const MYAAC_VERSION = '1.8.4';
|
const MYAAC_VERSION = '2.0-dev';
|
||||||
const DATABASE_VERSION = 46;
|
const DATABASE_VERSION = 47;
|
||||||
const TABLE_PREFIX = 'myaac_';
|
const TABLE_PREFIX = 'myaac_';
|
||||||
define('START_TIME', microtime(true));
|
define('START_TIME', microtime(true));
|
||||||
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
|
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
|
||||||
@@ -148,16 +148,17 @@ if(!IS_CLI) {
|
|||||||
|
|
||||||
/** @var array $config */
|
/** @var array $config */
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
if(@$config['env'] === 'dev' || defined('MYAAC_INSTALL')) {
|
if(isset($config['env']) && $config['env'] !== 'dev' && !defined('MYAAC_INSTALL')) {
|
||||||
ini_set('display_errors', 1);
|
|
||||||
ini_set('display_startup_errors', 1);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('display_startup_errors', 0);
|
ini_set('display_startup_errors', 0);
|
||||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
|
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ini_set('html_errors', 0);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
$autoloadFile = VENDOR . 'autoload.php';
|
$autoloadFile = VENDOR . 'autoload.php';
|
||||||
if (!is_file($autoloadFile)) {
|
if (!is_file($autoloadFile)) {
|
||||||
|
|||||||
BIN
images/facebook_16x16.png
Normal file
BIN
images/facebook_16x16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 718 B |
BIN
images/instagram_16x16.png
Normal file
BIN
images/instagram_16x16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 721 B |
BIN
images/whatsapp_16x16.png
Normal file
BIN
images/whatsapp_16x16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 688 B |
@@ -1,11 +1,11 @@
|
|||||||
CREATE TABLE IF NOT EXISTS `myaac_account_actions`
|
CREATE TABLE IF NOT EXISTS `myaac_account_actions`
|
||||||
(
|
(
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
`account_id` int NOT NULL,
|
`account_id` int NOT NULL,
|
||||||
`ip` int unsigned NOT NULL DEFAULT 0,
|
`ip` varchar(45) NOT NULL DEFAULT '',
|
||||||
`ipv6` binary(16) NOT NULL DEFAULT 0,
|
|
||||||
`date` int NOT NULL DEFAULT 0,
|
`date` int NOT NULL DEFAULT 0,
|
||||||
`action` varchar(255) NOT NULL DEFAULT '',
|
`action` varchar(255) NOT NULL DEFAULT '',
|
||||||
KEY (`account_id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `myaac_account_emails_verify`
|
CREATE TABLE IF NOT EXISTS `myaac_account_emails_verify`
|
||||||
|
|||||||
@@ -433,16 +433,22 @@ function delete_guild($id)
|
|||||||
$rank_list->orderBy('level');
|
$rank_list->orderBy('level');
|
||||||
|
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
$deletedColumn = 'deleted';
|
||||||
|
if ($db->hasColumn('players', 'deletion')) {
|
||||||
|
$deletedColumn = 'deletion';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var OTS_GuildRank $rank_in_guild
|
* @var OTS_GuildRank $rank_in_guild
|
||||||
*/
|
*/
|
||||||
foreach($rank_list as $rank_in_guild) {
|
foreach($rank_list as $rank_in_guild) {
|
||||||
if($db->hasTable('guild_members'))
|
if($db->hasTable('guild_members'))
|
||||||
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` 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'))
|
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
|
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();
|
$players_with_rank_number = $players_with_rank->rowCount();
|
||||||
if($players_with_rank_number > 0) {
|
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)) {
|
if(!file_exists($dir)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1203,6 +1210,21 @@ function deleteDirectory($dir, $ignore = array(), $contentOnly = false) {
|
|||||||
return rmdir($dir);
|
return rmdir($dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureFolderExists($dir): void
|
||||||
|
{
|
||||||
|
if (!file_exists($dir)) {
|
||||||
|
mkdir($dir, 0777, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureIndexExists($dir): void
|
||||||
|
{
|
||||||
|
$dir = rtrim($dir, '/');
|
||||||
|
if (!file_exists($file = $dir . '/index.html')) {
|
||||||
|
touch($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function config($key) {
|
function config($key) {
|
||||||
global $config;
|
global $config;
|
||||||
if (is_array($key)) {
|
if (is_array($key)) {
|
||||||
@@ -1712,6 +1734,43 @@ function isCanary(): bool
|
|||||||
return isset($vipSystemEnabled);
|
return isset($vipSystemEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStatusUptimeReadable(int $uptime): string
|
||||||
|
{
|
||||||
|
$fullMinute = 60;
|
||||||
|
$fullHour = (60 * $fullMinute);
|
||||||
|
$fullDay = (24 * $fullHour);
|
||||||
|
$fullMonth = (30 * $fullDay);
|
||||||
|
$fullYear = (365 * $fullDay);
|
||||||
|
|
||||||
|
// years
|
||||||
|
$years = floor($uptime / $fullYear);
|
||||||
|
$y = ($years > 1 ? "$years years, " : ($years == 1 ? 'year, ' : ''));
|
||||||
|
|
||||||
|
$uptime -= $years * $fullYear;
|
||||||
|
|
||||||
|
// months
|
||||||
|
$months = floor($uptime / $fullMonth);
|
||||||
|
$m = ($months > 1 ? "$months months, " : ($months == 1 ? 'month, ' : ''));
|
||||||
|
|
||||||
|
$uptime -= $months * $fullMonth;
|
||||||
|
|
||||||
|
// days
|
||||||
|
$days = floor($uptime / $fullDay);
|
||||||
|
$d = ($days > 1 ? "$days days, " : ($days == 1 ? 'day, ' : ''));
|
||||||
|
|
||||||
|
$uptime -= $days * $fullDay;
|
||||||
|
|
||||||
|
// hours
|
||||||
|
$hours = floor($uptime / $fullHour);
|
||||||
|
|
||||||
|
$uptime -= $hours * $fullHour;
|
||||||
|
|
||||||
|
// minutes
|
||||||
|
$min = floor($uptime / $fullMinute);
|
||||||
|
|
||||||
|
return "{$y}{$m}{$d}{$hours}h {$min}m";
|
||||||
|
}
|
||||||
|
|
||||||
// validator functions
|
// validator functions
|
||||||
require_once SYSTEM . 'compat/base.php';
|
require_once SYSTEM . 'compat/base.php';
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ use MyAAC\Settings;
|
|||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
defined('MYAAC') or die('Direct access not allowed!');
|
||||||
|
|
||||||
|
ensureIndexExists(CACHE);
|
||||||
|
ensureIndexExists(CACHE . 'twig/');
|
||||||
|
|
||||||
global $config;
|
global $config;
|
||||||
if(!isset($config['installed']) || !$config['installed']) {
|
if(!isset($config['installed']) || !$config['installed']) {
|
||||||
throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.');
|
throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.');
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
|
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use MyAAC\Models\AccountAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OTServ account abstraction.
|
* OTServ account abstraction.
|
||||||
*
|
*
|
||||||
@@ -1007,26 +1009,16 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
|||||||
|
|
||||||
public function logAction($action)
|
public function logAction($action)
|
||||||
{
|
{
|
||||||
$ip = get_browser_real_ip();
|
AccountAction::create([
|
||||||
if(!str_contains($ip, ":")) {
|
'account_id' => $this->getId(),
|
||||||
$ipv6 = '0';
|
'ip' => get_browser_real_ip(),
|
||||||
}
|
'date' => time(),
|
||||||
else {
|
'action' => $action,
|
||||||
$ipv6 = $ip;
|
]);
|
||||||
$ip = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->db->exec('INSERT INTO `' . TABLE_PREFIX . 'account_actions` (`account_id`, `ip`, `ipv6`, `date`, `action`) VALUES (' . $this->db->quote($this->getId()).', ' . ($ip == '' ? '0' : $this->db->quote(ip2long($ip))) . ', (' . ($ipv6 == '0' ? $this->db->quote('') : $this->db->quote(inet_pton($ipv6))) . '), UNIX_TIMESTAMP(NOW()), ' . $this->db->quote($action).')');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getActionsLog($limit1, $limit2)
|
public function getActionsLog($limit) {
|
||||||
{
|
return AccountAction::where('account_id', $this->data['id'])->orderByDesc('date')->limit($limit)->get()->toArray();
|
||||||
$actions = array();
|
|
||||||
|
|
||||||
foreach($this->db->query('SELECT `ip`, `ipv6`, `date`, `action` FROM `' . TABLE_PREFIX . 'account_actions` WHERE `account_id` = ' . $this->data['id'] . ' ORDER by `date` DESC LIMIT ' . $limit1 . ', ' . $limit2 . '')->fetchAll() as $a)
|
|
||||||
$actions[] = array('ip' => $a['ip'], 'ipv6' => $a['ipv6'], 'date' => $a['date'], 'action' => $a['action']);
|
|
||||||
|
|
||||||
return $actions;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Returns players iterator.
|
* Returns players iterator.
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ class OTS_DB_MySQL extends OTS_Base_DB
|
|||||||
'field' => $result['Field'],
|
'field' => $result['Field'],
|
||||||
'type' => $result['Type'],
|
'type' => $result['Type'],
|
||||||
'null' => strtolower($result['Null']),
|
'null' => strtolower($result['Null']),
|
||||||
|
'key' => strtolower($result['Key'] ?? ''),
|
||||||
'default' => $result['Default'],
|
'default' => $result['Default'],
|
||||||
'extra' => $result['Extra'],
|
'extra' => $result['Extra'],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ class OTS_ServerInfo
|
|||||||
return new OTS_Buffer($data);
|
return new OTS_Buffer($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_append('status-error.log', "Cannot connect to {$this->server}:{$this->port} - Error code: $error, message: $message");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
system/migrations/47.php
Normal file
42
system/migrations/47.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @var OTS_DB_MySQL $db
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 2025-02-27
|
||||||
|
// remove ipv6, change to ip (for both ipv4 + ipv6) as VARCHAR(45)
|
||||||
|
$up = function () use ($db) {
|
||||||
|
$accountActionsInfo = $db->getColumnInfo(TABLE_PREFIX . 'account_actions', 'account_id');
|
||||||
|
if ($accountActionsInfo && is_array($accountActionsInfo) && $accountActionsInfo['key'] == 'pri') {
|
||||||
|
$db->query("ALTER TABLE `myaac_account_actions` DROP KEY `account_id`;");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$db->hasColumn(TABLE_PREFIX . 'account_actions', 'id')) {
|
||||||
|
$db->addColumn(TABLE_PREFIX . 'account_actions', 'id', 'INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`)');
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->modifyColumn(TABLE_PREFIX . 'account_actions', 'ip', "VARCHAR(45) NOT NULL DEFAULT ''");
|
||||||
|
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET_NTOA(`ip`) WHERE `ip` != '0';");
|
||||||
|
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET6_NTOA(`ipv6`) WHERE `ip` = '0';");
|
||||||
|
|
||||||
|
if ($db->hasColumn(TABLE_PREFIX . 'account_actions', 'ipv6')) {
|
||||||
|
$db->dropColumn(TABLE_PREFIX . 'account_actions', 'ipv6');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$down = function () use ($db) {
|
||||||
|
if ($db->hasColumn(TABLE_PREFIX . 'account_actions', 'id')) {
|
||||||
|
$db->query("ALTER TABLE `" . TABLE_PREFIX . "account_actions` DROP `id`;");
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->query("ALTER TABLE `" . TABLE_PREFIX . "account_actions` ADD KEY (`account_id`);");
|
||||||
|
|
||||||
|
if (!$db->hasColumn(TABLE_PREFIX . 'account_actions', 'ipv6')) {
|
||||||
|
$db->addColumn(TABLE_PREFIX . 'account_actions', 'ipv6', "BINARY(16) NOT NULL DEFAULT 0x00000000000000000000000000000000 AFTER ip");
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ipv6` = INET6_ATON(ip) WHERE NOT IS_IPV4(`ip`);");
|
||||||
|
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = INET_ATON(`ip`) WHERE IS_IPV4(`ip`);");
|
||||||
|
$db->query("UPDATE `" . TABLE_PREFIX . "account_actions` SET `ip` = 0 WHERE `ipv6` != 0x00000000000000000000000000000000;");
|
||||||
|
$db->modifyColumn(TABLE_PREFIX . 'account_actions', 'ip', "INT(11) UNSIGNED NOT NULL DEFAULT 0;");
|
||||||
|
};
|
||||||
@@ -9,7 +9,7 @@ $up = function () use ($db) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$up = function () use ($db) {
|
$down = function () use ($db) {
|
||||||
if (!$db->hasColumn(TABLE_PREFIX . 'screenshots', 'name')) {
|
if (!$db->hasColumn(TABLE_PREFIX . 'screenshots', 'name')) {
|
||||||
$db->addColumn(TABLE_PREFIX . 'screenshots', 'name', 'VARCHAR(30) NOT NULL');
|
$db->addColumn(TABLE_PREFIX . 'screenshots', 'name', 'VARCHAR(30) NOT NULL');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ if(!empty($errors))
|
|||||||
|
|
||||||
if (setting('core.account_country')) {
|
if (setting('core.account_country')) {
|
||||||
$countries = array();
|
$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[$c] = $config['countries'][$c];
|
||||||
|
|
||||||
$countries['--'] = '----------';
|
$countries['--'] = '----------';
|
||||||
|
|||||||
@@ -96,12 +96,8 @@ if($email_new_time > 1)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$actions = array();
|
$actions = $account_logged->getActionsLog(1000);
|
||||||
foreach($account_logged->getActionsLog(0, 1000) as $action) {
|
|
||||||
$actions[] = array('action' => $action['action'], 'date' => $action['date'], 'ip' => $action['ip'] != 0 ? long2ip($action['ip']) : inet_ntop($action['ipv6']));
|
|
||||||
}
|
|
||||||
|
|
||||||
$players = array();
|
|
||||||
/** @var OTS_Players_List $account_players */
|
/** @var OTS_Players_List $account_players */
|
||||||
$account_players = $account_logged->getPlayersList();
|
$account_players = $account_logged->getPlayersList();
|
||||||
$account_players->orderBy('id');
|
$account_players->orderBy('id');
|
||||||
|
|||||||
@@ -202,36 +202,38 @@ if($player->isLoaded() && !$player->isDeleted())
|
|||||||
unset($storage);
|
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)');
|
$eq_sql = $db->query('SELECT `pid`, `itemtype` FROM player_items WHERE player_id = '.$player->getId().' AND (`pid` >= 1 and `pid` <= 10)');
|
||||||
$equipment = array();
|
$equipment = [];
|
||||||
foreach($eq_sql as $eq)
|
foreach($eq_sql as $eq) {
|
||||||
$equipment[$eq['pid']] = $eq['itemtype'];
|
$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");
|
$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++)
|
|
||||||
{
|
for($i = 0; $i <= 10; $i++) {
|
||||||
if(!isset($equipment[$i]) || $equipment[$i] == 0)
|
if(!isset($equipment[$i]) || $equipment[$i] == 0)
|
||||||
$equipment[$i] = $empty_slots[$i];
|
$equipment[$i] = $empty_slots[$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for($i = 1; $i < 11; $i++)
|
for($i = 1; $i < 11; $i++) {
|
||||||
{
|
if(Validator::number($equipment[$i])) {
|
||||||
if(Validator::number($equipment[$i]))
|
|
||||||
$equipment[$i] = getItemImage($equipment[$i]);
|
$equipment[$i] = getItemImage($equipment[$i]);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
$equipment[$i] = '<img src="images/items/' . $equipment[$i] . '.gif" width="32" height="32" border="0" alt=" ' . $equipment[$i] . '" />';
|
$equipment[$i] = '<img src="images/items/' . $equipment[$i] . '.gif" width="32" height="32" border="0" alt=" ' . $equipment[$i] . '" />';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$skulls = array(
|
|
||||||
1 => 'yellow_skull',
|
|
||||||
2 => 'green_skull',
|
|
||||||
3 => 'white_skull',
|
|
||||||
4 => 'red_skull',
|
|
||||||
5 => 'black_skull'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$skulls = [
|
||||||
|
1 => 'yellow_skull',
|
||||||
|
2 => 'green_skull',
|
||||||
|
3 => 'white_skull',
|
||||||
|
4 => 'red_skull',
|
||||||
|
5 => 'black_skull',
|
||||||
|
];
|
||||||
|
|
||||||
$dead_add_content = '';
|
$dead_add_content = '';
|
||||||
$deaths = array();
|
$deaths = array();
|
||||||
if($db->hasTable('killers')) {
|
if($db->hasTable('killers')) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ if(!$logged) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$configLuaFreePremium = configLua('freePremium');
|
$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();
|
$array_of_player_nig = array();
|
||||||
if(empty($errors))
|
if(empty($errors))
|
||||||
|
|||||||
@@ -91,13 +91,18 @@ $guild_owner = $guild->getOwner();
|
|||||||
if($guild_owner->isLoaded())
|
if($guild_owner->isLoaded())
|
||||||
$guild_owner_name = $guild_owner->getName();
|
$guild_owner_name = $guild_owner->getName();
|
||||||
|
|
||||||
|
$deletedColumn = 'deleted';
|
||||||
|
if ($db->hasColumn('players', 'deletion')) {
|
||||||
|
$deletedColumn = 'deletion';
|
||||||
|
}
|
||||||
|
|
||||||
$guild_members = array();
|
$guild_members = array();
|
||||||
foreach($rank_list as $rank)
|
foreach($rank_list as $rank)
|
||||||
{
|
{
|
||||||
if($db->hasTable(GUILD_MEMBERS_TABLE))
|
if($db->hasTable(GUILD_MEMBERS_TABLE))
|
||||||
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `' . GUILD_MEMBERS_TABLE . '`.`rank_id` as `rank_id` FROM `players`, `' . GUILD_MEMBERS_TABLE . '` WHERE `' . GUILD_MEMBERS_TABLE . '`.`rank_id` = ' . $rank->getId() . ' AND `players`.`id` = `' . GUILD_MEMBERS_TABLE . '`.`player_id` 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'))
|
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();
|
$players_with_rank_number = $players_with_rank->rowCount();
|
||||||
if($players_with_rank_number > 0)
|
if($players_with_rank_number > 0)
|
||||||
|
|||||||
@@ -176,7 +176,9 @@ if (empty($highscores)) {
|
|||||||
POT::SKILL_FISH => 'skill_fishing',
|
POT::SKILL_FISH => 'skill_fishing',
|
||||||
);
|
);
|
||||||
|
|
||||||
$query->addSelect($skill_ids[$skill] . ' as value');
|
$query
|
||||||
|
->addSelect($skill_ids[$skill] . ' as value')
|
||||||
|
->orderByDesc($skill_ids[$skill] . '_tries');
|
||||||
} else {
|
} else {
|
||||||
$query
|
$query
|
||||||
->join('player_skills', 'player_skills.player_id', '=', 'players.id')
|
->join('player_skills', 'player_skills.player_id', '=', 'players.id')
|
||||||
@@ -198,11 +200,11 @@ if (empty($highscores)) {
|
|||||||
if ($skill == POT::SKILL__MAGLEVEL) {
|
if ($skill == POT::SKILL__MAGLEVEL) {
|
||||||
$query
|
$query
|
||||||
->addSelect('players.maglevel as value', 'players.maglevel')
|
->addSelect('players.maglevel as value', 'players.maglevel')
|
||||||
->orderBy('manaspent');
|
->orderByDesc('manaspent');
|
||||||
} else { // level
|
} else { // level
|
||||||
$query
|
$query
|
||||||
->addSelect('players.level as value', 'players.experience')
|
->addSelect('players.level as value', 'players.experience')
|
||||||
->orderBy('experience');
|
->orderByDesc('experience');
|
||||||
$list = 'experience';
|
$list = 'experience';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = '';
|
$tickers_content = '';
|
||||||
if($tickers_db->rowCount() > 0)
|
if($tickers_db->rowCount() > 0)
|
||||||
{
|
{
|
||||||
@@ -142,7 +142,8 @@ if(!$news_cached)
|
|||||||
if($cache->enabled() && !$canEdit)
|
if($cache->enabled() && !$canEdit)
|
||||||
$cache->set('news_' . $template_name . '_' . TICKER, $tickers_content, 60 * 60);
|
$cache->set('news_' . $template_name . '_' . TICKER, $tickers_content, 60 * 60);
|
||||||
|
|
||||||
$featured_article_db =$db->query('SELECT `id`, `title`, `article_text`, `article_image`, `hide` FROM `' . TABLE_PREFIX . 'news` WHERE `type` = ' . ARTICLE . ($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 = '';
|
$article = '';
|
||||||
if($featured_article_db->rowCount() > 0) {
|
if($featured_article_db->rowCount() > 0) {
|
||||||
$article = $featured_article_db->fetch();
|
$article = $featured_article_db->fetch();
|
||||||
@@ -175,7 +176,7 @@ else {
|
|||||||
if(!$news_cached)
|
if(!$news_cached)
|
||||||
{
|
{
|
||||||
ob_start();
|
ob_start();
|
||||||
$newses = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news') . ' WHERE type = ' . NEWS . ($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)
|
if($newses->rowCount() > 0)
|
||||||
{
|
{
|
||||||
foreach($newses as $news)
|
foreach($newses as $news)
|
||||||
|
|||||||
@@ -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',
|
'desc' => 'should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io',
|
||||||
'default' => true,
|
'default' => true,
|
||||||
],
|
],
|
||||||
|
'account_countries_most_popular' => [
|
||||||
|
'name' => 'Account Countries Most Popular',
|
||||||
|
'type' => 'text',
|
||||||
|
'desc' => 'Those countries will be display at the top of the list on the create account page. The short codes of countries can be found in file <i>system/countries.conf.php</i>',
|
||||||
|
'default' => 'pl,se,br,us,gb',
|
||||||
|
'callbacks' => [
|
||||||
|
'get' => function ($value) {
|
||||||
|
$tmp = array_map('trim', explode(',', $value));
|
||||||
|
return array_filter($tmp, function ($v) {return !empty($v); });
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
'characters_per_account' => [
|
'characters_per_account' => [
|
||||||
'name' => 'Characters per Account',
|
'name' => 'Characters per Account',
|
||||||
'type' => 'number',
|
'type' => 'number',
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ class PHP
|
|||||||
{
|
{
|
||||||
$var = var_export($var, true);
|
$var = var_export($var, true);
|
||||||
|
|
||||||
|
ensureFolderExists($this->dir);
|
||||||
|
ensureIndexExists($this->dir);
|
||||||
|
|
||||||
// Write to temp file first to ensure atomicity
|
// Write to temp file first to ensure atomicity
|
||||||
$tmp = $this->dir . "tmp_$key." . uniqid('', true) . '.tmp';
|
$tmp = $this->dir . "tmp_$key." . uniqid('', true) . '.tmp';
|
||||||
file_put_contents($tmp, '<?php $var = ' . $var . ';', LOCK_EX);
|
file_put_contents($tmp, '<?php $var = ' . $var . ';', LOCK_EX);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class PluginDisableCommand extends Command
|
|||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this->setName('plugin:disable')
|
$this->setName('plugin:disable')
|
||||||
|
->setAliases(['plugin:deactivate'])
|
||||||
->setDescription('This command disables plugin')
|
->setDescription('This command disables plugin')
|
||||||
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to disable');
|
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to disable');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class PluginEnableCommand extends Command
|
|||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this->setName('plugin:enable')
|
$this->setName('plugin:enable')
|
||||||
|
->setAliases(['plugin:activate'])
|
||||||
->setDescription('This command enables plugin')
|
->setDescription('This command enables plugin')
|
||||||
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to enable');
|
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to enable');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class PluginUninstallCommand extends Command
|
|||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this->setName('plugin:uninstall')
|
$this->setName('plugin:uninstall')
|
||||||
|
->setAliases(['plugin:remove', 'plugin:delete'])
|
||||||
->setDescription('This command uninstalls plugin')
|
->setDescription('This command uninstalls plugin')
|
||||||
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to uninstall');
|
->addArgument('plugin-name', InputArgument::REQUIRED, 'Plugin that you want to uninstall');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,10 +76,11 @@ class Items
|
|||||||
|
|
||||||
public static function get($id) {
|
public static function get($id) {
|
||||||
self::load();
|
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);
|
$item = self::get($id);
|
||||||
|
|
||||||
$attr = $item['attributes'];
|
$attr = $item['attributes'];
|
||||||
@@ -112,15 +113,15 @@ class Items
|
|||||||
$s .= 'an item of type ' . $item['id'];
|
$s .= 'an item of type ' . $item['id'];
|
||||||
|
|
||||||
if(isset($attr['type']) && strtolower($attr['type']) == 'rune') {
|
if(isset($attr['type']) && strtolower($attr['type']) == 'rune') {
|
||||||
$item = Spell::where('item_id', $id)->first();
|
$spell = Spell::where('item_id', $id)->first();
|
||||||
if($item) {
|
if($spell) {
|
||||||
if($item->level > 0 && $item->maglevel > 0) {
|
if($spell->level > 0 && $spell->maglevel > 0) {
|
||||||
$s .= '. ' . ($count > 1 ? "They" : "It") . ' can only be used by ';
|
$s .= '. ' . ($count > 1 ? 'They' : 'It') . ' can only be used by ';
|
||||||
}
|
}
|
||||||
|
|
||||||
$configVocations = config('vocations');
|
$configVocations = config('vocations');
|
||||||
if(!empty(trim($item->vocations))) {
|
if(!empty(trim($spell->vocations))) {
|
||||||
$vocations = json_decode($item->vocations);
|
$vocations = json_decode($spell->vocations);
|
||||||
if(count($vocations) > 0) {
|
if(count($vocations) > 0) {
|
||||||
foreach($vocations as $voc => $show) {
|
foreach($vocations as $voc => $show) {
|
||||||
$vocations[$configVocations[$voc]] = $show;
|
$vocations[$configVocations[$voc]] = $show;
|
||||||
@@ -133,8 +134,39 @@ class Items
|
|||||||
|
|
||||||
$s .= ' with';
|
$s .= ' with';
|
||||||
|
|
||||||
|
if ($spell->level > 0) {
|
||||||
|
$s .= ' level ' . $spell->level;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($spell->maglevel > 0) {
|
||||||
|
if ($spell->level > 0) {
|
||||||
|
$s .= ' and';
|
||||||
|
}
|
||||||
|
|
||||||
|
$s .= ' magic level ' . $spell->maglevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
$s .= ' or higher';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($item['weaponType'])) {
|
||||||
|
if ($item['weaponType'] == 'distance' && isset($item['ammoType'])) {
|
||||||
|
$s .= ' (Range:' . $item['range'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($item['attack']) && $item['attack'] != 0) {
|
||||||
|
$s .= ', Atk ' . ($item['attack'] > 0 ? '+' . $item['attack'] : '-' . $item['attack']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($item['hitChance']) && $item['hitChance'] != -1) {
|
||||||
|
$s .= ', Hit% ' . ($item['hitChance'] > 0 ? '+' . $item['hitChance'] : '-' . $item['hitChance']);
|
||||||
|
}
|
||||||
|
elseif ($item['weaponType'] != 'ammo') {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $s;
|
return $s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ class AccountAction extends Model {
|
|||||||
|
|
||||||
public $timestamps = false;
|
public $timestamps = false;
|
||||||
|
|
||||||
protected $fillable = ['account_id', 'ip', 'ipv6', 'date', 'action'];
|
protected $fillable = ['account_id', 'ip', 'date', 'action'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -513,6 +513,9 @@ class Plugins {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensureFolderExists($cachePlugins = CACHE . 'plugins');
|
||||||
|
ensureIndexExists($cachePlugins);
|
||||||
|
|
||||||
self::$error = 'There was a problem with extracting zip archive.';
|
self::$error = 'There was a problem with extracting zip archive.';
|
||||||
$file_name = $plugin_temp_dir . $json_file;
|
$file_name = $plugin_temp_dir . $json_file;
|
||||||
if(!file_exists($file_name)) {
|
if(!file_exists($file_name)) {
|
||||||
@@ -549,21 +552,21 @@ class Plugins {
|
|||||||
if(isset($plugin_json['require'])) {
|
if(isset($plugin_json['require'])) {
|
||||||
$require = $plugin_json['require'];
|
$require = $plugin_json['require'];
|
||||||
|
|
||||||
$myaac_satified = true;
|
$myaac_satisfied = true;
|
||||||
if(isset($require['myaac_'])) {
|
if(isset($require['myaac_'])) {
|
||||||
$require_myaac = $require['myaac_'];
|
$require_myaac = $require['myaac_'];
|
||||||
if(!Semver::satisfies(MYAAC_VERSION, $require_myaac)) {
|
if(!Semver::satisfies(MYAAC_VERSION, $require_myaac)) {
|
||||||
$myaac_satified = false;
|
$myaac_satisfied = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(isset($require['myaac'])) {
|
else if(isset($require['myaac'])) {
|
||||||
$require_myaac = $require['myaac'];
|
$require_myaac = $require['myaac'];
|
||||||
if(version_compare(MYAAC_VERSION, $require_myaac, '<')) {
|
if(version_compare(MYAAC_VERSION, $require_myaac, '<')) {
|
||||||
$myaac_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 . ".";
|
self::$error = "Your AAC version doesn't meet the requirement of this plugin. Required version is: " . $require_myaac . ", and you're using version " . MYAAC_VERSION . ".";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ class Settings implements \ArrayAccess
|
|||||||
echo '<div class="input-group" id="show-hide-' . $key . '">';
|
echo '<div class="input-group" id="show-hide-' . $key . '">';
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '<input class="form-control" type="' . $setting['type'] . '" name="settings[' . $key . ']" value="' . ($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') {
|
if ($setting['type'] === 'password') {
|
||||||
echo '<div class="input-group-append input-group-text"><a href=""><i class="fas fa-eye-slash" ></i></a></div></div>';
|
echo '<div class="input-group-append input-group-text"><a href=""><i class="fas fa-eye-slash" ></i></a></div></div>';
|
||||||
@@ -266,7 +266,7 @@ class Settings implements \ArrayAccess
|
|||||||
if ($rows < 2) {
|
if ($rows < 2) {
|
||||||
$rows = 2; // always min 2 rows for textarea
|
$rows = 2; // always min 2 rows for textarea
|
||||||
}
|
}
|
||||||
echo '<textarea class="form-control" rows="' . $rows . '" name="settings[' . $key . ']" id="' . $key . '">' . $value . '</textarea>';
|
echo '<textarea class="form-control" rows="' . $rows . '" name="settings[' . $key . ']" id="' . $key . '">' . escapeHtml($value) . '</textarea>';
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ($setting['type'] === 'options') {
|
else if ($setting['type'] === 'options') {
|
||||||
|
|||||||
@@ -342,6 +342,16 @@ class Validator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global $hooks;
|
||||||
|
|
||||||
|
$params = ['name' => $name, 'error' => ''];
|
||||||
|
$hooks->triggerFilter(HOOK_FILTER_VALIDATE_CHARACTER_NEW_NAME, $params);
|
||||||
|
|
||||||
|
if (!empty($params['error'])) {
|
||||||
|
self::$lastError = $params['error'];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ define('HOOK_FILTER_ROUTES', ++$i);
|
|||||||
define('HOOK_FILTER_TWIG_DISPLAY', ++$i);
|
define('HOOK_FILTER_TWIG_DISPLAY', ++$i);
|
||||||
define('HOOK_FILTER_TWIG_RENDER', ++$i);
|
define('HOOK_FILTER_TWIG_RENDER', ++$i);
|
||||||
define('HOOK_FILTER_THEME_FOOTER', ++$i);
|
define('HOOK_FILTER_THEME_FOOTER', ++$i);
|
||||||
|
define('HOOK_FILTER_VALIDATE_CHARACTER_NEW_NAME', ++$i);
|
||||||
|
|
||||||
const HOOK_FIRST = HOOK_INIT;
|
const HOOK_FIRST = HOOK_INIT;
|
||||||
define('HOOK_LAST', $i);
|
define('HOOK_LAST', $i);
|
||||||
|
|||||||
@@ -145,13 +145,7 @@ function updateStatus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$uptime = $status['uptime'] = $serverStatus->getUptime();
|
$uptime = $status['uptime'] = $serverStatus->getUptime();
|
||||||
$m = date('m', $uptime);
|
$status['uptimeReadable'] = getStatusUptimeReadable($uptime);
|
||||||
$m = $m > 1 ? "$m months, " : ($m == 1 ? 'month, ' : '');
|
|
||||||
$d = date('d', $uptime);
|
|
||||||
$d = $d > 1 ? "$d days, " : ($d == 1 ? 'day, ' : '');
|
|
||||||
$h = date('H', $uptime);
|
|
||||||
$min = date('i', $uptime);
|
|
||||||
$status['uptimeReadable'] = "{$m}{$d}{$h}h {$min}m";
|
|
||||||
|
|
||||||
$status['monsters'] = $serverStatus->getMonstersCount();
|
$status['monsters'] = $serverStatus->getMonstersCount();
|
||||||
$status['motd'] = $serverStatus->getMOTD();
|
$status['motd'] = $serverStatus->getMOTD();
|
||||||
|
|||||||
@@ -53,6 +53,9 @@
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensureFolderExists(SIGNATURES_CACHE);
|
||||||
|
ensureIndexExists(SIGNATURES_CACHE);
|
||||||
|
|
||||||
$cached = SIGNATURES_CACHE.$player->getId() . '.png';
|
$cached = SIGNATURES_CACHE.$player->getId() . '.png';
|
||||||
if(file_exists($cached) && (time() < (filemtime($cached) + (60 * setting('core.signature_cache_time')))))
|
if(file_exists($cached) && (time() < (filemtime($cached) + (60 * setting('core.signature_cache_time')))))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user