Compare commits

..

16 Commits

Author SHA1 Message Date
slawkens
8d76e4e670 Merge branch 'develop' into feature/docker 2024-12-20 23:03:39 +01:00
slawkens
5e14521f08 Fix docker build 2024-12-20 22:27:57 +01:00
slawkens
335a0d1cff Merge branch 'develop' into feature/docker 2024-12-20 21:20:48 +01:00
slawkens
5735d487d9 Merge branch 'develop' into feature/docker 2024-07-14 06:01:27 +02:00
slawkens
d7e1ca747e Merge branch 'develop' into feature/docker 2024-02-29 16:12:28 +01:00
slawkens
5a9490138b Merge branch 'develop' into feature/docker 2024-02-18 12:12:32 +01:00
slawkens
42e40e5d77 Twig_SimpleFilter is deprecated 2023-09-22 16:18:05 +02:00
slawkens
80a3a72b36 Update .gitignore 2023-09-20 15:55:06 +02:00
slawkens
a4b1631f6d Add missing file 2023-09-20 15:54:44 +02:00
slawkens
49af260c2e Some features for docker users
Disable IP Check on install
automatically fill out server_path
2023-09-17 14:39:02 +02:00
slawkens
72d7ee8bf2 Speed up 20x? By removing volume 2023-09-16 21:49:11 +02:00
slawkens
c503f5e0a5 enable apcu & opcache 2023-09-16 19:10:56 +02:00
slawkens
03b2d71572 [wip] docker setup
It's working now
2023-09-16 18:20:08 +02:00
slawkens
86b94ea5e8 Merge branch 'develop' into feature/docker 2023-09-16 14:41:28 +02:00
slawkens
e9b5617748 Create Dockerfile 2023-09-16 14:40:58 +02:00
slawkens
fee9d60da4 Create docker-compose.yml 2023-09-16 14:40:55 +02:00
188 changed files with 4429 additions and 4381 deletions

65
.dockerignore Normal file
View File

@@ -0,0 +1,65 @@
Thumbs.db
.DS_Store
.idea
#
/.htaccess
# composer
composer.phar
vendor
# npm
node_modules
tools/ext
# cypress
cypress.env.json
cypress/e2e/2-advanced-examples
cypress/screenshots
# created by release.sh
releases
tmp
config.local.php
!docker/config.local.php
# all custom templates
templates/*
!templates/tibiacom
!templates/kathrine
# guild images
images/guilds/*
!images/guilds/default.gif
# editor images
images/editor/*
!images/editor/index.html
# gallery images
images/gallery/*
!images/gallery/index.html
!images/gallery/demon.jpg
!images/gallery/demon_thumb.gif
# cache
system/cache/*
!system/cache/index.html
!system/cache/twig/index.html
!system/cache/signatures/index.html
!system/cache/plugins/index.html
!system/cache/persistent/index.html
# logs
system/logs/*
!system/logs/index.html
# data
system/data/*
!system/data/index.html
# php sessions
system/php_sessions/*
!system/php_sessions/index.html

View File

@@ -1,9 +1,9 @@
name: Cypress
on:
pull_request:
branches: [main]
branches: [develop]
push:
branches: [main]
branches: [develop]
jobs:
cypress:
@@ -35,7 +35,7 @@ jobs:
- name: Checkout MyAAC
uses: actions/checkout@v4
with:
ref: main
ref: develop
- uses: actions/setup-node@v4
with:

View File

@@ -1,9 +1,9 @@
name: PHP Linting
on:
pull_request:
branches: [main]
branches: [develop]
push:
branches: [main]
branches: [develop]
jobs:
phplint:

View File

@@ -2,9 +2,9 @@ name: "PHPStan"
on:
pull_request:
branches: [main]
branches: [develop]
push:
branches: [main]
branches: [develop]
jobs:
tests:

5
.gitignore vendored
View File

@@ -4,7 +4,6 @@ Thumbs.db
#
/.htaccess
lua
# composer
composer.phar
@@ -24,6 +23,7 @@ releases
tmp
config.local.php
!docker/config.local.php
# all custom templates
templates/*
@@ -76,3 +76,6 @@ landing
# system
system/functions_custom.php
# others/rest
system/pages/downloads.php

View File

@@ -1,112 +1,5 @@
# Changelog
## [1.3.1 - 19.03.2025]
### Fixed
* Fixed migrate:run command (https://github.com/slawkens/myaac/commit/1a5771ad51e595fe13368a0721b059c4ecefb17d)
### Changed
* Small adjustments (https://github.com/slawkens/myaac/commit/6fac883659f581baac1361826d046410156f1e58, https://github.com/slawkens/myaac/commit/4a6896b4469968b9904292734cf6c14ba5eeef14)
## [1.3 - 10.03.2025]
### Changed
* Use latest outfit-images host from @gesior (https://github.com/slawkens/myaac/commit/529bdcf016dd0f9dffbc34d81f99a046a9ddb70d)
* Change monster link to $_GET ?name= (https://github.com/slawkens/myaac/commit/4c5cc8b573b2b3e7ec00a22b7ede30a68083a924)
### Fixed
* Fixed house links (https://github.com/slawkens/myaac/commit/887b5068ad11c4cdab614afd34525caba785ce13)
* Fixed long title on headline.php (https://github.com/slawkens/myaac/commit/3e3f4bb5a514158ec8777684ca6c7f1c2a37bed5)
* Fixed menu colors once again, plus add !important tag (https://github.com/slawkens/myaac/commit/aa52df6e2ec92cafc25b655ae907bf2e1746d9cc)
* Fix: add possibility to remove all menu items in admin panel (https://github.com/slawkens/myaac/commit/00fe1adc15ea7646596d755f6e6e1f7854ffc1d5, https://github.com/slawkens/myaac/commit/9239a4f4198c3ad260802ac3b47e9c41b80b754e)
## [1.2 - 09.02.2025]
### Added
* Twig session(key) function + reworked session functions to accept multi-array like in Laravel (https://github.com/slawkens/myaac/commit/b46ddb43d03ef7e5fc34e555e92e856bdc905691)
* add template_name to twig variables (https://github.com/slawkens/myaac/commit/ae1161d77050bda181802b4496c9de920a7bb1bc)
* add HOOK_INIT, executed just after $hooks are loaded (https://github.com/slawkens/myaac/commit/19686725dc810f63a07f049f82c66cf336d90ca6)
### Changed
* settings: password input hide/show, enable Save button only if changes has been made, save settings in transaction (https://github.com/slawkens/myaac/commit/4fda4f643b60a151179e5dd4f04912fb2618d98f, https://github.com/slawkens/myaac/commit/28fef952f857b79d64bc7495ffa5e1999e68e192, https://github.com/slawkens/myaac/commit/4b6024dc451accadb6c469fa282a9a764c1c0a81)
* rework menus: Different categories can have different colors + Option to reset menus (https://github.com/slawkens/myaac/commit/73de93a561f6b13111e019075724357d8a617249, https://github.com/slawkens/myaac/commit/3da3e62c5b12390d75de9b3320729bcca6e0b458)
### Fixed
* highscores: Fix online status + vocation for TFS 0.x (https://github.com/slawkens/myaac/commit/ea51ad27c38be88d86514cb979bb394fcfbef1f0)
* clear cache button in admin bar needed to be clicked twice until it worked (https://github.com/slawkens/myaac/commit/ea51ad27c38be88d86514cb979bb394fcfbef1f0)
* HOOK_STARTUP location (https://github.com/slawkens/myaac/commit/a73fb1003ee3f812cf182d1834d65f08e6f60d1f)
* if vocation name has more words (https://github.com/slawkens/myaac/commit/9d7fc98e1e0a96b59ecc1a7c39800a64445db364)
### Updated
* Bump twig/twig from 3.18.0 to 3.19.0 (#284)
## [1.1 - 27.01.2025]
### Changed
* adjust mailer settings descriptions to latest gmail (https://github.com/slawkens/myaac/commit/c5d5bb80671db135e6b503f53684771c7272e05d)
* optimize $player->isOnline() function, thanks @gesior (https://github.com/slawkens/myaac/commit/10dd818b139d5e1bb1ca9ec81edfb083ba9316b4)
* make players.comment and guilds.description VARCHAR (https://github.com/slawkens/myaac/commit/a45ceab83a74bee2b89cdb72baceda75e577e3cf)
* add lua/ folder to .gitignore (https://github.com/slawkens/myaac/commit/07012f786b1114cb6ab2f064f82c645b136a375a)
### Fixed
* general fixes in the tibiacom template menus, better support for custom menus
* make functions_custom.php optional (https://github.com/slawkens/myaac/commit/dc2b5afd9980984e2b259c9fc99f2ade46f70a5a)
* error in CLI, where BASE_URL is not defined (https://github.com/slawkens/myaac/commit/4d749b881582f64b5a46196dbbb5ee8097127f03)
* hook ACCOUNT_LOGIN_BEFORE_ACCOUNT location (https://github.com/slawkens/myaac/commit/669c447fca8643ce56d9ef8c1374ec647c780998)
## [1.0.1 - 14.01.2025]
### Fixed
* tibiacom account & news menu links not auto expanding
### Updated (Thanks dependabot)
* twig from ^2.0 to ^3.11
* tinymce from ^6.8.3 to ^7.2.0
* cypress from ^12.12.0 to ^13.17.0
* nesbot/carbon from 2.72.5 to 2.72.6
## [1.0 - 12.01.2025]
First stable release in the v1.0 series.
Minimum PHP 8.1 is required.
Changes since RC.2:
### Added
* feature: migrations up/down. Allows to downgrade/upgrade database to specified version (https://github.com/slawkens/myaac/commit/3f6ff3a3326b0475d28d11ffd7fff51f362d799f)
* new hooks for news management (https://github.com/slawkens/myaac/commit/011a85d8ae34283ded6999882833f9d4797028ec, https://github.com/slawkens/myaac/commit/36bd3eb846e829b45313e10f7568dc4e95841143)
* None Vocation to highscores (can be changed to RookStayer in Admin Panel) (https://github.com/slawkens/myaac/commit/a4a248099521bb5b8b2aa5bd592138debd2f19d5)
* support for button_color (green, red, blue) (https://github.com/slawkens/myaac/commit/d8b6b749ee62e88b6af4a05d3d7557f90b94d94e)
* add $whoopsHandler as variable, can be used by plugins (https://github.com/slawkens/myaac/commit/b0c8cf2ecda23045d725aaf43cfb3852ed766a4b)
* PlayerModel->outfit_url attribute (https://github.com/slawkens/myaac/commit/3b5be1a8db5dceecaa388e2925a5536d13b38881)
* support for selecting plugin themes in Admin menus.php (https://github.com/slawkens/myaac/commit/77a2c1cec343ffe4be5c2c2503ee81bc32a14ca1)
### Changed
* schema: Change character set to utf8mb4 (support for Emojis in Menus/Pages/News/Forum etc.) (https://github.com/slawkens/myaac/commit/27c44f1bdfb6234cf0c9d5b4b491123bb205b08f)
* prefer get_browser_real_ip() over REMOTE_ADDR (https://github.com/slawkens/myaac/commit/941846605c00cee83168d2f916410b8ba8d4b7b9)
* automatically set selected current one on highscores filters (https://github.com/slawkens/myaac/commit/e96227fbe41ae281783b2d49edb169a603601813)
* rewrite towns loading code, removed OTBM loader (was too slow) (https://github.com/slawkens/myaac/commit/c980a0914632e7b27f718464f669a200707d217e)
* allow OTS_Player to be passed as object to getPlayerLink (https://github.com/slawkens/myaac/commit/84d37c5a8f2c4535a41c8aa8264752969d3f3a3d)
* do not clear menus by default on install (https://github.com/slawkens/myaac/commit/12d8faa3eda5e798f97b71e941c035187daad96e)
* display warning in admin panel - plugins - if zip extension is not installed (https://github.com/slawkens/myaac/commit/e3ffe5d9e11d78ab064a370d8541bac351c9bcd9)
* set default_socket_timeout for ipinfo.io checkup to 5 seconds (https://github.com/slawkens/myaac/commit/783d96fc6568a607d3198b832fed3a0dd06c4ebb)
* refactor getTopPlayers function (support for balance) (https://github.com/slawkens/myaac/commit/c769962e39fe8dfb72ecd5be1864e145696be794)
### Fixed
* XSS in forum (https://github.com/slawkens/myaac/commit/c2b7286d20d4b579171540f7a774e8a0995d5e8f, https://github.com/slawkens/myaac/commit/8fb643596f9586005976e7bdb484a541a9d8715e)
* price deducted when changing sex (https://github.com/slawkens/myaac/commit/16671ea40b72dcf74037c359ad572f9eb825edf9)
* move_thread by unauthorized user (https://github.com/slawkens/myaac/commit/d6c40c836a53cb1710f911f77f45f28b54ea1b54, thanks @anyeor)
* TFS 1.4.2 where conditions is NULL (https://github.com/slawkens/myaac/commit/b8396d4c8482e951da538b13f2296123732c4545)
* do not show forum new thread show button if not logged in (https://github.com/slawkens/myaac/commit/507402171ba3b6e7ee184bd7fa73e0d55e0cad7a, @anyeor)
* login if limiter is disabled (https://github.com/slawkens/myaac/commit/a0f1971583f0f790013e2145fb5ac573c59fbdef)
* fixes to installMenus function (https://github.com/slawkens/myaac/commit/a2fadc5945fe0a5e39f740827f6ffbda1bb501e2)
* many PHP exceptions in different places
* fixes to tibiacom menus ActiveSubmenuItem
### Removed
* bugtracker SQL table code as the page has been removed/moved to plugins (https://github.com/slawkens/myaac/commit/5782772b901b05fb814bc718d062f6e2cd71df8c)
## [1.0-RC.2 - 25.10.2024]
Still waiting for your reports about bugs found in this release. We are very close to stable release.
@@ -194,6 +87,7 @@ Minimum PHP version for this release is 8.1.
* support for login and create account only by email (configurable)
* with no need for account name
* Google ReCAPTCHA v3 support (available as plugin)
* automatically load towns names from .OTBM file
* support for Account Number
* suggest account number option
* many new functions, hooks and configurables
@@ -222,4 +116,4 @@ Minimum PHP version for this release is 8.1.
* change_password email to be more informal
### Fixed
* hundreds of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here
* hundrets of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here

View File

@@ -1,3 +1,3 @@
* Gesior.pl (2007 - 2008)
* Slawkens (2009 - 2025)
* Slawkens (2009 - 2023)
* Contributors listed in CONTRIBUTORS.txt

View File

@@ -11,10 +11,10 @@ Official website: https://my-aac.org
[![Closed Issues](https://img.shields.io/github/issues-closed-raw/slawkens/myaac)](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed)
| Version | Status | Branch | Requirements |
|:--------|:-----------------------|:-------|:---------------|
| **1.x** | **Active development** | master | **PHP >= 8.1** |
|:--------|:-----------------------|:--------|:---------------|
| **1.x** | **Active development** | develop | **PHP >= 8.1** |
| 0.9.x | Not developed anymore | 0.9 | PHP >= 7.2.5 |
| 0.8.x | Active support | 0.8 | PHP >= 7.2.5 |
| 0.8.x | Active support | master | PHP >= 7.2.5 |
| 0.7.x | End Of Life | 0.7 | PHP >= 5.3.3 |
### Requirements

33
aac
View File

@@ -3,5 +3,34 @@
require_once __DIR__ . '/common.php';
$console = new \MyAAC\App\Console();
$console->run();
if(!IS_CLI) {
echo 'This script can be run only in command line mode.';
exit(1);
}
require_once SYSTEM . 'functions.php';
define('SELF_NAME', basename(__FILE__));
use MyAAC\Plugins;
use Symfony\Component\Console\Application;
$application = new Application('MyAAC', MYAAC_VERSION);
$commandsGlob = glob(SYSTEM . 'src/Commands/*.php');
foreach ($commandsGlob as $item) {
$name = pathinfo($item, PATHINFO_FILENAME);
if ($name == 'Command') { // ignore base Command class
continue;
}
$commandPre = '\\MyAAC\Commands\\';
$application->add(new ($commandPre . $name));
}
$pluginCommands = Plugins::getCommands();
foreach ($pluginCommands as $item) {
$application->add(require $item);
}
$application->run();

View File

@@ -1,8 +1,67 @@
<?php
require_once '../common.php';
require_once SYSTEM . 'functions.php';
// few things we'll need
require '../common.php';
const ADMIN_PANEL = true;
const MYAAC_ADMIN = true;
$admin = new \MyAAC\App\Admin();
$admin->run();
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
{
header('Location: ' . BASE_URL . 'install/');
throw new RuntimeException('Setup detected that <b>install/</b> directory exists. Please visit <a href="' . BASE_URL . 'install">this</a> url to start MyAAC Installation.<br/>Delete <b>install/</b> directory if you already installed MyAAC.<br/>Remember to REFRESH this page when you\'re done!');
}
$content = '';
// validate page
$page = $_GET['p'] ?? '';
if(empty($page) || preg_match("/[^a-zA-Z0-9_\-\/.]/", $page))
$page = 'dashboard';
$page = strtolower($page);
define('PAGE', $page);
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
require __DIR__ . '/includes/debugbar.php';
require SYSTEM . 'status.php';
require SYSTEM . 'login.php';
require __DIR__ . '/includes/functions.php';
$twig->addGlobal('config', $config);
$twig->addGlobal('status', $status);
if (ACTION == 'logout') {
require SYSTEM . 'logout.php';
}
// if we're not logged in - show login box
if(!$logged || !admin()) {
$page = 'login';
}
// include our page
$file = __DIR__ . '/pages/' . $page . '.php';
if(!@file_exists($file)) {
if (str_contains($page, 'plugins/')) {
$file = BASE . $page;
}
else {
$page = '404';
$file = SYSTEM . 'pages/404.php';
}
}
ob_start();
if($hooks->trigger(HOOK_ADMIN_BEFORE_PAGE)) {
require $file;
}
$content .= ob_get_contents();
ob_end_clean();
// template
$template_path = 'template/';
require __DIR__ . '/' . $template_path . 'template.php';

View File

@@ -9,7 +9,6 @@
*/
use MyAAC\Models\Account as AccountModel;
use MyAAC\Models\AccountAction;
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
@@ -94,7 +93,7 @@ else if (isset($_REQUEST['search'])) {
?>
<div class="row">
<?php
$groups = app()->get('groups');
$groups = new OTS_Groups_List();
if ($id > 0) {
$account = new OTS_Account();
$account->load($id);
@@ -467,8 +466,9 @@ else if (isset($_REQUEST['search'])) {
</thead>
<tbody>
<?php
$accountActions = AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
$accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
foreach ($accountActions as $i => $log):
$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6));
?>
<tr>
<td><?php echo $i + 1; ?></td>

View File

@@ -110,7 +110,7 @@ if($action == 'edit' || $action == 'new') {
$player->load($player_id);
}
$account_players = accountLogged()->getPlayersList();
$account_players = $account_logged->getPlayersList();
$account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.changelog.form.html.twig', array(
'action' => $action,

View File

@@ -13,7 +13,7 @@ $title = 'Login';
csrfProtect();
require PAGES . 'account/login.php';
if (logged()) {
if ($logged) {
header('Location: ' . (admin() ? ADMIN_URL : BASE_URL));
return;
}

View File

@@ -57,14 +57,13 @@ function admin_give_coins($coins)
function admin_give_premdays($days)
{
global $freePremium;
global $db, $freePremium;
if ($freePremium) {
displayMessage('Premium days not supported. Free Premium enabled.');
return;
}
$db = app()->get('database');
$value = $days * 86400;
$now = time();
// othire
@@ -175,12 +174,10 @@ else {
}
function displayMessage($message, $success = false) {
global $hasCoinsColumn, $hasPointsColumn, $freePremium;
global $twig, $hasCoinsColumn, $hasPointsColumn, $freePremium;
$success ? success($message): error($message);
$twig = app()->get('twig');
$twig->display('admin.tools.account.html.twig', array(
'hasCoinsColumn' => $hasCoinsColumn,
'hasPointsColumn' => $hasPointsColumn,

View File

@@ -99,9 +99,9 @@ else {
}
function displayMessage($message, $success = false)
{
$twig = app()->get('twig');
function displayMessage($message, $success = false) {
global $twig;
$success ? success($message): error($message);
$twig->display('admin.tools.teleport.html.twig', array());
}

View File

@@ -10,7 +10,6 @@
use MyAAC\Cache\Cache;
use MyAAC\Models\Menu;
use MyAAC\Plugins;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Menus';
@@ -22,16 +21,14 @@ if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) {
return;
}
$pluginThemes = Plugins::getThemes();
if (isset($_POST['template'])) {
$template = $_POST['template'];
if (isset($_POST['save'])) {
$post_menu = $_POST['menu'] ?? [];
$post_menu_link = $_POST['menu_link'] ?? [];
$post_menu_blank = $_POST['menu_blank'] ?? [];
$post_menu_color = $_POST['menu_color'] ?? [];
if (isset($_POST['menu'])) {
$post_menu = $_POST['menu'];
$post_menu_link = $_POST['menu_link'];
$post_menu_blank = $_POST['menu_blank'];
$post_menu_color = $_POST['menu_color'];
if (count($post_menu) != count($post_menu_link)) {
echo 'Menu count is not equal menu links. Something went wrong when sending form.';
return;
@@ -59,67 +56,54 @@ if (isset($_POST['template'])) {
}
}
onTemplateMenusChange();
$cache = Cache::getInstance();
if ($cache->enabled()) {
$cache->delete('template_menus');
}
success('Saved at ' . date('H:i'));
}
$path = TEMPLATES . $template;
if (isset($pluginThemes[$template])) {
$path = BASE . $pluginThemes[$template];
}
$path .= '/config.php';
if (file_exists($path)) {
require_once $path;
$file = TEMPLATES . $template . '/config.php';
if (file_exists($file)) {
require_once $file;
} else {
echo 'Cannot find template config.php file.';
return;
}
if (isset($_GET['reset_colors'])) {
if (isset($config['menu_default_color'])) {
Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]);
success('Colors has been reset.');
}
else {
warning('There is no default color defined, cannot reset colors.');
}
}
if (!isset($config['menu_categories'])) {
echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus.";
return;
}
if (isset($_GET['reset_colors'])) {
foreach ($config['menu_categories'] as $id => $options) {
$color = $options['default_links_color'] ?? ($config['menu_default_links_color'] ?? ($config['menu_default_color'] ?? '#ffffff'));
Menu::where('template', $template)->where('category', $id)->update(['color' => str_replace('#', '', $color)]);
}
onTemplateMenusChange();
success('Colors has been reset at ' . date('H:i'));
}
if (isset($_GET['reset_menus'])) {
$configMenus = config('menus');
if (isset($configMenus)) {
Plugins::installMenus($template, config('menus'), true);
onTemplateMenusChange();
success('Menus has been reset at ' . date('H:i'));
}
else {
error("This template don't support reinstalling menus.");
}
}
$title = 'Menus - ' . $template;
$canResetColors = isset($config['menu_default_color']) || isset($config['menu_default_links_color']);
foreach ($config['menu_categories'] as $id => $options) {
if (isset($options['default_links_color'])) {
$canResetColors = true;
}
}
$twig->display('admin.menus.header.html.twig', [
'template' => $template,
'canResetColors' => $canResetColors
]);
?>
<div align="center" class="text-center">
<p class="note">You are editing: <?= $template ?><br/><br/>
Hint: You can drag menu items.<br/>
Hint: Add links to external sites using: <b>http://</b> or <b>https://</b> prefix.<br/>
Not all templates support blank and colorful links.
</p>
<?php if (isset($config['menu_default_color'])) {?>
<form method="post" action="?p=menus&reset_colors" onsubmit="return confirm('Do you really want to reset colors?');">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-danger">Reset Colors to default</button>
</form>
<br/>
<?php } ?>
</div>
<?php
$menus = Menu::query()
->select('name', 'link', 'blank', 'color', 'category', 'ordering')
@@ -135,7 +119,7 @@ if (isset($_POST['template'])) {
<form method="post" id="menus-form" action="?p=menus">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" name="save" class="btn btn-info">Save</button><br/><br/>
<button type="submit" class="btn btn-info">Save</button><br/><br/>
<div class="row">
<?php foreach ($config['menu_categories'] as $id => $cat): ?>
<div class="col-md-12 col-lg-6">
@@ -149,13 +133,12 @@ if (isset($_POST['template'])) {
if (isset($menus[$id])) {
$i = 0;
foreach ($menus[$id] as $menu):
$color = (empty($menu['color']) ? ($cat['default_links_color'] ?? ($config['menu_default_links_color'] ?? ($config['menu_default_color'] ?? '#ffffff'))) : '#' . $menu['color']);
?>
<li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo escapeHtml($menu['name']); ?>"/>
<label>Link:</label> <input type="text" name="menu_link[<?php echo $id ?>][]" value="<?php echo $menu['link'] ?>"/>
<input type="hidden" name="menu_blank[<?php echo $id ?>][]" value="0"/>
<label><input class="blank-checkbox" type="checkbox" <?php echo($menu['blank'] == 1 ? 'checked' : '') ?>/><span title="Open in New Window">New Window</span></label>
<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo $color; ?>"/>
<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo (empty($menu['color']) ? ($config['menu_default_color'] ?? '#ffffff') : $menu['color']); ?>"/>
<a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li>
<?php $i++; $last_id[$id] = $i;
endforeach;
@@ -168,7 +151,7 @@ if (isset($_POST['template'])) {
</div>
<div class="row pb-2">
<div class="col-md-12">
<button type="submit" name="save" class="btn btn-info">Save</button>
<button type="submit" class="btn btn-info">Save</button>
<?php
echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>';
?>
@@ -179,19 +162,15 @@ if (isset($_POST['template'])) {
$twig->display('admin.menus.js.html.twig', array(
'menus' => $menus,
'last_id' => $last_id,
'menu_default_color' => $config['menu_default_color'] ?? '#ffffff'
));
?>
<?php
} else {
$templates = Menu::select('template')->distinct()->get()->toArray();
foreach ($templates as $key => $value) {
$path = TEMPLATES . $value['template'];
if (isset($pluginThemes[$value['template']])) {
$path = BASE . $pluginThemes[$value['template']];
}
if (!file_exists($path . '/config.php')) {
$file = TEMPLATES . $value['template'] . '/config.php';
if (!file_exists($file)) {
unset($templates[$key]);
}
}
@@ -200,11 +179,3 @@ if (isset($_POST['template'])) {
'templates' => $templates
));
}
function onTemplateMenusChange(): void
{
$cache = app()->get('cache');
if ($cache->enabled()) {
$cache->delete('template_menus');
}
}

View File

@@ -7,8 +7,6 @@ use MyAAC\Models\Monster;
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
global $eloquentConnection;
$count = $eloquentConnection->query()
->select([
'total_accounts' => Account::selectRaw('COUNT(id)'),

View File

@@ -50,7 +50,7 @@ if(!empty($action))
if (isRequestMethod('post')) {
if ($action == 'new') {
if (isset($forum_section) && $forum_section != '-1') {
$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, accountLogged()->getId(), $errors);
$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors);
}
if (isset($p_title) && News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) {
@@ -113,7 +113,7 @@ if($action == 'edit' || $action == 'new') {
$player->load($player_id);
}
$account_players = accountLogged()->getPlayersList();
$account_players = $account_logged->getPlayersList();
$account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.news.form.html.twig', array(
'action' => $action,

View File

@@ -15,18 +15,21 @@ $title = 'Notepad';
csrfProtect();
/**
* @var OTS_Account $account_logged
*/
$_content = '';
$notepad = ModelsNotepad::where('account_id', accountLogged()->getId())->first();
$notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first();
if (isset($_POST['content'])) {
$_content = html_entity_decode(stripslashes($_POST['content']));
if (!$notepad) {
ModelsNotepad::create([
'account_id' => accountLogged()->getId(),
'account_id' => $account_logged->getId(),
'content' => $_content
]);
}
else {
ModelsNotepad::where('account_id', accountLogged()->getId())->update(['content' => $_content]);
ModelsNotepad::where('account_id', $account_logged->getId())->update(['content' => $_content]);
}
success('Saved at ' . date('H:i'));

View File

@@ -25,7 +25,7 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
header('X-XSS-Protection:0');
$name = $p_title = null;
$groups = app()->get('groups');
$groups = new OTS_Groups_List();
$php = false;
$enable_tinymce = true;

View File

@@ -71,7 +71,7 @@ else if (isset($_REQUEST['search'])) {
?>
<div class="row">
<?php
$groups = app()->get('groups');
$groups = new OTS_Groups_List();
if ($id > 0) {
$player = new OTS_Player();
$player->load($id);

View File

@@ -1,7 +1,5 @@
<?php
global $menus;
$menus = [
['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'],
['name' => 'Settings', 'icon' => 'edit', 'order' => 19, 'link' =>

View File

@@ -21,7 +21,7 @@
</head>
<body class="sidebar-mini ">
<?php $hooks->trigger(HOOK_ADMIN_BODY_START); ?>
<?php if (admin()) { ?>
<?php if ($logged && admin()) { ?>
<div class="wrapper">
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<ul class="navbar-nav">
@@ -40,7 +40,7 @@
</nav>
<aside class="main-sidebar sidebar-dark-info elevation-4">
<a href="<?php echo ADMIN_URL; ?>" class="brand-link navbar-info">
<img src="<?php echo ADMIN_URL; ?>images/logo.png" class="brand-image img-circle elevation-3" style="opacity: .8" alt="MyAAC">
<img src="<?php echo ADMIN_URL; ?>images/logo.png" class="brand-image img-circle elevation-3" style="opacity: .8">
<span class="brand-text"><b>My</b>AAC</span>
</a>
<div class="sidebar">
@@ -97,6 +97,20 @@
<?php
}
}
$query = $db->query('SELECT `name`, `page`, `flags` FROM `' . TABLE_PREFIX . 'admin_menu` ORDER BY `ordering`');
$menu_db = $query->fetchAll();
foreach ($menu_db as $item) {
if ($item['flags'] == 0 || hasFlag($item['flags'])) { ?>
<li class="nav-item">
<a class="nav-link<?php echo($page == $item['page'] ? ' active' : '') ?>" href="?p=<?php echo $item['page'] ?>">
<i class="nav-icon fas fa-link"></i>
<p><?php echo $item['name'] ?></p>
</a>
</li>
<?php
}
}
?>
</ul>
</nav>
@@ -108,7 +122,7 @@
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h3 class="m-0 text-dark"><?php echo($title ?? ''); ?><small> - Admin Panel</small></h3>
<h3 class="m-0 text-dark"><?php echo(isset($title) ? $title : ''); ?><small> - Admin Panel</small></h3>
</div>
<div class="col-sm-6">
<div class="float-sm-right d-none d-sm-inline">
@@ -163,14 +177,17 @@
<div id="sidebar-overlay"></div>
</div>
<?php } else if (!logged() && !admin()) {
<?php } else if (!$logged && !admin()) {
echo $content;
}
?>
<?php
if (admin()) {
/**
* @var OTS_Account $account_logged
*/
if ($logged && admin()) {
$twig->display('admin-bar.html.twig', [
'username' => USE_ACCOUNT_NAME ? accountLogged()->getName() : accountLogged()->getId()
'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()
]);
}
?>

View File

@@ -1,22 +1,15 @@
<?php
use MyAAC\Services\LoginService;
define('MYAAC_ADMIN', true);
require '../../common.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
require SYSTEM . 'login.php';
$loginService = new LoginService();
$loginService->checkLogin();
if(!admin()) {
if(!admin())
die('Access denied.');
}
if(!function_exists('phpinfo')) {
if(!function_exists('phpinfo'))
die('phpinfo() disabled on this web server.');
}
phpinfo();

View File

@@ -24,20 +24,16 @@
*/
use MyAAC\DataLoader;
use MyAAC\Services\LoginService;
const MYAAC_ADMIN = true;
require '../../common.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
require SYSTEM . 'login.php';
$loginService = new LoginService();
$loginService->checkLogin();
if (!admin()) {
if (!admin())
die('Access denied.');
}
ini_set('max_execution_time', 300);
ob_implicit_flush();

View File

@@ -1,6 +1,6 @@
<?php
use MyAAC\Services\LoginService;
use MyAAC\Hooks;
use MyAAC\Settings;
const MYAAC_ADMIN = true;
@@ -8,9 +8,7 @@ const MYAAC_ADMIN = true;
require '../../common.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
$loginService = new LoginService();
$loginService->checkLogin();
require SYSTEM . 'login.php';
if(!admin()) {
http_response_code(500);
@@ -29,7 +27,7 @@ if (!isset($_POST['settings'])) {
die('Please enter settings.');
}
$settings = app()->get('settings');
$settings = Settings::getInstance();
$success = $settings->save($_REQUEST['plugin'], $_POST['settings']);

View File

@@ -1,20 +1,14 @@
<?php
use MyAAC\Services\LoginService;
define('MYAAC_ADMIN', true);
require '../../common.php';
require SYSTEM . 'init.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'status.php';
require SYSTEM . 'login.php';
$loginService = new LoginService();
$loginService->checkLogin();
if(!admin()) {
if(!admin())
die('Access denied.');
}
if(!$status['online'])
die('Offline');

View File

@@ -1,19 +1,13 @@
<?php
use MyAAC\Services\LoginService;
define('MYAAC_ADMIN', true);
require '../../common.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
require SYSTEM . 'login.php';
$loginService = new LoginService();
$loginService->checkLogin();
if(!admin()) {
if(!admin())
die('Access denied.');
}
// Don't attempt to process the upload on an OPTIONS request
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {

View File

@@ -26,8 +26,8 @@
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
const MYAAC = true;
const MYAAC_VERSION = '2.0-dev';
const DATABASE_VERSION = 44;
const MYAAC_VERSION = '1.0-RC.2';
const DATABASE_VERSION = 41;
const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true));
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));

View File

@@ -8,7 +8,7 @@
"ext-dom": "*",
"phpmailer/phpmailer": "^6.1",
"composer/semver": "^3.2",
"twig/twig": "^3.11",
"twig/twig": "^2.0",
"erusev/parsedown": "^1.7",
"nikic/fast-route": "^1.3",
"matomo/device-detector": "^6.0",

295
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "be4d1489a53a9cd8eec6bcaa7a096f30",
"content-hash": "27c63d07ab6337cd8bb5b59f2b2e08d8",
"packages": [
{
"name": "brick/math",
@@ -885,16 +885,16 @@
},
{
"name": "matomo/device-detector",
"version": "6.4.2",
"version": "6.4.1",
"source": {
"type": "git",
"url": "https://github.com/matomo-org/device-detector.git",
"reference": "806e52d214b05ddead1a1d4304c7592f61f95976"
"reference": "0d364e0dd6c177da3c24cd4049178026324fd7ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/806e52d214b05ddead1a1d4304c7592f61f95976",
"reference": "806e52d214b05ddead1a1d4304c7592f61f95976",
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/0d364e0dd6c177da3c24cd4049178026324fd7ac",
"reference": "0d364e0dd6c177da3c24cd4049178026324fd7ac",
"shasum": ""
},
"require": {
@@ -950,20 +950,20 @@
"source": "https://github.com/matomo-org/matomo",
"wiki": "https://dev.matomo.org/"
},
"time": "2024-12-16T16:38:01+00:00"
"time": "2024-09-24T13:50:04+00:00"
},
{
"name": "maximebf/debugbar",
"version": "v1.23.5",
"version": "v1.23.3",
"source": {
"type": "git",
"url": "https://github.com/php-debugbar/php-debugbar.git",
"reference": "eeabd61a1f19ba5dcd5ac4585a477130ee03ce25"
"url": "https://github.com/maximebf/php-debugbar.git",
"reference": "687400043d77943ef95e8417cb44e1673ee57844"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/eeabd61a1f19ba5dcd5ac4585a477130ee03ce25",
"reference": "eeabd61a1f19ba5dcd5ac4585a477130ee03ce25",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/687400043d77943ef95e8417cb44e1673ee57844",
"reference": "687400043d77943ef95e8417cb44e1673ee57844",
"shasum": ""
},
"require": {
@@ -1015,10 +1015,10 @@
"debugbar"
],
"support": {
"issues": "https://github.com/php-debugbar/php-debugbar/issues",
"source": "https://github.com/php-debugbar/php-debugbar/tree/v1.23.5"
"issues": "https://github.com/maximebf/php-debugbar/issues",
"source": "https://github.com/maximebf/php-debugbar/tree/v1.23.3"
},
"time": "2024-12-15T19:20:42+00:00"
"time": "2024-10-29T12:24:25+00:00"
},
{
"name": "mustangostang/spyc",
@@ -1076,16 +1076,16 @@
},
{
"name": "nesbot/carbon",
"version": "2.72.6",
"version": "2.72.5",
"source": {
"type": "git",
"url": "https://github.com/CarbonPHP/carbon.git",
"reference": "1e9d50601e7035a4c61441a208cb5bed73e108c5"
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "afd46589c216118ecd48ff2b95d77596af1e57ed"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/1e9d50601e7035a4c61441a208cb5bed73e108c5",
"reference": "1e9d50601e7035a4c61441a208cb5bed73e108c5",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/afd46589c216118ecd48ff2b95d77596af1e57ed",
"reference": "afd46589c216118ecd48ff2b95d77596af1e57ed",
"shasum": ""
},
"require": {
@@ -1105,7 +1105,7 @@
"doctrine/orm": "^2.7 || ^3.0",
"friendsofphp/php-cs-fixer": "^3.0",
"kylekatarnls/multi-tester": "^2.0",
"ondrejmirtes/better-reflection": "<6",
"ondrejmirtes/better-reflection": "*",
"phpmd/phpmd": "^2.9",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^0.12.99 || ^1.7.14",
@@ -1118,6 +1118,10 @@
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev",
"dev-2.x": "2.x-dev"
},
"laravel": {
"providers": [
"Carbon\\Laravel\\ServiceProvider"
@@ -1127,10 +1131,6 @@
"includes": [
"extension.neon"
]
},
"branch-alias": {
"dev-2.x": "2.x-dev",
"dev-master": "3.x-dev"
}
},
"autoload": {
@@ -1179,7 +1179,7 @@
"type": "tidelift"
}
],
"time": "2024-12-27T09:28:11+00:00"
"time": "2024-06-03T19:18:41+00:00"
},
{
"name": "nikic/fast-route",
@@ -1575,16 +1575,16 @@
},
{
"name": "symfony/console",
"version": "v6.4.17",
"version": "v6.4.15",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "799445db3f15768ecc382ac5699e6da0520a0a04"
"reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/799445db3f15768ecc382ac5699e6da0520a0a04",
"reference": "799445db3f15768ecc382ac5699e6da0520a0a04",
"url": "https://api.github.com/repos/symfony/console/zipball/f1fc6f47283e27336e7cebb9e8946c8de7bff9bd",
"reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd",
"shasum": ""
},
"require": {
@@ -1649,7 +1649,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v6.4.17"
"source": "https://github.com/symfony/console/tree/v6.4.15"
},
"funding": [
{
@@ -1665,7 +1665,7 @@
"type": "tidelift"
}
],
"time": "2024-12-07T12:07:30+00:00"
"time": "2024-11-06T14:19:14+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -1686,12 +1686,12 @@
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/contracts",
"name": "symfony/contracts"
},
"branch-alias": {
"dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
@@ -1760,8 +1760,8 @@
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
@@ -1836,8 +1836,8 @@
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
@@ -1914,8 +1914,8 @@
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
@@ -1998,8 +1998,8 @@
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
@@ -2052,6 +2052,71 @@
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce",
"reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "metapackage",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.31.0",
@@ -2072,8 +2137,8 @@
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
@@ -2132,82 +2197,6 @@
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php81",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php81\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/service-contracts",
"version": "v3.5.1",
@@ -2232,12 +2221,12 @@
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/contracts",
"name": "symfony/contracts"
},
"branch-alias": {
"dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
@@ -2491,12 +2480,12 @@
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/contracts",
"name": "symfony/contracts"
},
"branch-alias": {
"dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
@@ -2637,38 +2626,38 @@
},
{
"name": "twig/twig",
"version": "v3.19.0",
"version": "v2.16.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "d4f8c2b86374f08efc859323dbcd95c590f7124e"
"reference": "19185947ec75d433a3ac650af32fc05649b95ee1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/d4f8c2b86374f08efc859323dbcd95c590f7124e",
"reference": "d4f8c2b86374f08efc859323dbcd95c590f7124e",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/19185947ec75d433a3ac650af32fc05649b95ee1",
"reference": "19185947ec75d433a3ac650af32fc05649b95ee1",
"shasum": ""
},
"require": {
"php": ">=8.0.2",
"symfony/deprecation-contracts": "^2.5|^3",
"php": ">=7.1.3",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php81": "^1.29"
"symfony/polyfill-php72": "^1.8"
},
"require-dev": {
"phpstan/phpstan": "^2.0",
"psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
"psr/container": "^1.0",
"symfony/phpunit-bridge": "^5.4.9|^6.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.16-dev"
}
},
"autoload": {
"files": [
"src/Resources/core.php",
"src/Resources/debug.php",
"src/Resources/escaper.php",
"src/Resources/string_loader.php"
],
"psr-0": {
"Twig_": "lib/"
},
"psr-4": {
"Twig\\": "src/"
}
@@ -2701,7 +2690,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.19.0"
"source": "https://github.com/twigphp/Twig/tree/v2.16.1"
},
"funding": [
{
@@ -2713,7 +2702,7 @@
"type": "tidelift"
}
],
"time": "2025-01-29T07:06:14+00:00"
"time": "2024-09-09T17:53:56+00:00"
},
{
"name": "voku/portable-ascii",
@@ -2851,16 +2840,16 @@
"packages-dev": [
{
"name": "phpstan/phpstan",
"version": "1.12.15",
"version": "1.12.12",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "c91d4e8bc056f46cf653656e6f71004b254574d1"
"reference": "b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/c91d4e8bc056f46cf653656e6f71004b254574d1",
"reference": "c91d4e8bc056f46cf653656e6f71004b254574d1",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0",
"reference": "b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0",
"shasum": ""
},
"require": {
@@ -2905,7 +2894,7 @@
"type": "github"
}
],
"time": "2025-01-05T16:40:22+00:00"
"time": "2024-11-28T22:13:23+00:00"
}
],
"aliases": [],
@@ -2922,5 +2911,5 @@
"ext-dom": "*"
},
"platform-dev": [],
"plugin-api-version": "2.3.0"
"plugin-api-version": "2.6.0"
}

View File

@@ -116,9 +116,9 @@ describe('Check Public Pages', () => {
})
// library
it('Go to monsters page', () => {
it('Go to creatures page', () => {
cy.visit({
url: Cypress.env('URL') + '/monsters',
url: Cypress.env('URL') + '/creatures',
method: 'GET',
})
})

View File

@@ -4,7 +4,7 @@ const YOU_ARE_NOT_LOGGEDIN = 'You are not logged in.';
describe('Check Protected Pages', () => {
// character actions
it('Go to account character creation page', () => {
it('Go to accouht character creation page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/character/create',
method: 'GET',
@@ -12,7 +12,7 @@ describe('Check Protected Pages', () => {
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
it('Go to account character deletion page', () => {
it('Go to accouht character deletion page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/character/delete',
method: 'GET',
@@ -21,7 +21,7 @@ describe('Check Protected Pages', () => {
})
// account actions
it('Go to account email change page', () => {
it('Go to accouht email change page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/email',
method: 'GET',
@@ -29,7 +29,7 @@ describe('Check Protected Pages', () => {
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
it('Go to account password change page', () => {
it('Go to accouht password change page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/password',
method: 'GET',
@@ -37,7 +37,7 @@ describe('Check Protected Pages', () => {
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
it('Go to account info change page', () => {
it('Go to accouht info change page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/info',
method: 'GET',
@@ -45,7 +45,7 @@ describe('Check Protected Pages', () => {
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
it('Go to account logout change page', () => {
it('Go to accouht logout change page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/logout',
method: 'GET',

40
docker-compose.yml Normal file
View File

@@ -0,0 +1,40 @@
services:
web:
ports:
- 8001:80
build:
args:
user: www-data
uid: 33
context: ./
dockerfile: ./docker/Dockerfile
restart: unless-stopped
working_dir: /var/www/html
depends_on:
- db
#volumes:
# - ./:/var/www/html
db:
image: mysql:8.0
restart: unless-stopped # always?
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: myaac
#MYSQL_ROOT_PASSWORD: root
MYSQL_PASSWORD: myaac
MYSQL_USER: myaac
ports:
- 8003:3306
volumes:
- ./docker/tfs_schema.sql:/docker-entrypoint-initdb.d/tfs_schema.sql
- db:/var/lib/mysql
phpmyadmin:
image: phpmyadmin
restart: always
ports:
- 8002:80
volumes:
db:

56
docker/Dockerfile Normal file
View File

@@ -0,0 +1,56 @@
FROM php:8.2-apache
ARG APCU_VERSION=5.1.22
# Arguments defined in docker-compose.yml
ARG user
ARG uid
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
libzip-dev \
zip \
unzip \
nano \
vim
RUN apt-get install -y nodejs npm
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo pdo_mysql gd zip opcache
RUN docker-php-ext-configure opcache --enable-opcache
RUN pecl install apcu-${APCU_VERSION} && docker-php-ext-enable apcu
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Create system user to run Composer Commands
#RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
RUN chown -R www-data.www-data /var/www
USER $user
WORKDIR /home/$user
RUN git clone https://github.com/otland/forgottenserver.git
COPY --chown=www-data:www-data docker/config.lua /home/$user/forgottenserver
COPY --chown=www-data:www-data docker/config.local.php /var/www/html
#WORKDIR /home/$user/forgottenserver
WORKDIR /var/www/html
COPY --chown=www-data:www-data . .
RUN composer install
RUN npm install

4
docker/config.local.php Normal file
View File

@@ -0,0 +1,4 @@
<?php
$config['installed'] = false;
$config['server_path'] = '/home/www-data/forgottenserver';
$config['install_ignore_ip_check'] = true;

12
docker/config.lua Normal file
View File

@@ -0,0 +1,12 @@
serverName = "Forgotten"
mysqlHost = "db"
mysqlUser = "myaac"
mysqlPass = "myaac"
mysqlDatabase = "myaac"
mysqlPort = 3306
mysqlSock = ""
ip = "192.168.176.1"
statusPort = 7171
statusTimeout = 2000

384
docker/tfs_schema.sql Normal file
View File

@@ -0,0 +1,384 @@
CREATE TABLE IF NOT EXISTS `accounts` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`password` char(40) NOT NULL,
`secret` char(16) DEFAULT NULL,
`type` int NOT NULL DEFAULT '1',
`premium_ends_at` int unsigned NOT NULL DEFAULT '0',
`email` varchar(255) NOT NULL DEFAULT '',
`creation` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `players` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`group_id` int NOT NULL DEFAULT '1',
`account_id` int NOT NULL DEFAULT '0',
`level` int NOT NULL DEFAULT '1',
`vocation` int NOT NULL DEFAULT '0',
`health` int NOT NULL DEFAULT '150',
`healthmax` int NOT NULL DEFAULT '150',
`experience` bigint unsigned NOT NULL DEFAULT '0',
`lookbody` int NOT NULL DEFAULT '0',
`lookfeet` int NOT NULL DEFAULT '0',
`lookhead` int NOT NULL DEFAULT '0',
`looklegs` int NOT NULL DEFAULT '0',
`looktype` int NOT NULL DEFAULT '136',
`lookaddons` int NOT NULL DEFAULT '0',
`lookmount` int NOT NULL DEFAULT '0',
`lookmounthead` int NOT NULL DEFAULT '0',
`lookmountbody` int NOT NULL DEFAULT '0',
`lookmountlegs` int NOT NULL DEFAULT '0',
`lookmountfeet` int NOT NULL DEFAULT '0',
`randomizemount` tinyint NOT NULL DEFAULT '0',
`direction` tinyint unsigned NOT NULL DEFAULT '2',
`maglevel` int NOT NULL DEFAULT '0',
`mana` int NOT NULL DEFAULT '0',
`manamax` int NOT NULL DEFAULT '0',
`manaspent` bigint unsigned NOT NULL DEFAULT '0',
`soul` int unsigned NOT NULL DEFAULT '0',
`town_id` int NOT NULL DEFAULT '1',
`posx` int NOT NULL DEFAULT '0',
`posy` int NOT NULL DEFAULT '0',
`posz` int NOT NULL DEFAULT '0',
`conditions` blob DEFAULT NULL,
`cap` int NOT NULL DEFAULT '400',
`sex` int NOT NULL DEFAULT '0',
`lastlogin` bigint unsigned NOT NULL DEFAULT '0',
`lastip` varbinary(16) NOT NULL DEFAULT '0',
`save` tinyint NOT NULL DEFAULT '1',
`skull` tinyint NOT NULL DEFAULT '0',
`skulltime` bigint NOT NULL DEFAULT '0',
`lastlogout` bigint unsigned NOT NULL DEFAULT '0',
`blessings` tinyint NOT NULL DEFAULT '0',
`onlinetime` bigint NOT NULL DEFAULT '0',
`deletion` bigint NOT NULL DEFAULT '0',
`balance` bigint unsigned NOT NULL DEFAULT '0',
`offlinetraining_time` smallint unsigned NOT NULL DEFAULT '43200',
`offlinetraining_skill` int NOT NULL DEFAULT '-1',
`stamina` smallint unsigned NOT NULL DEFAULT '2520',
`skill_fist` int unsigned NOT NULL DEFAULT 10,
`skill_fist_tries` bigint unsigned NOT NULL DEFAULT 0,
`skill_club` int unsigned NOT NULL DEFAULT 10,
`skill_club_tries` bigint unsigned NOT NULL DEFAULT 0,
`skill_sword` int unsigned NOT NULL DEFAULT 10,
`skill_sword_tries` bigint unsigned NOT NULL DEFAULT 0,
`skill_axe` int unsigned NOT NULL DEFAULT 10,
`skill_axe_tries` bigint unsigned NOT NULL DEFAULT 0,
`skill_dist` int unsigned NOT NULL DEFAULT 10,
`skill_dist_tries` bigint unsigned NOT NULL DEFAULT 0,
`skill_shielding` int unsigned NOT NULL DEFAULT 10,
`skill_shielding_tries` bigint unsigned NOT NULL DEFAULT 0,
`skill_fishing` int unsigned NOT NULL DEFAULT 10,
`skill_fishing_tries` bigint unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE,
KEY `vocation` (`vocation`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `account_bans` (
`account_id` int NOT NULL,
`reason` varchar(255) NOT NULL,
`banned_at` bigint NOT NULL,
`expires_at` bigint NOT NULL,
`banned_by` int NOT NULL,
PRIMARY KEY (`account_id`),
FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `account_ban_history` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL,
`reason` varchar(255) NOT NULL,
`banned_at` bigint NOT NULL,
`expired_at` bigint NOT NULL,
`banned_by` int NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `account_storage` (
`account_id` int NOT NULL,
`key` int unsigned NOT NULL,
`value` int NOT NULL,
PRIMARY KEY (`account_id`, `key`),
FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `ip_bans` (
`ip` varbinary(16) NOT NULL,
`reason` varchar(255) NOT NULL,
`banned_at` bigint NOT NULL,
`expires_at` bigint NOT NULL,
`banned_by` int NOT NULL,
PRIMARY KEY (`ip`),
FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `player_namelocks` (
`player_id` int NOT NULL,
`reason` varchar(255) NOT NULL,
`namelocked_at` bigint NOT NULL,
`namelocked_by` int NOT NULL,
PRIMARY KEY (`player_id`),
FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`namelocked_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `account_viplist` (
`account_id` int NOT NULL COMMENT 'id of account whose viplist entry it is',
`player_id` int NOT NULL COMMENT 'id of target player of viplist entry',
`description` varchar(128) NOT NULL DEFAULT '',
`icon` tinyint unsigned NOT NULL DEFAULT '0',
`notify` tinyint NOT NULL DEFAULT '0',
UNIQUE KEY `account_player_index` (`account_id`,`player_id`),
FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE,
FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `guilds` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`ownerid` int NOT NULL,
`creationdata` int NOT NULL,
`motd` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY (`name`),
UNIQUE KEY (`ownerid`),
FOREIGN KEY (`ownerid`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `guild_invites` (
`player_id` int NOT NULL DEFAULT '0',
`guild_id` int NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`guild_id`),
FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE,
FOREIGN KEY (`guild_id`) REFERENCES `guilds` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `guild_ranks` (
`id` int NOT NULL AUTO_INCREMENT,
`guild_id` int NOT NULL COMMENT 'guild',
`name` varchar(255) NOT NULL COMMENT 'rank name',
`level` int NOT NULL COMMENT 'rank level - leader, vice, member, maybe something else',
PRIMARY KEY (`id`),
FOREIGN KEY (`guild_id`) REFERENCES `guilds` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `guild_membership` (
`player_id` int NOT NULL,
`guild_id` int NOT NULL,
`rank_id` int NOT NULL,
`nick` varchar(15) NOT NULL DEFAULT '',
PRIMARY KEY (`player_id`),
FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`guild_id`) REFERENCES `guilds` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`rank_id`) REFERENCES `guild_ranks` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `guild_wars` (
`id` int NOT NULL AUTO_INCREMENT,
`guild1` int NOT NULL DEFAULT '0',
`guild2` int NOT NULL DEFAULT '0',
`name1` varchar(255) NOT NULL,
`name2` varchar(255) NOT NULL,
`status` tinyint NOT NULL DEFAULT '0',
`started` bigint NOT NULL DEFAULT '0',
`ended` bigint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `guild1` (`guild1`),
KEY `guild2` (`guild2`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `guildwar_kills` (
`id` int NOT NULL AUTO_INCREMENT,
`killer` varchar(50) NOT NULL,
`target` varchar(50) NOT NULL,
`killerguild` int NOT NULL DEFAULT '0',
`targetguild` int NOT NULL DEFAULT '0',
`warid` int NOT NULL DEFAULT '0',
`time` bigint NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`warid`) REFERENCES `guild_wars` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `houses` (
`id` int NOT NULL AUTO_INCREMENT,
`owner` int NOT NULL,
`paid` int unsigned NOT NULL DEFAULT '0',
`warnings` int NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`rent` int NOT NULL DEFAULT '0',
`town_id` int NOT NULL DEFAULT '0',
`bid` int NOT NULL DEFAULT '0',
`bid_end` int NOT NULL DEFAULT '0',
`last_bid` int NOT NULL DEFAULT '0',
`highest_bidder` int NOT NULL DEFAULT '0',
`size` int NOT NULL DEFAULT '0',
`beds` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `owner` (`owner`),
KEY `town_id` (`town_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `house_lists` (
`house_id` int NOT NULL,
`listid` int NOT NULL,
`list` text NOT NULL,
FOREIGN KEY (`house_id`) REFERENCES `houses` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `market_history` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`player_id` int NOT NULL,
`sale` tinyint NOT NULL DEFAULT '0',
`itemtype` smallint unsigned NOT NULL,
`amount` smallint unsigned NOT NULL,
`price` bigint unsigned NOT NULL DEFAULT '0',
`expires_at` bigint unsigned NOT NULL,
`inserted` bigint unsigned NOT NULL,
`state` tinyint unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `player_id` (`player_id`, `sale`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `market_offers` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`player_id` int NOT NULL,
`sale` tinyint NOT NULL DEFAULT '0',
`itemtype` smallint unsigned NOT NULL,
`amount` smallint unsigned NOT NULL,
`created` bigint unsigned NOT NULL,
`anonymous` tinyint NOT NULL DEFAULT '0',
`price` bigint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `sale` (`sale`,`itemtype`),
KEY `created` (`created`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `players_online` (
`player_id` int NOT NULL,
PRIMARY KEY (`player_id`)
) ENGINE=MEMORY DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `player_deaths` (
`player_id` int NOT NULL,
`time` bigint unsigned NOT NULL DEFAULT '0',
`level` int NOT NULL DEFAULT '1',
`killed_by` varchar(255) NOT NULL,
`is_player` tinyint NOT NULL DEFAULT '1',
`mostdamage_by` varchar(100) NOT NULL,
`mostdamage_is_player` tinyint NOT NULL DEFAULT '0',
`unjustified` tinyint NOT NULL DEFAULT '0',
`mostdamage_unjustified` tinyint NOT NULL DEFAULT '0',
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE,
KEY `killed_by` (`killed_by`),
KEY `mostdamage_by` (`mostdamage_by`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `player_depotitems` (
`player_id` int NOT NULL,
`sid` int NOT NULL COMMENT 'any given range eg 0-100 will be reserved for depot lockers and all > 100 will be then normal items inside depots',
`pid` int NOT NULL DEFAULT '0',
`itemtype` smallint unsigned NOT NULL,
`count` smallint NOT NULL DEFAULT '0',
`attributes` blob NOT NULL,
UNIQUE KEY `player_id_2` (`player_id`, `sid`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `player_inboxitems` (
`player_id` int NOT NULL,
`sid` int NOT NULL,
`pid` int NOT NULL DEFAULT '0',
`itemtype` smallint unsigned NOT NULL,
`count` smallint NOT NULL DEFAULT '0',
`attributes` blob NOT NULL,
UNIQUE KEY `player_id_2` (`player_id`, `sid`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `player_storeinboxitems` (
`player_id` int NOT NULL,
`sid` int NOT NULL,
`pid` int NOT NULL DEFAULT '0',
`itemtype` smallint unsigned NOT NULL,
`count` smallint NOT NULL DEFAULT '0',
`attributes` blob NOT NULL,
UNIQUE KEY `player_id_2` (`player_id`, `sid`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `player_items` (
`player_id` int NOT NULL DEFAULT '0',
`pid` int NOT NULL DEFAULT '0',
`sid` int NOT NULL DEFAULT '0',
`itemtype` smallint unsigned NOT NULL DEFAULT '0',
`count` smallint NOT NULL DEFAULT '0',
`attributes` blob NOT NULL,
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE,
KEY `sid` (`sid`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `player_spells` (
`player_id` int NOT NULL,
`name` varchar(255) NOT NULL,
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `player_storage` (
`player_id` int NOT NULL DEFAULT '0',
`key` int unsigned NOT NULL DEFAULT '0',
`value` int NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`key`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `server_config` (
`config` varchar(50) NOT NULL,
`value` varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY `config` (`config`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `tile_store` (
`house_id` int NOT NULL,
`data` longblob NOT NULL,
FOREIGN KEY (`house_id`) REFERENCES `houses` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE IF NOT EXISTS `towns` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`posx` int NOT NULL DEFAULT '0',
`posy` int NOT NULL DEFAULT '0',
`posz` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '35'), ('players_record', '0');
DROP TRIGGER IF EXISTS `ondelete_players`;
DROP TRIGGER IF EXISTS `oncreate_guilds`;
DELIMITER //
CREATE TRIGGER `ondelete_players` BEFORE DELETE ON `players`
FOR EACH ROW BEGIN
UPDATE `houses` SET `owner` = 0 WHERE `owner` = OLD.`id`;
END
//
CREATE TRIGGER `oncreate_guilds` AFTER INSERT ON `guilds`
FOR EACH ROW BEGIN
INSERT INTO `guild_ranks` (`name`, `level`, `guild_id`) VALUES ('the Leader', 3, NEW.`id`);
INSERT INTO `guild_ranks` (`name`, `level`, `guild_id`) VALUES ('a Vice-Leader', 2, NEW.`id`);
INSERT INTO `guild_ranks` (`name`, `level`, `guild_id`) VALUES ('a Member', 1, NEW.`id`);
END
//
DELIMITER ;

155
index.php
View File

@@ -24,7 +24,160 @@
* @link https://my-aac.org
*/
use MyAAC\UsageStatistics;
use MyAAC\Visitors;
require_once 'common.php';
require_once SYSTEM . 'functions.php';
app()->run();
$uri = $_SERVER['REQUEST_URI'];
if(false !== strpos($uri, 'index.php')) {
$uri = str_replace_first('/index.php', '', $uri);
}
if(0 === strpos($uri, '/')) {
$uri = str_replace_first('/', '', $uri);
}
if(preg_match("/^[A-Za-z0-9-_%'+\/]+\.png$/i", $uri)) {
if (!empty(BASE_DIR)) {
$tmp = explode('.', str_replace_first(str_replace_first('/', '', BASE_DIR) . '/', '', $uri));
}
else {
$tmp = explode('.', $uri);
}
$_REQUEST['name'] = urldecode($tmp[0]);
chdir(TOOLS . 'signature');
include TOOLS . 'signature/index.php';
exit();
}
if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) {
http_response_code(404);
exit;
}
if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install'))
{
header('Location: ' . BASE_URL . 'install/');
exit();
}
$template_place_holders = array();
require_once SYSTEM . 'init.php';
require_once SYSTEM . 'template.php';
require_once SYSTEM . 'login.php';
require_once SYSTEM . 'status.php';
$twig->addGlobal('config', $config);
$twig->addGlobal('status', $status);
// backward support for gesior
if(setting('core.backward_support')) {
define('INITIALIZED', true);
$SQL = $db;
$layout_header = template_header();
$layout_name = $template_path;
$news_content = '';
$tickers_content = '';
$main_content = '';
$config['access_admin_panel'] = 2;
$group_id_of_acc_logged = 0;
if($logged && $account_logged)
$group_id_of_acc_logged = $account_logged->getGroupId();
$config['site'] = &$config;
$config['server'] = &$config['lua'];
$config['site']['shop_system'] = setting('core.gifts_system');
$config['site']['gallery_page'] = true;
if(!isset($config['vdarkborder']))
$config['vdarkborder'] = '#505050';
if(!isset($config['darkborder']))
$config['darkborder'] = '#D4C0A1';
if(!isset($config['lightborder']))
$config['lightborder'] = '#F1E0C6';
$config['site']['download_page'] = true;
$config['site']['serverinfo_page'] = true;
$config['site']['screenshot_page'] = true;
$forumSetting = setting('core.forum');
if($forumSetting != '')
$config['forum_link'] = (strtolower($forumSetting) === 'site' ? getLink('forum') : $forumSetting);
foreach($status as $key => $value)
$config['status']['serverStatus_' . $key] = $value;
}
require_once SYSTEM . 'router.php';
$hooks->trigger(HOOK_STARTUP);
// anonymous usage statistics
// sent only when user agrees
if(setting('core.anonymous_usage_statistics')) {
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days
$should_report = true;
$value = '';
if($cache->enabled() && $cache->fetch('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
}
else {
$value = '';
if(fetchDatabaseConfig('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
if($cache->enabled()) {
$cache->set('last_usage_report', $value);
}
}
else {
registerDatabaseConfig('last_usage_report', time() - ($report_time - (7 * 24 * 60 * 60))); // first report after a week
$should_report = false;
}
}
if($should_report) {
UsageStatistics::report();
updateDatabaseConfig('last_usage_report', time());
if($cache->enabled()) {
$cache->set('last_usage_report', time());
}
}
}
if(setting('core.views_counter'))
require_once SYSTEM . 'counter.php';
if(setting('core.visitors_counter')) {
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
}
/**
* @var OTS_Account $account_logged
*/
if ($logged && admin()) {
$content .= $twig->render('admin-bar.html.twig', [
'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()
]);
}
$title_full = (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];
require $template_path . '/' . $template_index;
echo base64_decode('PCEtLSBQb3dlcmVkIGJ5IE15QUFDIDo6IGh0dHBzOi8vd3d3Lm15LWFhYy5vcmcvIC0tPg==') . PHP_EOL;
if(superAdmin()) {
echo '<!-- Generated in: ' . round(microtime(true) - START_TIME, 4) . 'ms -->';
echo PHP_EOL . '<!-- Queries done: ' . $db->queries() . ' -->';
if(function_exists('memory_get_peak_usage')) {
echo PHP_EOL . '<!-- Peak memory usage: ' . convert_bytes(memory_get_peak_usage(true)) . ' -->';
}
}
$hooks->trigger(HOOK_FINISH);

View File

@@ -2,9 +2,7 @@
defined('MYAAC') or die('Direct access not allowed!');
function query($query)
{
global $error;
$db = app()->get('database');
global $db, $error;
try {
$db->query($query);

View File

@@ -1,13 +1,13 @@
SET @myaac_database_version = 43;
SET @myaac_database_version = 41;
CREATE TABLE `myaac_account_actions`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`account_id` INT(11) NOT NULL,
`ip` VARCHAR(45) NOT NULL DEFAULT '',
`ip` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`ipv6` BINARY(16) NOT NULL DEFAULT 0,
`date` INT(11) NOT NULL DEFAULT 0,
`action` VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
KEY (`account_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_admin_menu`
@@ -91,7 +91,7 @@ CREATE TABLE `myaac_forum`
`post_date` int(20) NOT NULL default '0',
`last_edit_aid` int(20) NOT NULL default '0',
`edit_date` int(20) NOT NULL default '0',
`post_ip` varchar(45) NOT NULL default '0.0.0.0',
`post_ip` varchar(32) NOT NULL default '0.0.0.0',
`sticked` tinyint(1) NOT NULL DEFAULT '0',
`closed` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),

View File

@@ -195,7 +195,7 @@ if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) {
}
}
if(!$allow)
if(!$allow && !config('install_ignore_ip_check'))
{
$content = warning('In file <b>install/ip.txt</b> must be your IP!<br/>
In file is:<br /><b>' . nl2br($file_content) . '</b><br/>

View File

@@ -11,6 +11,7 @@ foreach($config['clients'] as $client) {
}
$twig->display('install.config.html.twig', array(
'config' => $config,
'clients' => $clients,
'timezones' => DateTimeZone::listIdentifiers(),
'locale' => $locale,

View File

@@ -41,6 +41,9 @@ if(!$error) {
$configToSave['cache_engine'] = 'auto';
$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true);
$configToSave['database_auto_migrate'] = true;
if (isset($config['install_ignore_ip_check'])) {
$configToSave['install_ignore_ip_check'] = $config['install_ignore_ip_check'];
}
if(!$error) {
$content = '';
@@ -77,7 +80,7 @@ if(!$error) {
$_SESSION['config_content'] = $content;
unset($_SESSION['saved']);
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.php</b>', $locale['step_database_error_file']);
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
error($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>');
}

View File

@@ -12,7 +12,7 @@ if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['save
return;
}
$cache = app()->get('cache');
$cache = Cache::getInstance();
if ($cache->enabled()) {
// clear plugin_hooks to have fresh hooks
$cache->delete('plugins_hooks');
@@ -58,7 +58,7 @@ if ($db->hasTable('players')) {
$player_used = &$player_db;
}
$groups = app()->get('groups');
$groups = new OTS_Groups_List();
$player_used->setGroupId($groups->getHighestId());
}

View File

@@ -1,4 +1,3 @@
<?php defined('MYAAC') or die('Direct access not allowed!'); ?>
<!DOCTYPE html>
<html dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>">
<head>

View File

@@ -156,14 +156,9 @@ if ($db->hasTable('guilds')) {
}
if (!$db->hasColumn('guilds', 'description')) {
if (query("ALTER TABLE `guilds` ADD `description` VARCHAR(5000) NOT NULL DEFAULT '';"))
if (query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' guilds.description...');
}
else {
if (query("ALTER TABLE `guilds` MODIFY `description` VARCHAR(5000) NOT NULL DEFAULT '';")) {
success($locale['step_database_modifying_field'] . ' guilds.description...');
}
}
if ($db->hasColumn('guilds', 'logo_gfx_name')) {
if (query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) {
@@ -202,14 +197,9 @@ if ($db->hasTable('players')) {
}
if (!$db->hasColumn('players', 'comment')) {
if (query("ALTER TABLE `players` ADD `comment` VARCHAR(5000) NOT NULL DEFAULT '';"))
if (query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
else {
if (query("ALTER TABLE `players` MODIFY `comment` VARCHAR(5000) NOT NULL DEFAULT '';")) {
success($locale['step_database_modifying_field'] . ' players.comment...');
}
}
if ($db->hasColumn('players', 'rank_id')) {
if (query("ALTER TABLE players MODIFY `rank_id` INT(11) NOT NULL DEFAULT 0;"))

View File

@@ -33,9 +33,7 @@ if ($db->hasTable('players')) {
$time = time();
function insert_sample_if_not_exist($p)
{
global $success, $deleted, $time;
$db = app()->get('database');
global $db, $success, $deleted, $time;
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote($p['name']));
if ($query->rowCount() == 0) {

View File

@@ -12,6 +12,10 @@ server {
deny all;
}
location /vendor {
deny all;
}
# block .htaccess, CHANGELOG.md, composer.json etc.
# this is to prevent finding software versions
location ~\.(ht|md|json|dist)$ {
@@ -24,7 +28,7 @@ server {
}
location / {
try_files $uri $uri/ /index.php?$query_string;
try_files $uri $uri/ /index.php?$query_string;;
}
location ~ \.php$ {

905
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
"postinstall": "node ./npm-post-install.js"
},
"devDependencies": {
"cypress": "^13.17.0"
"cypress": "^12.12.0"
},
"dependencies": {
"@tinymce/tinymce-jquery": "^2.1.0",
@@ -12,6 +12,6 @@
"fs-extra": "^11.2.0",
"jquery": "^3.7.1",
"jquery-ui": "^1.13.2",
"tinymce": "^7.2.0"
"tinymce": "^6.8.3"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "create-account-hint",
"description": "This plugin display text 'To play on Forgotten you need an account. All you have to do to create your new account is to enter an account name, password, country and your email address. Also you have to agree to the terms presented below. If you have done so, your account name will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.' on the create account page.",
"description": "This plugin display text 'To play on Forgotten you need an account. All you have to do to create your new account is to enter an account name, password, country and your email address. Also you have to agree to the terms presented below. If you have done so, your account name will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.' on the create account page. <strong>Be careful when uninstalling this!</strong>",
"version": "1.0",
"author": "slawkens",
"contact": "slawkens@gmail.com",

View File

@@ -9,4 +9,7 @@
*/
defined('MYAAC') or die('Direct access not allowed!');
$twig->display('account-create-hint/hint.html.twig');
global $twig_loader;
$twig_loader->prependPath(BASE . 'plugins/account-create-hint');
$twig->display('hint.html.twig');

View File

@@ -22,7 +22,7 @@ if [ $1 = "prepare" ]; then
mkdir -p tmp
# get myaac from git archive
git archive --format zip --output tmp/myaac.zip main
git archive --format zip --output tmp/myaac.zip develop
cd tmp/ || exit

View File

@@ -9,6 +9,72 @@
*/
defined('MYAAC') or die('Direct access not allowed!');
class Validator extends \MyAAC\Validator {}
function check_name($name, &$errors = '') {
if(Validator::characterName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function check_account_id($id, &$errors = '') {
if(Validator::accountId($id))
return true;
$errors = Validator::getLastError();
return false;
}
function check_account_name($name, &$errors = '') {
if(Validator::accountName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function check_name_new_char($name, &$errors = '') {
if(Validator::newCharacterName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function check_rank_name($name, &$errors = '') {
if(Validator::rankName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function check_guild_name($name, &$errors = '') {
if(Validator::guildName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function news_place() {
return tickers();
}
function tableExist($table)
{
global $db;
return $db->hasTable($table);
}
function fieldExist($field, $table)
{
global $db;
return $db->hasColumn($table, $field);
}
function getCreatureImgPath($creature): string {
return getMonsterImgPath($creature);
}

View File

@@ -38,4 +38,3 @@ class GuildRank extends OTS_GuildRank {}
class House extends OTS_House {}
class Cache extends \MyAAC\Cache\Cache {}
class Validator extends \MyAAC\Validator {}

60
system/compat/pages.php Normal file
View File

@@ -0,0 +1,60 @@
<?php
/**
* Compat pages (backward support for Gesior AAC)
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
switch($page)
{
case 'adminpanel':
header('Location: ' . ADMIN_URL);
die;
case 'createaccount':
$page = 'account/create';
break;
case 'accountmanagement':
$page = 'account/manage';
break;
case 'lostaccount':
$page = 'account/lost';
break;
case 'whoisonline':
$page = 'online';
break;
case 'latestnews':
$page = 'news';
break;
case 'archive':
case 'newsarchive':
$page = 'news/archive';
break;
case 'tibiarules':
$page = 'rules';
break;
case 'killstatistics':
$page = 'last-kills';
break;
case 'buypoints':
$page = 'points';
break;
case 'shopsystem':
$page = 'gifts';
break;
default:
break;
}

View File

@@ -15,7 +15,7 @@ define('COUNTER_SYNC', 10); // how often counter is synchronized with database (
$views_counter = 1; // default value, must be here!
$cache = app()->get('cache');
$cache = Cache::getInstance();
if($cache->enabled())
{
$value = 0;

141
system/database.php Normal file
View File

@@ -0,0 +1,141 @@
<?php
/**
* Database connection
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use Illuminate\Database\Capsule\Manager as Capsule;
defined('MYAAC') or die('Direct access not allowed!');
if (!isset($config['database_overwrite'])) {
$config['database_overwrite'] = false;
}
if(!$config['database_overwrite'] && !isset($config['database_user'][0], $config['database_password'][0], $config['database_name'][0]))
{
if(isset($config['lua']['sqlType'])) {// tfs 0.3
if(isset($config['lua']['mysqlHost'])) {// tfs 0.2
$config['otserv_version'] = TFS_02;
$config['database_type'] = 'mysql';
$config['database_host'] = $config['lua']['mysqlHost'];
$config['database_port'] = $config['lua']['mysqlPort'];
$config['database_user'] = $config['lua']['mysqlUser'];
$config['database_password'] = $config['lua']['mysqlPass'];
$config['database_name'] = $config['lua']['mysqlDatabase'];
$config['database_encryption'] = $config['lua']['passwordType'];
}
else {
$config['otserv_version'] = TFS_03;
$config['database_type'] = $config['lua']['sqlType'];
$config['database_host'] = $config['lua']['sqlHost'];
$config['database_port'] = $config['lua']['sqlPort'];
$config['database_user'] = $config['lua']['sqlUser'];
$config['database_password'] = $config['lua']['sqlPass'];
$config['database_name'] = $config['lua']['sqlDatabase'];
$config['database_encryption'] = $config['lua']['encryptionType'];
if(!isset($config['database_encryption']) || empty($config['database_encryption'])) // before 0.3.6
$config['database_encryption'] = $config['lua']['passwordType'];
}
}
else if(isset($config['lua']['mysqlHost'])) // tfs 1.0
{
$config['otserv_version'] = TFS_02;
$config['database_type'] = 'mysql';
$config['database_host'] = $config['lua']['mysqlHost'];
$config['database_port'] = $config['lua']['mysqlPort'];
$config['database_user'] = $config['lua']['mysqlUser'];
$config['database_password'] = $config['lua']['mysqlPass'];
$config['database_name'] = $config['lua']['mysqlDatabase'];
if(!isset($config['database_socket'][0])) {
$config['database_socket'] = isset($config['lua']['mysqlSock']) ? trim($config['lua']['mysqlSock']) : '';
}
$config['database_encryption'] = 'sha1';
}
else if(isset($config['lua']['database_type'])) // otserv
{
$config['otserv_version'] = OTSERV;
$config['database_type'] = $config['lua']['database_type'];
$config['database_host'] = $config['lua']['database_host'];
$config['database_port'] = $config['lua']['database_port'];
$config['database_user'] = $config['lua']['database_username'];
$config['database_password'] = $config['lua']['database_password'];
$config['database_name'] = $config['lua']['database_schema'];
$config['database_encryption'] = isset($config['lua']['passwordtype']) ? $config['lua']['passwordtype'] : $config['lua']['password_type'];
$config['database_salt'] = isset($config['lua']['passwordsalt']) ? $config['lua']['passwordsalt'] : $config['lua']['password_salt'];
}
else if(isset($config['lua']['sql_host'])) // otserv 0.6.3 / 0.6.4
{
$config['otserv_version'] = OTSERV_06;
$config['database_type'] = $config['lua']['sql_type'];
$config['database_host'] = $config['lua']['sql_host'];
$config['database_port'] = $config['lua']['sql_port'];
$config['database_user'] = $config['lua']['sql_user'];
$config['database_password'] = $config['lua']['sql_pass'];
$config['database_name'] = $config['lua']['sql_db'];
$config['database_encryption'] = isset($config['lua']['passwordtype']) ? $config['lua']['passwordtype'] : $config['lua']['password_type'];
$config['database_salt'] = isset($config['lua']['passwordsalt']) ? $config['lua']['passwordsalt'] : $config['lua']['password_salt'];
}
}
if(isset($config['lua']['useMD5Passwords']) && getBoolean($config['lua']['useMD5Passwords']))
$config['database_encryption'] = 'md5';
if(!isset($config['database_log'])) {
$config['database_log'] = false;
}
if(!isset($config['database_socket'])) {
$config['database_socket'] = '';
}
try {
$ots->connect(array(
'host' => $config['database_host'],
'user' => $config['database_user'],
'password' => $config['database_password'],
'database' => $config['database_name'],
'log' => $config['database_log'],
'socket' => @$config['database_socket'],
'persistent' => @$config['database_persistent']
));
global $db;
$db = POT::getInstance()->getDBHandle();
$capsule = new Capsule;
$capsule->addConnection([
'driver' => 'mysql',
'database' => $config['database_name'],
]);
$capsule->getConnection()->setPdo($db);
$capsule->getConnection()->setReadPdo($db);
$capsule->setAsGlobal();
$capsule->bootEloquent();
$eloquentConnection = $capsule->getConnection();
} catch (Exception $e) {
if(isset($cache) && $cache->enabled()) {
$cache->delete('config_lua');
}
if(defined('MYAAC_INSTALL')) {
$error = $e->getMessage();
return; // installer will take care of this
}
throw new RuntimeException('ERROR: Cannot connect to MySQL database.<br/>' .
'Possible reasons:' .
'<ul>' .
'<li>MySQL is not configured propertly in <i>config.lua</i>.</li>' .
'<li>MySQL server is not running.</li>' .
'</ul>' . $e->getMessage());
}

View File

@@ -9,16 +9,16 @@
*/
use MyAAC\Exceptions\SensitiveException;
use Whoops\Handler\PlainTextHandler;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Run;
if (class_exists(Run::class)) {
$whoops = new Run;
if (class_exists(\Whoops\Run::class)) {
$whoops = new \Whoops\Run;
if(IS_CLI) {
$whoops->pushHandler(new \Whoops\Handler\PlainTextHandler);
}
else {
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
}
$whoopsHandler = IS_CLI ? (new PlainTextHandler()) : (new PrettyPageHandler());
$whoops->pushHandler($whoopsHandler);
$whoops->register();
return;
}

View File

@@ -9,7 +9,6 @@
*/
defined('MYAAC') or die('Direct access not allowed!');
use MyAAC\App\App;
use MyAAC\Cache\Cache;
use MyAAC\CsrfToken;
use MyAAC\Items;
@@ -50,7 +49,7 @@ function warning($message, $return = false) {
return message($message, 'warning', $return);
}
function note($message, $return = false) {
return message($message, 'note', $return);
return info($message, $return);
}
function info($message, $return = false) {
return message($message, 'info', $return);
@@ -122,7 +121,7 @@ function getPlayerLink($name, $generate = true, bool $colored = false): string
function getMonsterLink($name, $generate = true): string
{
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'monsters?name=' . urlencode($name);
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'monsters/' . urlencode($name);
if(!$generate) return $url;
return generateLink($url, $name);
@@ -130,14 +129,16 @@ function getMonsterLink($name, $generate = true): string
function getHouseLink($name, $generate = true): string
{
if(is_numeric($name)) {
if(is_numeric($name))
{
$house = House::find(intval($name), ['name']);
if ($house) {
$name = $house->name;
}
}
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses?name=' . urlencode($name);
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses/' . urlencode($name);
if(!$generate) return $url;
return generateLink($url, $name);
@@ -275,10 +276,7 @@ function generateRandomString($length, $lowCase = true, $upCase = false, $numeri
*/
function getForumBoards()
{
global $canEdit;
$db = app()->get('database');
global $db, $canEdit;
$sections = $db->query('SELECT `id`, `name`, `description`, `closed`, `guild`, `access`' . ($canEdit ? ', `hide`, `ordering`' : '') . ' FROM `' . TABLE_PREFIX . 'forum_boards` ' . (!$canEdit ? ' WHERE `hide` != 1' : '') .
' ORDER BY `ordering`;');
if($sections)
@@ -354,12 +352,13 @@ function updateDatabaseConfig($name, $value)
*/
function encrypt($str)
{
$configDatabaseSalt = config('database_salt');
if(isset($configDatabaseSalt)) // otserv
$str .= $configDatabaseSalt;
global $config;
if(isset($config['database_salt'])) // otserv
$str .= $config['database_salt'];
$encryptionType = config('database_encryption');
if(isset($encryptionType) && strtolower($encryptionType) !== 'plain') {
$encryptionType = $config['database_encryption'];
if(isset($encryptionType) && strtolower($encryptionType) !== 'plain')
{
if($encryptionType === 'vahash')
return base64_encode(hash('sha256', $str));
@@ -435,7 +434,7 @@ function delete_guild($id)
if(count($rank_list) > 0) {
$rank_list->orderBy('level');
$db = app()->get('database');
global $db;
/**
* @var OTS_GuildRank $rank_in_guild
*/
@@ -497,11 +496,9 @@ function tickers()
*/
function template_place_holder($type): string
{
global $template_place_holders, $debugBar;
global $twig, $template_place_holders, $debugBar;
$ret = '';
$twig = app()->get('twig');
if (isset($debugBar)) {
$debugBarRenderer = $debugBar->getJavascriptRenderer();
}
@@ -533,11 +530,9 @@ function template_place_holder($type): string
*/
function template_header($is_admin = false): string
{
global $title_full;
global $title_full, $twig;
$charset = setting('core.charset') ?? 'utf-8';
$twig = app()->get('twig');
return $twig->render('templates.header.html.twig',
[
'charset' => $charset,
@@ -552,44 +547,38 @@ function template_header($is_admin = false): string
*/
function template_footer(): string
{
$footer = [];
global $views_counter;
$ret = '';
if(admin()) {
$footer[] = generateLink(ADMIN_URL, 'Admin Panel', true);
$ret .= generateLink(ADMIN_URL, 'Admin Panel', true);
}
if(setting('core.visitors_counter')) {
global $visitors;
$amount = $visitors->getAmountVisitors();
$footer[] = 'Currently there ' . ($amount > 1 ? 'are' : 'is') . ' ' . $amount . ' visitor' . ($amount > 1 ? 's' : '') . '.';
$ret .= '<br/>Currently there ' . ($amount > 1 ? 'are' : 'is') . ' ' . $amount . ' visitor' . ($amount > 1 ? 's' : '') . '.';
}
if(setting('core.views_counter')) {
global $views_counter;
$footer[] = 'Page has been viewed ' . $views_counter . ' times.';
$ret .= '<br/>Page has been viewed ' . $views_counter . ' times.';
}
if(setting('core.footer_load_time')) {
$footer[] = 'Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.';
$ret .= '<br/>Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.';
}
$settingFooter = setting('core.footer');
if(isset($settingFooter[0])) {
$footer[] = '' . $settingFooter;
$ret .= '<br/>' . $settingFooter;
}
// please respect my work and help spreading the word, thanks!
$footer[] = base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=');
$hooks = app()->get('hooks');
$footer = $hooks->triggerFilter(HOOK_FILTER_THEME_FOOTER, $footer);
return implode('<br/>', $footer);
return $ret . '<br/>' . base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=');
}
function template_ga_code()
{
$twig = app()->get('twig');
global $twig;
if(!isset(setting('core.google_analytics_id')[0]))
return '';
@@ -600,20 +589,34 @@ function template_form()
{
global $template_name;
$templates = Cache::remember('templates', 5 * 60, function() {
return get_templates();
});
$cache = Cache::getInstance();
if($cache->enabled())
{
$tmp = '';
if($cache->fetch('templates', $tmp)) {
$templates = unserialize($tmp);
}
else
{
$templates = get_templates();
$cache->set('templates', serialize($templates), 30);
}
}
else
$templates = get_templates();
$options = '';
foreach($templates as $value)
foreach($templates as $key => $value)
$options .= '<option ' . ($template_name == $value ? 'SELECTED' : '') . '>' . $value . '</option>';
$twig = app()->get('twig');
global $twig;
return $twig->render('forms.change_template.html.twig', ['options' => $options]);
}
function getStyle($i) {
return is_int($i / 2) ? config('darkborder') : config('lightborder');
function getStyle($i)
{
global $config;
return is_int($i / 2) ? $config['darkborder'] : $config['lightborder'];
}
$vowels = array('e', 'y', 'u', 'i', 'o', 'a');
@@ -723,20 +726,13 @@ function getSkillName($skillId, $suffix = true)
return 'unknown';
}
function logged(): bool {
return app()->isLoggedIn();
}
function accountLogged(): OTS_Account {
$loggedAccount = app()->getAccountLogged();
return $loggedAccount ?? new OTS_Account();
}
/**
* Performs flag check on the current logged in user.
* Table in database: accounts, field: website_flags
*/
function hasFlag(int $flag): bool {
return (logged() && (accountLogged()->getWebFlags() & $flag) == $flag);
global $logged, $logged_flags;
return ($logged && ($logged_flags & $flag) == $flag);
}
/**
* Check if current logged user have got admin flag set.
@@ -879,7 +875,7 @@ function getWorldName($id)
*/
function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
{
global $mailer;
global $mailer, $config;
if (!setting('core.mail_enabled')) {
log_append('mailer-error.log', '_mail() function has been used, but Mail Support is disabled.');
@@ -931,7 +927,7 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->From = setting('core.mail_address');
$mailer->Sender = setting('core.mail_address');
$mailer->CharSet = 'utf-8';
$mailer->FromName = configLua('serverName');
$mailer->FromName = $config['lua']['serverName'];
$mailer->Subject = $subject;
$mailer->addAddress($to);
$mailer->Body = $tmp_body;
@@ -1000,29 +996,31 @@ function load_config_lua($filename)
continue;
}
$tmp_exp = explode('=', $line, 2);
if(str_contains($line, 'dofile')) {
if(strpos($line, 'dofile') !== false)
{
$delimiter = '"';
if(!str_contains($line, $delimiter)) {
if(strpos($line, $delimiter) === false)
$delimiter = "'";
}
$tmp = explode($delimiter, $line);
$result = array_merge($result, load_config_lua($config['server_path'] . $tmp[1]));
}
else if(count($tmp_exp) >= 2) {
else if(count($tmp_exp) >= 2)
{
$key = trim($tmp_exp[0]);
if(!str_starts_with($key, '--')) {
if(0 !== strpos($key, '--'))
{
$value = trim($tmp_exp[1]);
if(str_contains($value, '--')) {// found some deep comment
if(strpos($value, '--') !== false) {// found some deep comment
$value = preg_replace('/--.*$/i', '', $value);
}
if(is_numeric($value))
$result[$key] = (float) $value;
elseif(in_array(@$value[0], array("'", '"')) && in_array(@$value[strlen($value) - 1], array("'", '"')))
$result[$key] = substr(substr($value, 1), 0, -1);
$result[$key] = (string) substr(substr($value, 1), 0, -1);
elseif(in_array($value, array('true', 'false')))
$result[$key] = $value === 'true';
$result[$key] = ($value === 'true') ? true : false;
elseif(@$value[0] === '{') {
// arrays are not supported yet
// just ignore the error
@@ -1030,7 +1028,7 @@ function load_config_lua($filename)
}
else
{
foreach($result as $tmp_key => $tmp_value) // load values defined by other keys, like: dailyFragsToBlackSkull = dailyFragsToRedSkull
foreach($result as $tmp_key => $tmp_value) // load values definied by other keys, like: dailyFragsToBlackSkull = dailyFragsToRedSkull
$value = str_replace($tmp_key, $tmp_value, $value);
$ret = @eval("return $value;");
if((string) $ret == '' && trim($value) !== '""') // = parser error
@@ -1044,7 +1042,8 @@ function load_config_lua($filename)
}
}
return array_merge($result, $config['lua'] ?? []);
$result = array_merge($result, isset($config['lua']) ? $config['lua'] : array());
return $result;
}
function str_replace_first($search,$replace, $subject) {
@@ -1070,36 +1069,17 @@ function get_browser_real_ip() {
return '0';
}
function setSession($key, $value = null): void {
if (!is_array($key)) {
$key = [$key => $value];
}
foreach ($key as $arrayKey => $arrayValue) {
if (is_null($arrayValue)) {
unsetSession($arrayKey);
}
else {
$_SESSION[setting('core.session_prefix') . $arrayKey] = $arrayValue;
}
}
function setSession($key, $data) {
$_SESSION[setting('core.session_prefix') . $key] = $data;
}
function getSession($key) {
return $_SESSION[setting('core.session_prefix') . $key] ?? null;
$key = setting('core.session_prefix') . $key;
return isset($_SESSION[$key]) ? $_SESSION[$key] : false;
}
function unsetSession($key): void {
function unsetSession($key) {
unset($_SESSION[setting('core.session_prefix') . $key]);
}
function session($key): mixed {
if (is_array($key)) {
setSession($key);
return null;
}
return getSession($key);
}
function csrf(bool $return = false): string {
return CsrfToken::create($return);
}
@@ -1122,16 +1102,20 @@ function csrfProtect(): void
}
}
function getTopPlayers($limit = 5, $skill = 'level') {
$db = app()->get('database');
function getTopPlayers($limit = 5) {
global $db;
if ($skill === 'level') {
$skill = 'experience';
$cache = Cache::getInstance();
if($cache->enabled()) {
$tmp = '';
if($cache->fetch('top_' . $limit . '_level', $tmp)) {
$players = unserialize($tmp);
}
}
return Cache::remember("top_{$limit}_{$skill}", 2 * 60, function () use ($db, $limit, $skill) {
if (!isset($players)) {
$columns = [
'id', 'name', 'level', 'vocation', 'experience', 'balance',
'id', 'name', 'level', 'vocation', 'experience',
'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet'
];
@@ -1139,27 +1123,36 @@ function getTopPlayers($limit = 5, $skill = 'level') {
$columns[] = 'lookaddons';
}
return Player::query()
if ($db->hasColumn('players', 'online')) {
$columns[] = 'online';
}
$players = Player::query()
->select($columns)
->withOnlineStatus()
->notDeleted()
->where('group_id', '<', setting('core.highscores_groups_hidden'))
->whereNotIn('id', setting('core.highscores_ids_hidden'))
->where('account_id', '!=', 1)
->orderByDesc($skill)
->orderByDesc('experience')
->limit($limit)
->get()
->map(function ($e, $i) {
$row = $e->toArray();
$row['online'] = $e->online_status;
$row['rank'] = $i + 1;
$row['outfit_url'] = $e->outfit_url;
unset($row['online_table']);
return $row;
})->toArray();
});
if($cache->enabled()) {
$cache->set('top_' . $limit . '_level', serialize($players), 120);
}
}
return $players;
}
function deleteDirectory($dir, $ignore = array(), $contentOnly = false) {
@@ -1228,7 +1221,7 @@ function clearCache()
{
News::clearCache();
$cache = app()->get('cache');
$cache = Cache::getInstance();
if($cache->enabled()) {
$keysToClear = [
'status', 'templates',
@@ -1266,7 +1259,7 @@ function clearCache()
}
}
$db = app()->get('database');
global $db;
$db->setClearCacheAfter(true);
}
@@ -1278,7 +1271,7 @@ function clearCache()
// routes cache
clearRouteCache();
$hooks = app()->get('hooks');
global $hooks;
$hooks->trigger(HOOK_CACHE_CLEAR, ['cache' => Cache::getInstance()]);
return true;
@@ -1294,8 +1287,7 @@ function clearRouteCache(): void
function getCustomPageInfo($name)
{
$logged_access = logged() ? accountLogged()->getAccess() : 0;
global $logged_access;
$page = Pages::isPublic()
->where('name', 'LIKE', $name)
->where('access', '<=', $logged_access)
@@ -1309,9 +1301,7 @@ function getCustomPageInfo($name)
}
function getCustomPage($name, &$success): string
{
global $title, $ignore;
$twig = app()->get('twig');
global $twig, $title, $ignore;
$success = false;
$content = '';
@@ -1335,6 +1325,9 @@ function getCustomPage($name, &$success): string
$tmp = $page['body'];
global $config;
if(setting('core.backward_support')) {
global $SQL, $main_content, $subtopic;
}
ob_start();
eval($tmp);
@@ -1525,7 +1518,8 @@ function verify_number($number, $name, $max_length)
function Outfits_loadfromXML()
{
$file_path = config('data_path') . 'XML/outfits.xml';
global $config;
$file_path = $config['data_path'] . 'XML/outfits.xml';
if (!file_exists($file_path)) { return null; }
$xml = new DOMDocument;
@@ -1550,7 +1544,8 @@ function Outfits_loadfromXML()
function Mounts_loadfromXML()
{
$file_path = config('data_path') . 'XML/mounts.xml';
global $config;
$file_path = $config['data_path'] . 'XML/mounts.xml';
if (!file_exists($file_path)) { return null; }
$xml = new DOMDocument;
@@ -1673,10 +1668,8 @@ function getGuildLogoById($id)
return BASE_URL . GUILD_IMAGES_DIR . $logo;
}
function displayErrorBoxWithBackButton($errors, $action = null)
{
$twig = app()->get('twig');
function displayErrorBoxWithBackButton($errors, $action = null) {
global $twig;
$twig->display('error_box.html.twig', ['errors' => $errors]);
$twig->display('account.back_button.html.twig', [
'action' => $action ?: getLink('')
@@ -1703,20 +1696,8 @@ function getAccountIdentityColumn(): string
return 'id';
}
function app() {
static $__app;
if (!isset($__app)) {
$__app = new App();
}
return $__app;
}
// validator functions
require_once SYSTEM . 'compat/base.php';
// custom functions
$customFunctions = SYSTEM . 'functions_custom.php';
if (is_file($customFunctions)) {
require $customFunctions;
}
require SYSTEM . 'functions_custom.php';

View File

@@ -17,8 +17,8 @@ use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!');
$configInstalled = config('installed');
if(!isset($configInstalled) || !$configInstalled) {
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.');
}
@@ -30,28 +30,31 @@ if (config('env') === 'dev' || getBoolean(config('enable_debugbar'))) {
$debugBar = new StandardDebugBar();
}
$configServerPath = config('server_path');
if(empty($configServerPath)) {
if(empty($config['server_path'])) {
throw new RuntimeException('Server Path has been not set. Go to config.php and set it.');
}
// take care of trailing slash at the end
if($configServerPath[strlen($configServerPath) - 1] !== '/') {
config(['server_path', $configServerPath . '/']);
}
if($config['server_path'][strlen($config['server_path']) - 1] !== '/')
$config['server_path'] .= '/';
// enable gzip compression if supported by the browser
if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && str_contains($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('ob_gzhandler'))
ob_start('ob_gzhandler');
// cache
global $cache;
$cache = Cache::getInstance();
// event system
$hooks = app()->get('hooks');
global $hooks;
$hooks = new Hooks();
$hooks->load();
// twig
require_once SYSTEM . 'twig.php';
// action, used by many pages
global $action;
$action = $_REQUEST['action'] ?? '';
define('ACTION', $action);
@@ -77,11 +80,9 @@ foreach($_REQUEST as $var => $value) {
// load otserv config file
$config_lua_reload = true;
global $cache;
$cache = app()->get('cache');
if($cache->enabled()) {
$tmp = null;
if($cache->fetch('server_path', $tmp) && $tmp == config('server_path')) {
if($cache->fetch('server_path', $tmp) && $tmp == $config['server_path']) {
$tmp = null;
if($cache->fetch('config_lua', $tmp) && $tmp) {
$config['lua'] = unserialize($tmp);
@@ -91,33 +92,31 @@ if($cache->enabled()) {
}
if($config_lua_reload) {
config(['lua', load_config_lua(config('server_path') . 'config.lua')]);
$config['lua'] = load_config_lua($config['server_path'] . 'config.lua');
// cache config
if($cache->enabled()) {
$cache->set('config_lua', serialize(config('lua')), 2 * 60);
$cache->set('server_path', config('server_path'), 10 * 60);
$cache->set('config_lua', serialize($config['lua']), 120);
$cache->set('server_path', $config['server_path']);
}
}
unset($tmp);
if(configLua('servername') !== null) {
$config['lua']['serverName'] = configLua('servername');
}
if(isset($config['lua']['servername']))
$config['lua']['serverName'] = $config['lua']['servername'];
if(configLua('houserentperiod') !== null) {
$config['lua']['houseRentPeriod'] = configLua('houserentperiod');
}
if(isset($config['lua']['houserentperiod']))
$config['lua']['houseRentPeriod'] = $config['lua']['houserentperiod'];
// localize data/ directory based on data directory set in config.lua
foreach(array('dataDirectory', 'data_directory', 'datadir') as $key) {
if(!isset(configLua($key)[0])) {
if(!isset($config['lua'][$key][0])) {
break;
}
$foundValue = configLua('lua')[$key];
$foundValue = $config['lua'][$key];
if($foundValue[0] !== '/') {
$foundValue = config('server_path') . $foundValue;
$foundValue = $config['server_path'] . $foundValue;
}
if($foundValue[strlen($foundValue) - 1] !== '/') {// do not forget about trailing slash
@@ -126,21 +125,21 @@ foreach(array('dataDirectory', 'data_directory', 'datadir') as $key) {
}
if(!isset($foundValue)) {
$foundValue = config('server_path') . 'data/';
$foundValue = $config['server_path'] . 'data/';
}
config(['data_path', $foundValue]);
$config['data_path'] = $foundValue;
unset($foundValue);
// POT
require_once SYSTEM . 'libs/pot/OTS.php';
$ots = POT::getInstance();
$eloquentConnection = null;
global $db;
$db = app()->get('db');
require_once SYSTEM . 'database.php';
// verify myaac tables exists in database
if(!defined('MYAAC_INSTALL') && !$db->hasTable('myaac_account_actions')) {
throw new RuntimeException('Seems that the table myaac_account_actions of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting ' . (IS_CLI ? 'http://your-ip.com/' : BASE_URL) . 'install');
throw new RuntimeException('Seems that the table myaac_account_actions of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting ' . BASE_URL . 'install');
}
// execute migrations
@@ -150,7 +149,8 @@ if (!isset($configDatabaseAutoMigrate) || $configDatabaseAutoMigrate) {
}
// settings
$settings = app()->get('settings');
$settings = Settings::getInstance();
$settings->load();
// csrf protection
$token = getSession('csrf_token');

View File

@@ -12,8 +12,6 @@
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
use MyAAC\Models\AccountAction;
/**
* OTServ account abstraction.
*
@@ -445,19 +443,19 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
throw new E_OTS_NotLoaded();
}
$configFreePremium = configLua('freePremium');
if(isset($configFreePremium) && getBoolean($configFreePremium)) {return -1;}
if(isset($this->data['premium_ends_at']) || isset($this->data['premend'])) {
$col = isset($this->data['premium_ends_at']) ? 'premium_ends_at' : 'premend';
$ret = ceil(($this->data[$col] - time()) / (24 * 60 * 60));
return max($ret, 0);
return $ret > 0 ? $ret : 0;
}
if($this->data['premdays'] == 0) {
return 0;
}
global $config;
if(isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium'])) return -1;
if($this->data['premdays'] == self::GRATIS_PREMIUM_DAYS){
return self::GRATIS_PREMIUM_DAYS;
}
@@ -478,8 +476,8 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
public function isPremium()
{
$configFreePremium = configLua('freePremium');
if(isset($configFreePremium) && getBoolean($configFreePremium)) return true;
global $config;
if(isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium'])) return true;
if(isset($this->data['premium_ends_at'])) {
return $this->data['premium_ends_at'] > time();
@@ -772,7 +770,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
$filter->compareField('account_id', (int) $this->data['id']);
if(!$withDeleted) {
$db = app()->get('database');
global $db;
if($db->hasColumn('players', 'deletion')) {
$filter->compareField('deletion', 0);
} else {
@@ -936,7 +934,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
return $this->data['group_id'];
}
$db = app()->get('database');
global $db;
if($db->hasColumn('accounts', 'group_id')) {
$query = $this->db->query('SELECT `group_id` FROM `accounts` WHERE `id` = ' . (int) $this->getId())->fetch();
// if anything was found
@@ -963,7 +961,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
return $this->data['group_id'];
}
$db = app()->get('database');
global $db;
if($db->hasColumn('accounts', 'group_id')) {
$query = $this->db->query('SELECT `group_id` FROM `accounts` WHERE `id` = ' . (int) $this->getId())->fetch();
// if anything was found
@@ -1012,16 +1010,26 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
public function logAction($action)
{
AccountAction::create([
'account_id' => $this->getId(),
'ip' => get_browser_real_ip(),
'date' => time(),
'action' => $action,
]);
$ip = get_browser_real_ip();
if(strpos($ip, ":") === false) {
$ipv6 = '0';
}
else {
$ipv6 = $ip;
$ip = '';
}
public function getActionsLog($limit) {
return AccountAction::where('account_id', $this->data['id'])->orderByDesc('date')->limit($limit)->get()->toArray();
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)
{
$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.

View File

@@ -97,13 +97,14 @@ class OTS_DB_MySQL extends OTS_Base_DB
$params['persistent'] = false;
}
$cache = app()->get('cache');
global $config;
$cache = Cache::getInstance();
if($cache->enabled()) {
$tmp = null;
$need_revalidation = true;
if($cache->fetch('database_checksum', $tmp) && $tmp) {
$tmp = unserialize($tmp);
if(sha1(config('database_host') . '.' . config('database_name')) === $tmp) {
if(sha1($config['database_host'] . '.' . $config['database_name']) === $tmp) {
$need_revalidation = false;
}
}
@@ -147,7 +148,9 @@ class OTS_DB_MySQL extends OTS_Base_DB
public function __destruct()
{
$cache = app()->get('cache');
global $config;
$cache = Cache::getInstance();
if($cache->enabled()) {
if ($this->clearCacheAfter) {
$cache->delete('database_tables');
@@ -157,7 +160,7 @@ class OTS_DB_MySQL extends OTS_Base_DB
else {
$cache->set('database_tables', serialize($this->has_table_cache), 3600);
$cache->set('database_columns', serialize($this->has_column_cache), 3600);
$cache->set('database_checksum', serialize(sha1(config('database_host') . '.' . config('database_name'))), 3600);
$cache->set('database_checksum', serialize(sha1($config['database_host'] . '.' . $config['database_name'])), 3600);
}
}
@@ -215,7 +218,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
}
private function hasTableInternal($name) {
return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote(config('database_name')) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0);
global $config;
return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote($config['database_name']) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0);
}
public function hasColumn($table, $column) {

View File

@@ -490,9 +490,7 @@ class OTS_Group extends OTS_Row_DAO implements IteratorAggregate, Countable
// creates filter
$filter = new OTS_SQLFilter();
$filter->compareField('group_id', (int) $this->data['id']);
$db = app()->get('database');
global $db;
if($db->hasColumn('players', 'deletion'))
$filter->compareField('deletion', 0);
else

View File

@@ -33,7 +33,7 @@ class OTS_Groups_List implements IteratorAggregate, Countable
*/
public function __construct($file = '')
{
$db = app()->get('db');
global $db;
if($db->hasTable('groups')) { // read groups from database
foreach($db->query('SELECT `id`, `name`, `access` FROM `groups`;') as $group)
{
@@ -47,8 +47,10 @@ class OTS_Groups_List implements IteratorAggregate, Countable
return;
}
if(!isset($file[0])) {
$file = config('data_path') . 'XML/groups.xml';
if(!isset($file[0]))
{
global $config;
$file = $config['data_path'] . 'XML/groups.xml';
}
if(!@file_exists($file)) {
@@ -57,7 +59,7 @@ class OTS_Groups_List implements IteratorAggregate, Countable
return;
}
$cache = app()->get('cache');
$cache = Cache::getInstance();
$data = array();
if($cache->enabled())

View File

@@ -284,6 +284,8 @@ class OTS_Guild extends OTS_Row_DAO implements IteratorAggregate, Countable
}
public function hasMember(OTS_Player $player) {
global $db;
if(!$player || !$player->isLoaded()) {
return false;
}

View File

@@ -108,8 +108,6 @@ class OTS_Player extends OTS_Row_DAO
POT::SKILL_SHIELD => array('value' => 0, 'tries' => 0),
POT::SKILL_FISH => array('value' => 0, 'tries' => 0)
);
private static array $playersOnline;
/**
* Magic PHP5 method.
*
@@ -655,19 +653,18 @@ class OTS_Player extends OTS_Row_DAO
//if($path == '')
// $path = $config['data_path'].'XML/groups.xml';
if(!isset($this->data['group_id'])) {
if( !isset($this->data['group_id']) )
{
throw new E_OTS_NotLoaded();
}
//$groups = new DOMDocument();
//$groups->load($path);
$groups = app()->get('groups');
global $groups;
$tmp = $groups->getGroup($this->data['group_id']);
if($tmp) {
if($tmp)
return $tmp;
}
return new OTS_Group();
// echo 'error while loading group..';
@@ -768,18 +765,10 @@ class OTS_Player extends OTS_Row_DAO
public function isOnline()
{
if($this->db->hasTable('players_online')) {// tfs 1.0
if (!isset(self::$playersOnline)) {
self::$playersOnline = [];
$query = $this->db->query('SELECT `player_id` FROM `players_online`');
foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $item) {
self::$playersOnline[$item['player_id']] = true;
}
}
return isset(self::$playersOnline[$this->data['id']]);
if($this->db->hasTable('players_online')) // tfs 1.0
{
$query = $this->db->query('SELECT `player_id` FROM `players_online` WHERE `player_id` = ' . $this->data['id']);
return $query->rowCount() > 0;
}
if( !isset($this->data['online']) )
@@ -854,8 +843,9 @@ class OTS_Player extends OTS_Row_DAO
}
if(isset($this->data['promotion'])) {
global $config;
if((int)$this->data['promotion'] > 0)
return ($this->data['vocation'] + ($this->data['promotion'] * config('vocations_amount')));
return ($this->data['vocation'] + ($this->data['promotion'] * $config['vocations_amount']));
}
return $this->data['vocation'];
@@ -1762,6 +1752,11 @@ class OTS_Player extends OTS_Row_DAO
*/
public function getConditions()
{
if( !isset($this->data['conditions']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['conditions'];
}

41
system/login.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
/**
* Login manager
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$logged = false;
$logged_flags = 0;
$account_logged = new OTS_Account();
// stay-logged with sessions
$current_session = getSession('account');
if($current_session !== false)
{
$account_logged->load($current_session);
if($account_logged->isLoaded() && $account_logged->getPassword() == getSession('password')
//&& (!isset($_SESSION['admin']) || admin())
&& (getSession('remember_me') !== false || getSession('last_visit') > time() - 15 * 60)) { // login for 15 minutes if "remember me" is not used
$logged = true;
}
else {
unsetSession('account');
unset($account_logged);
}
}
if($logged) {
$logged_flags = $account_logged->getWebFlags();
$twig->addGlobal('logged', true);
$twig->addGlobal('account_logged', $account_logged);
}
setSession('last_visit', time());
if(defined('PAGE')) {
setSession('last_page', PAGE);
}
setSession('last_uri', $_SERVER['REQUEST_URI']);

View File

@@ -12,10 +12,7 @@ use MyAAC\CsrfToken;
defined('MYAAC') or die('Direct access not allowed!');
$account_logged = accountLogged();
$hooks = app()->get('hooks');
if($account_logged !== null && $account_logged->isLoaded()) {
if(isset($account_logged) && $account_logged->isLoaded()) {
if($hooks->trigger(HOOK_LOGOUT, ['account_id' => $account_logged->getId()])) {
unsetSession('account');
unsetSession('password');
@@ -23,11 +20,7 @@ if($account_logged !== null && $account_logged->isLoaded()) {
CsrfToken::generate();
global $logged, $account_logged;
$logged = false;
$account_logged = new OTS_Account();
app()->setLoggedIn($logged);
app()->setAccountLogged($account_logged);
unset($account_logged);
}
}

View File

@@ -4,7 +4,7 @@ use MyAAC\Settings;
function updateHighscoresIdsHidden(): void
{
$db = app()->get('database');
global $db;
if (!$db->hasTable('players')) {
return;

View File

@@ -3,10 +3,12 @@
* @var OTS_DB_MySQL $db
*/
use MyAAC\Cache\Cache;
$up = function () use ($db) {
$db->dropTable(TABLE_PREFIX . 'hooks');
$cache = app()->get('cache');
$cache = Cache::getInstance();
if($cache->enabled()) {
$cache->delete('hooks');
}
@@ -15,7 +17,7 @@ $up = function () use ($db) {
$down = function () use ($db) {
$db->exec(file_get_contents(__DIR__ . '/28-hooks.sql'));
$cache = app()->get('cache');
$cache = Cache::getInstance();
if($cache->enabled()) {
$cache->delete('hooks');
}

View File

@@ -8,7 +8,7 @@
// the size of ipv6 can be maximal 45 chars
$up = function () use ($db) {
$db->modifyColumn(TABLE_PREFIX . 'visitors', 'ip', 'VARCHAR(45) NOT NULL');
$db->modifyColumn(TABLE_PREFIX . 'visitors', 'ip', 'VARCHAR(15) NOT NULL');
};
$down = function () {

View File

@@ -1,15 +0,0 @@
<?php
/**
* @var OTS_DB_MySQL $db
*/
// 2025-09-01
// resize forum.post_ip to support ipv6
$up = function () use ($db) {
$db->modifyColumn(TABLE_PREFIX . 'forum', 'post_ip', "varchar(45) NOT NULL default '0.0.0.0'");
};
$down = function () {
// there is no downgrade for this
};

View File

@@ -1,20 +0,0 @@
<?php
/**
* @var OTS_DB_MySQL $db
*/
// 2025-01-22
// change columns to VARCHAR
$up = function () use ($db) {
$db->query("UPDATE guilds set description = '' WHERE description is NULL;"); // prevent truncate error when column is NULL
$db->modifyColumn('guilds', 'description', "VARCHAR(5000) NOT NULL DEFAULT ''");
$db->query("UPDATE players set comment = '' WHERE comment is NULL;");
$db->modifyColumn('players', 'comment', "VARCHAR(5000) NOT NULL DEFAULT ''");
};
$down = function () use ($db) {
$db->modifyColumn('guilds', 'description', "TEXT NOT NULL");
$db->modifyColumn('players', 'comment', "TEXT NOT NULL");
};

View File

@@ -1,27 +0,0 @@
<?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) {
$db->query("ALTER TABLE `myaac_account_actions` DROP KEY `account_id`;");
$db->query("ALTER TABLE `myaac_account_actions` ADD COLUMN `id` INT(11) 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';");
$db->dropColumn(TABLE_PREFIX . 'account_actions', 'ipv6');
};
$down = function () use ($db) {
$db->query("ALTER TABLE `" . TABLE_PREFIX . "account_actions` DROP `id`;");
$db->query("ALTER TABLE `" . TABLE_PREFIX . "account_actions` ADD KEY (`account_id`);");
$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;");
};

View File

@@ -10,7 +10,7 @@
*/
defined('MYAAC') or die('Direct access not allowed!');
if(!logged())
if(!$logged)
{
$title = 'Login';

View File

@@ -13,7 +13,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Change E-Mail';
require __DIR__ . '/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -16,7 +16,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Change Info';
require __DIR__ . '/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -13,7 +13,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Change Password';
require __DIR__ . '/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -16,7 +16,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Change Comment';
require PAGES . 'account/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -13,7 +13,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Change Name';
require PAGES . 'account/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -13,7 +13,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Change Sex';
require PAGES . 'account/base.php';
if(!logged()) {
if(!$logged) {
return;
}
@@ -66,7 +66,7 @@ else
$new_sex_str = $config['genders'][$new_sex];
$player->save();
$account_logged->setCustomField(setting('core.donate_column'), $points - setting('core.account_change_character_sex_price'));
$account_logged->setCustomField(setting('core.donate_column'), $points - setting('core.account_change_character_name_price'));
$account_logged->logAction('Changed sex on character <b>' . $player->getName() . '</b> from <b>' . $old_sex_str . '</b> to <b>' . $new_sex_str . '</b>.');
$twig->display('success.html.twig', array(
'title' => 'Character Sex Changed',

View File

@@ -16,7 +16,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Create Character';
require PAGES . 'account/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -13,7 +13,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Delete Character';
require PAGES . 'account/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -17,7 +17,8 @@ $title = 'Create Account';
if (setting('core.account_country'))
require SYSTEM . 'countries.conf.php';
if(logged()) {
if($logged)
{
echo 'Please logout before attempting to create a new account.';
return;
}

View File

@@ -29,7 +29,6 @@ if(!empty($login_account) && !empty($login_password))
$limiter->enabled = setting('core.account_login_ipban_protection');
$limiter->load();
global $logged, $account_logged, $logged_flags;
$account_logged = new OTS_Account();
if (config('account_login_by_email')) {
$account_logged->findByEMail($login_account);
@@ -70,9 +69,6 @@ if(!empty($login_account) && !empty($login_password))
$account_logged->setCustomField('web_lastlogin', time());
}
app()->setLoggedIn($logged);
app()->setAccountLogged($account_logged);
$hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me));
}

View File

@@ -13,7 +13,7 @@ $title = 'Logout';
require __DIR__ . '/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -14,7 +14,7 @@ $title = 'Account Management';
require __DIR__ . '/login.php';
require __DIR__ . '/base.php';
if(!logged()) {
if(!$logged) {
return;
}
@@ -34,7 +34,7 @@ if(isset($_REQUEST['redirect']))
return;
}
$groups = app()->get('groups');
$groups = new OTS_Groups_List();
$freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS;
$dayOrDays = $account_logged->getPremDays() == 1 ? 'day' : 'days';
@@ -85,8 +85,12 @@ if($email_new_time > 1)
}
}
$actions = $account_logged->getActionsLog(1000);
$actions = array();
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 */
$account_players = $account_logged->getPlayersList();
$account_players->orderBy('id');

View File

@@ -13,7 +13,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Register Account';
require __DIR__ . '/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -13,7 +13,7 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Register Account';
require __DIR__ . '/base.php';
if(!logged()) {
if(!$logged) {
return;
}

View File

@@ -14,10 +14,10 @@ use MyAAC\Models\PlayerDeath;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Characters';
$groups = app()->get('groups');
function generate_search_form($autofocus = false): string
$groups = new OTS_Groups_List();
function generate_search_form($autofocus = false)
{
$twig = app()->get('twig');
global $config, $twig;
return $twig->render('characters.form.html.twig', array(
'link' => getLink('characters'),
'autofocus' => $autofocus
@@ -26,9 +26,7 @@ function generate_search_form($autofocus = false): string
function retrieve_former_name($name)
{
global $oldName;
$db = app()->get('db');
global $oldName, $db;
if($db->hasTable('player_namelocks') && $db->hasColumn('player_namelocks', 'name')) {
$newNameSql = $db->query('SELECT `name`, `new_name` FROM `player_namelocks` WHERE `name` = ' . $db->quote($name));
@@ -44,9 +42,8 @@ function retrieve_former_name($name)
}
$name = '';
if(isset($_REQUEST['name'])) {
if(isset($_REQUEST['name']))
$name = urldecode(stripslashes(ucwords(strtolower($_REQUEST['name']))));
}
if(empty($name))
{
@@ -66,15 +63,15 @@ if(!$player->isLoaded())
{
$tmp_zmienna = "";
$tmp_name = retrieve_former_name($name);
while(!empty($tmp_name)) {
while(!empty($tmp_name))
{
$tmp_zmienna = $tmp_name;
$tmp_name = retrieve_former_name($tmp_zmienna);
}
if(!empty($tmp_zmienna)) {
if(!empty($tmp_zmienna))
$player->find($tmp_zmienna);
}
}
if($player->isLoaded() && !$player->isDeleted())
{

View File

@@ -168,8 +168,10 @@ class FAQ
static public function move($id, $i, &$errors)
{
global $db;
$row = ModelsFAQ::find($id);
if($row) {
if($row)
{
$ordering = $row->ordering + $i;
$old_record = ModelsFAQ::where('ordering', $ordering)->first();
if($old_record) {
@@ -180,9 +182,8 @@ class FAQ
$row->ordering = $ordering;
$row->save();
}
else {
else
$errors[] = 'FAQ with id ' . $id . ' does not exists.';
}
return !count($errors);
}

View File

@@ -39,10 +39,9 @@ if(!empty($action))
$info = $db->query("SELECT `section`, COUNT(`id`) AS 'threads', SUM(`replies`) AS 'replies' FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `first_post` = `id` GROUP BY `section`")->fetchAll();
$boards = [];
foreach($info as $data) {
$boards = array();
foreach($info as $data)
$counters[$data['section']] = array('threads' => $data['threads'], 'posts' => $data['replies'] + $data['threads']);
}
foreach($sections as $id => $section)
{

View File

@@ -17,7 +17,7 @@ if(!$canEdit) {
return;
}
$groupsList = app()->get('groups');
$groupsList = new OTS_Groups_List();
$groups = [
['id' => 0, 'name' => 'Guest'],
];

View File

@@ -29,8 +29,7 @@ if(strtolower($forumSetting) != 'site') {
$canEdit = Forum::isModerator();
global $sections;
$sections = [];
$sections = array();
foreach(getForumBoards() as $section) {
$sections[$section['id']] = array(
'id' => $section['id'],

View File

@@ -18,7 +18,7 @@ if ($ret === false) {
return;
}
if(!logged()) {
if(!$logged) {
echo 'You are not logged in. <a href="' . getLink('account/manage') . '?redirect=' . urlencode(getLink('forum')) . '">Log in</a> to post on the forum.<br /><br />';
return;
}
@@ -35,7 +35,7 @@ if(Forum::canPost($account_logged))
$thread = $db->query("SELECT `author_guid`, `author_aid`, `first_post`, `post_topic`, `post_date`, `post_text`, `post_smile`, `post_html`, `id`, `section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `id` = ".$post_id." LIMIT 1")->fetch();
if(isset($thread['id'])) {
$first_post = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread['first_post']." LIMIT 1")->fetch();
echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread['first_post']) . '">'.htmlspecialchars($first_post['post_topic']).'</a> >> <b>Edit post</b>';
echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread['first_post']) . '">'.$first_post['post_topic'].'</a> >> <b>Edit post</b>';
if(Forum::hasAccess($thread['section'] && ($account_logged->getId() == $thread['author_aid'] || Forum::isModerator()))) {
$char_id = $post_topic = $text = $smile = $html = null;

View File

@@ -18,14 +18,13 @@ if ($ret === false) {
return;
}
if(!logged()) {
if(!$logged) {
echo 'You are not logged in. <a href="' . getLink('account/manage') . '?redirect=' . urlencode(getLink('forum')) . '">Log in</a> to post on the forum.<br /><br />';
return;
}
if(!Forum::isModerator()) {
echo 'You are not logged in or you are not moderator.';
return;
}
$save = isset($_REQUEST['save']) && (int)$_REQUEST['save'] == 1;

View File

@@ -18,7 +18,7 @@ if ($ret === false) {
return;
}
if(!logged()) {
if(!$logged) {
$extra_url = '';
if(isset($_GET['thread_id'])) {
$extra_url = '?action=new_post&thread_id=' . $_GET['thread_id'];
@@ -40,7 +40,7 @@ if(Forum::canPost($account_logged)) {
$thread = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".$thread_id." LIMIT 1")->fetch();
if(isset($thread['id']) && Forum::hasAccess($thread['section'])) {
echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread_id) . '">'.htmlspecialchars($thread['post_topic']).'</a> >> <b>Post new reply</b><br /><h3>'.htmlspecialchars($thread['post_topic']).'</h3>';
echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread_id) . '">'.$thread['post_topic'].'</a> >> <b>Post new reply</b><br /><h3>'.$thread['post_topic'].'</h3>';
$quote = isset($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : NULL;
$text = isset($_REQUEST['text']) ? stripslashes(trim($_REQUEST['text'])) : NULL;

View File

@@ -18,7 +18,7 @@ if ($ret === false) {
return;
}
if(!logged()) {
if(!$logged) {
$extra_url = '';
if(isset($_GET['section_id'])) {
$extra_url = '?action=new_thread&section_id=' . $_GET['section_id'];
@@ -95,23 +95,7 @@ if(Forum::canPost($account_logged)) {
if (count($errors) == 0) {
$saved = true;
$db->insert(FORUM_TABLE_PREFIX . 'forum', [
'first_post' => 0,
'last_post' => time(),
'section' => $section_id,
'replies' => 0,
'views' => 0,
'author_aid' => $account_logged->getId(),
'author_guid' => $char_id,
'post_text' => $text,
'post_topic' => $post_topic,
'post_smile' => $smile,
'post_html' => $html,
'post_date' => time(),
'last_edit_aid' => 0,
'edit_date' => 0,
'post_ip' => get_browser_real_ip(),
]);
$db->query("INSERT INTO `" . FORUM_TABLE_PREFIX . "forum` (`first_post` ,`last_post` ,`section` ,`replies` ,`views` ,`author_aid` ,`author_guid` ,`post_text` ,`post_topic` ,`post_smile`, `post_html` ,`post_date` ,`last_edit_aid` ,`edit_date`, `post_ip`) VALUES ('0', '" . time() . "', '" . (int)$section_id . "', '0', '0', '" . $account_logged->getId() . "', '" . $char_id . "', " . $db->quote($text) . ", " . $db->quote($post_topic) . ", '" . $smile . "', '" . $html . "', '" . time() . "', '0', '0', '" . get_browser_real_ip() . "')");
$thread_id = $db->lastInsertId();

Some files were not shown because too many files have changed in this diff Show More