mirror of
https://github.com/slawkens/myaac.git
synced 2026-03-20 09:33:32 +01:00
feat: Rewrite of the core: avoid globals where possible
Create services for: login, status, router, database, AnonymousStatistics Drop gesior.backward_support Drop compat/pages.php Drop part of compat/classes.php Move signature to routes
This commit is contained in:
8
system/src/App/Admin.php
Normal file
8
system/src/App/Admin.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\App;
|
||||
|
||||
class Admin
|
||||
{
|
||||
|
||||
}
|
||||
144
system/src/App/App.php
Normal file
144
system/src/App/App.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\App;
|
||||
|
||||
use MyAAC\Hooks;
|
||||
use MyAAC\Services\AnonymousStatisticsService;
|
||||
use MyAAC\Services\DatabaseService;
|
||||
use MyAAC\Services\LoginService;
|
||||
use MyAAC\Services\RouterService;
|
||||
use MyAAC\Services\StatusService;
|
||||
use MyAAC\Settings;
|
||||
use MyAAC\Visitors;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
|
||||
class App
|
||||
{
|
||||
private bool $isLoggedIn = false;
|
||||
private array $instances = [];
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$configInstalled = config('installed');
|
||||
if((!isset($configInstalled) || !$configInstalled) && file_exists(BASE . 'install')) {
|
||||
header('Location: ' . BASE_URL . 'install/');
|
||||
exit();
|
||||
}
|
||||
|
||||
$template_place_holders = [];
|
||||
|
||||
require_once SYSTEM . 'init.php';
|
||||
|
||||
require_once SYSTEM . 'template.php';
|
||||
|
||||
$loginService = new LoginService();
|
||||
$this->isLoggedIn = $loginService->checkLogin();
|
||||
|
||||
$statusService = new StatusService();
|
||||
$status = $statusService->checkStatus();
|
||||
|
||||
global $config;
|
||||
|
||||
$twig = app()->get('twig');
|
||||
$twig->addGlobal('config', $config);
|
||||
$twig->addGlobal('status', $status);
|
||||
|
||||
$hooks = app()->get('hooks');
|
||||
$hooks->trigger(HOOK_STARTUP);
|
||||
|
||||
$routerService = new RouterService();
|
||||
$handleRouting = $routerService->handleRouting();
|
||||
|
||||
$title = $handleRouting['title'];
|
||||
$content = $handleRouting['content'];
|
||||
|
||||
$anonymouseStatisticsService = new AnonymousStatisticsService();
|
||||
$anonymouseStatisticsService->checkReport();
|
||||
|
||||
if(setting('core.views_counter')) {
|
||||
require_once SYSTEM . 'counter.php';
|
||||
}
|
||||
|
||||
if(setting('core.visitors_counter')) {
|
||||
global $visitors;
|
||||
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
|
||||
}
|
||||
|
||||
global $content;
|
||||
/**
|
||||
* @var \OTS_Account $account_logged
|
||||
*/
|
||||
if ($this->isLoggedIn && admin()) {
|
||||
$content .= $twig->render('admin-bar.html.twig', [
|
||||
'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()
|
||||
]);
|
||||
}
|
||||
|
||||
global $template_path, $template_index;
|
||||
$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);
|
||||
}
|
||||
|
||||
public function setLoggedIn($loggedIn): void {
|
||||
$this->isLoggedIn = $loggedIn;
|
||||
}
|
||||
|
||||
public function isLoggedIn(): bool {
|
||||
return $this->isLoggedIn;
|
||||
}
|
||||
|
||||
public function get($what)
|
||||
{
|
||||
if ($what == 'db') {
|
||||
$what = 'database';
|
||||
}
|
||||
|
||||
if (!isset($this->instances[$what])) {
|
||||
switch ($what) {
|
||||
case 'cache':
|
||||
$this->instances[$what] = \MyAAC\Cache\Cache::getInstance();
|
||||
break;
|
||||
|
||||
case 'database':
|
||||
$databaseService = new DatabaseService();
|
||||
$this->instances[$what] = $databaseService->getConnectionHandle();
|
||||
break;
|
||||
|
||||
case 'hooks':
|
||||
$this->instances[$what] = new Hooks();
|
||||
break;
|
||||
|
||||
case 'settings':
|
||||
$this->instances[$what] = Settings::getInstance();
|
||||
break;
|
||||
|
||||
case 'twig':
|
||||
$dev_mode = (config('env') === 'dev');
|
||||
$this->instances[$what] = new Environment($this->get('twig-loader'), array(
|
||||
'cache' => CACHE . 'twig/',
|
||||
'auto_reload' => $dev_mode,
|
||||
'debug' => $dev_mode
|
||||
));
|
||||
break;
|
||||
|
||||
case 'twig-loader':
|
||||
$this->instances[$what] = new FilesystemLoader(SYSTEM . 'templates');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->instances[$what];
|
||||
}
|
||||
}
|
||||
41
system/src/App/Console.php
Normal file
41
system/src/App/Console.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\App;
|
||||
|
||||
use MyAAC\Plugins;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
class Console
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
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__));
|
||||
|
||||
$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();
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,7 @@ class CreateCharacter
|
||||
}
|
||||
}
|
||||
|
||||
global $hooks;
|
||||
$hooks = app()->get('hooks');
|
||||
if (!$hooks->trigger(HOOK_ACCOUNT_CREATE_CHARACTER_AFTER,
|
||||
[
|
||||
'account' => $account,
|
||||
|
||||
@@ -49,7 +49,7 @@ class News
|
||||
'article_image' => ($type == 3 ? $article_image : '')
|
||||
];
|
||||
|
||||
global $hooks;
|
||||
$hooks = app()->get('hooks');
|
||||
if (!$hooks->trigger(HOOK_ADMIN_NEWS_ADD_PRE, $params)) {
|
||||
return false;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ class News
|
||||
'article_image' => ($type == 3 ? $article_image : ''),
|
||||
];
|
||||
|
||||
global $hooks;
|
||||
$hooks = app()->get('hooks');
|
||||
if (!$hooks->trigger(HOOK_ADMIN_NEWS_UPDATE_PRE, $params)) {
|
||||
return false;
|
||||
}
|
||||
@@ -105,7 +105,7 @@ class News
|
||||
|
||||
static public function delete($id, &$errors)
|
||||
{
|
||||
global $hooks;
|
||||
$hooks = app()->get('hooks');
|
||||
|
||||
if(isset($id)) {
|
||||
$row = ModelsNews::find($id);
|
||||
@@ -140,7 +140,7 @@ class News
|
||||
|
||||
static public function toggleHide($id, &$errors, &$status)
|
||||
{
|
||||
global $hooks;
|
||||
$hooks = app()->get('hooks');
|
||||
|
||||
if(isset($id)) {
|
||||
$row = ModelsNews::find($id);
|
||||
|
||||
@@ -716,7 +716,7 @@ class Plugins {
|
||||
}
|
||||
}
|
||||
|
||||
$cache = Cache::getInstance();
|
||||
$cache = app()->get('cache');
|
||||
if($cache->enabled()) {
|
||||
$cache->delete('templates');
|
||||
$cache->delete('hooks');
|
||||
|
||||
52
system/src/Services/AnonymousStatisticsService.php
Normal file
52
system/src/Services/AnonymousStatisticsService.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\Services;
|
||||
|
||||
use MyAAC\Cache\Cache;
|
||||
use MyAAC\UsageStatistics;
|
||||
|
||||
/*
|
||||
* anonymous usage statistics
|
||||
* sent only when user agrees
|
||||
*/
|
||||
class AnonymousStatisticsService
|
||||
{
|
||||
public function checkReport(): void
|
||||
{
|
||||
if(!setting('core.anonymous_usage_statistics')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days
|
||||
$should_report = true;
|
||||
|
||||
$cache = app()->get('cache');
|
||||
|
||||
$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, 60 * 60);
|
||||
}
|
||||
}
|
||||
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(), 60 * 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
153
system/src/Services/DatabaseService.php
Normal file
153
system/src/Services/DatabaseService.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\Services;
|
||||
|
||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||
|
||||
class DatabaseService
|
||||
{
|
||||
private $db;
|
||||
|
||||
public function getConnectionHandle()
|
||||
{
|
||||
if (!isset($this->db)) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
public function connect(): void
|
||||
{
|
||||
global $config;
|
||||
|
||||
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'] = '';
|
||||
}
|
||||
|
||||
$ots = \POT::getInstance();
|
||||
$cache = app()->get('cache');
|
||||
|
||||
try {
|
||||
$ots->connect([
|
||||
'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 $eloquentConnection;
|
||||
$this->db = $ots->getDBHandle();
|
||||
|
||||
$capsule = new Capsule;
|
||||
$capsule->addConnection([
|
||||
'driver' => 'mysql',
|
||||
'database' => $config['database_name'],
|
||||
]);
|
||||
|
||||
$capsule->getConnection()->setPdo($this->db);
|
||||
$capsule->getConnection()->setReadPdo($this->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());
|
||||
}
|
||||
}
|
||||
}
|
||||
47
system/src/Services/LoginService.php
Normal file
47
system/src/Services/LoginService.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\Services;
|
||||
|
||||
class LoginService
|
||||
{
|
||||
public function checkLogin(): bool
|
||||
{
|
||||
global $logged, $logged_flags, $account_logged;
|
||||
|
||||
$logged = false;
|
||||
$logged_flags = 0;
|
||||
$account_logged = new \OTS_Account();
|
||||
|
||||
// stay-logged with sessions
|
||||
$current_session = getSession('account');
|
||||
if($current_session) {
|
||||
$account_logged->load($current_session);
|
||||
if($account_logged->isLoaded() && $account_logged->getPassword() == getSession('password')
|
||||
//&& (!isset($_SESSION['admin']) || admin())
|
||||
&& (getSession('remember_me') || 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 = app()->get('twig');
|
||||
$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']);
|
||||
|
||||
app()->setLoggedIn($logged);
|
||||
return $logged;
|
||||
}
|
||||
}
|
||||
364
system/src/Services/RouterService.php
Normal file
364
system/src/Services/RouterService.php
Normal file
@@ -0,0 +1,364 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\Services;
|
||||
|
||||
use MyAAC\Models\Pages;
|
||||
use MyAAC\Plugins;
|
||||
|
||||
class RouterService
|
||||
{
|
||||
public function handleRouting(): array
|
||||
{
|
||||
global $content, $logged, $db, $twig, $template_path, $template;
|
||||
|
||||
if(!isset($content[0])) {
|
||||
$content = '';
|
||||
}
|
||||
|
||||
// check if site has been closed
|
||||
$load_it = true;
|
||||
$site_closed = false;
|
||||
if(fetchDatabaseConfig('site_closed', $site_closed)) {
|
||||
$site_closed = ($site_closed == 1);
|
||||
if($site_closed) {
|
||||
if(!admin()) {
|
||||
$title = getDatabaseConfig('site_closed_title');
|
||||
$content .= '<p class="note">' . getDatabaseConfig('site_closed_message') . '</p><br/>';
|
||||
$load_it = false;
|
||||
}
|
||||
|
||||
if(!$logged) {
|
||||
ob_start();
|
||||
require SYSTEM . 'pages/account/manage.php';
|
||||
$content .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
$load_it = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
define('SITE_CLOSED', $site_closed);
|
||||
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
if(str_contains($uri, 'index.php')) {
|
||||
/** @var TYPE_NAME $uri */
|
||||
$uri = str_replace_first('/index.php', '', $uri);
|
||||
}
|
||||
|
||||
if(str_starts_with($uri, '/')) {
|
||||
$uri = str_replace_first('/', '', $uri);
|
||||
}
|
||||
|
||||
// Strip query string (?foo=bar) and decode URI
|
||||
/** @var string $uri */
|
||||
if (false !== $pos = strpos($uri, '?')) {
|
||||
if ($pos !== 1) {
|
||||
$uri = substr($uri, 0, $pos);
|
||||
}
|
||||
else {
|
||||
$uri = str_replace_first('?', '', $uri);
|
||||
}
|
||||
}
|
||||
|
||||
$uri = rawurldecode($uri);
|
||||
if (BASE_DIR !== '') {
|
||||
$tmp = str_replace_first('/', '', BASE_DIR);
|
||||
$uri = str_replace_first($tmp, '', $uri);
|
||||
}
|
||||
|
||||
if(0 === strpos($uri, '/')) {
|
||||
$uri = str_replace_first('/', '', $uri);
|
||||
}
|
||||
|
||||
define('URI', $uri);
|
||||
|
||||
if(!$load_it) {
|
||||
// ignore warnings in some functions/plugins
|
||||
// page is not loaded anyway
|
||||
define('PAGE', '');
|
||||
|
||||
return [
|
||||
'title' => 'Maintenance mode',
|
||||
'content' => $content,
|
||||
];
|
||||
}
|
||||
|
||||
/** @var string $content */
|
||||
if(SITE_CLOSED && admin())
|
||||
$content .= '<p class="note">Site is under maintenance (closed mode). Only privileged users can see it.</p>';
|
||||
|
||||
$ignore = false;
|
||||
|
||||
/** @var boolean $logged */
|
||||
/** @var \OTS_Account $account_logged */
|
||||
global $logged_access;
|
||||
$logged_access = 0;
|
||||
if($logged && $account_logged && $account_logged->isLoaded()) {
|
||||
$logged_access = $account_logged->getAccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Routes loading
|
||||
*/
|
||||
$dispatcher = \FastRoute\cachedDispatcher(function (\FastRoute\RouteCollector $r) {
|
||||
$routes = require SYSTEM . 'routes.php';
|
||||
|
||||
$routesFinal = [];
|
||||
foreach($this->getDatabasePages() as $page) {
|
||||
$routesFinal[] = ['*', $page, '__database__/' . $page, 100];
|
||||
}
|
||||
|
||||
Plugins::clearWarnings();
|
||||
foreach (Plugins::getRoutes() as $route) {
|
||||
$routesFinal[] = [$route[0], $route[1], $route[2], $route[3] ?? 1000];
|
||||
/*
|
||||
echo '<pre>';
|
||||
var_dump($route[1], $route[3], $route[2]);
|
||||
echo '/<pre>';
|
||||
*/
|
||||
}
|
||||
|
||||
foreach ($routes as $route) {
|
||||
if (!str_contains($route[2], '__redirect__') && !str_contains($route[2], '__database__')) {
|
||||
$routesFinal[] = [$route[0], $route[1], 'system/pages/' . $route[2], $route[3] ?? 10000];
|
||||
}
|
||||
else {
|
||||
$routesFinal[] = [$route[0], $route[1], $route[2], $route[3] ?? 10000];
|
||||
}
|
||||
}
|
||||
|
||||
// sort required for the next step (filter)
|
||||
usort($routesFinal, function ($a, $b)
|
||||
{
|
||||
// key 3 is priority
|
||||
if ($a[3] == $b[3]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($a[3] < $b[3]) ? -1 : 1;
|
||||
});
|
||||
|
||||
// remove duplicates
|
||||
// if same route pattern, but different priority
|
||||
$routesFinal = array_filter($routesFinal, function ($a) {
|
||||
$aliases = [
|
||||
[':int', ':string', ':alphanum'],
|
||||
[':\d+', ':[A-Za-z0-9-_%+\' ]+', ':[A-Za-z0-9]+'],
|
||||
];
|
||||
|
||||
// apply aliases
|
||||
$a[1] = str_replace($aliases[0], $aliases[1], $a[1]);
|
||||
|
||||
static $duplicates = [];
|
||||
if (isset($duplicates[$a[1]])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$duplicates[$a[1]] = true;
|
||||
return true;
|
||||
});
|
||||
/*
|
||||
echo '<pre>';
|
||||
var_dump($routesFinal);
|
||||
echo '</pre>';
|
||||
die;
|
||||
*/
|
||||
foreach ($routesFinal as $route) {
|
||||
if ($route[0] === '*') {
|
||||
$route[0] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'];
|
||||
}
|
||||
else {
|
||||
if (is_string($route[0])) {
|
||||
$route[0] = explode(',', $route[0]);
|
||||
}
|
||||
|
||||
$toUpperCase = function(string $value): string {
|
||||
return trim(strtoupper($value));
|
||||
};
|
||||
|
||||
// convert to upper case, fast-route accepts only upper case
|
||||
$route[0] = array_map($toUpperCase, $route[0]);
|
||||
}
|
||||
|
||||
$aliases = [
|
||||
[':int', ':string', ':alphanum'],
|
||||
[':\d+', ':[A-Za-z0-9-_%+\' ]+', ':[A-Za-z0-9]+'],
|
||||
];
|
||||
|
||||
// apply aliases
|
||||
$route[1] = str_replace($aliases[0], $aliases[1], $route[1]);
|
||||
|
||||
$r->addRoute($route[0], $route[1], $route[2]);
|
||||
}
|
||||
|
||||
if (config('env') === 'dev') {
|
||||
foreach(Plugins::getWarnings() as $warning) {
|
||||
log_append('router.log', $warning);
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
'cacheFile' => CACHE . 'route.cache',
|
||||
'cacheDisabled' => config('env') === 'dev',
|
||||
]
|
||||
);
|
||||
|
||||
// Fetch method and URI
|
||||
$httpMethod = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
$found = true;
|
||||
|
||||
// old support for pages like /?subtopic=accountmanagement
|
||||
$page = $_REQUEST['p'] ?? ($_REQUEST['subtopic'] ?? '');
|
||||
if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) {
|
||||
if (isset($_REQUEST['p'])) { // some plugins may require this
|
||||
$_REQUEST['subtopic'] = $_REQUEST['p'];
|
||||
}
|
||||
|
||||
$file = $this->loadPageFromFileSystem($page, $found);
|
||||
if(!$found) {
|
||||
$file = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
|
||||
switch ($routeInfo[0]) {
|
||||
case \FastRoute\Dispatcher::NOT_FOUND:
|
||||
// ... 404 Not Found
|
||||
/**
|
||||
* Fallback to load page from templates/ or system/pages/ directory
|
||||
*/
|
||||
$page = $uri;
|
||||
if (preg_match('/^[A-z0-9\/\-]+$/', $page)) {
|
||||
$file = $this->loadPageFromFileSystem($page, $found);
|
||||
} else {
|
||||
$found = false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case \FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
|
||||
// ... 405 Method Not Allowed
|
||||
$page = '405';
|
||||
$allowedMethods = $routeInfo[1];
|
||||
$file = SYSTEM . 'pages/405.php';
|
||||
break;
|
||||
|
||||
case \FastRoute\Dispatcher::FOUND:
|
||||
$path = $routeInfo[1];
|
||||
$vars = $routeInfo[2];
|
||||
|
||||
$_REQUEST = array_merge($_REQUEST, $vars);
|
||||
$_GET = array_merge($_GET, $vars);
|
||||
extract($vars);
|
||||
|
||||
if (str_contains($path, '__database__/')) {
|
||||
$pageName = str_replace('__database__/', '', $path);
|
||||
|
||||
$success = false;
|
||||
$tmp_content = getCustomPage($pageName, $success);
|
||||
if ($success) {
|
||||
$content .= $tmp_content;
|
||||
if (hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) {
|
||||
$pageInfo = getCustomPageInfo($pageName);
|
||||
$content = $twig->render('admin.links.html.twig', ['page' => 'pages', 'id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hide' => $pageInfo !== null ? $pageInfo['hide'] : '0']
|
||||
) . $content;
|
||||
}
|
||||
|
||||
$page = $pageName;
|
||||
$file = false;
|
||||
}
|
||||
} else if (str_contains($path, '__redirect__/')) {
|
||||
$path = str_replace('__redirect__/', '', $path);
|
||||
header('Location: ' . BASE_URL . $path);
|
||||
exit;
|
||||
} else {
|
||||
// parse for define PAGE
|
||||
$tmp = BASE_DIR;
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
if (strlen($tmp) > 0) {
|
||||
$uri = str_replace(BASE_DIR . '/', '', $uri);
|
||||
}
|
||||
|
||||
if (false !== $pos = strpos($uri, '?')) {
|
||||
$uri = substr($uri, 0, $pos);
|
||||
}
|
||||
if (str_starts_with($uri, '/')) {
|
||||
$uri = str_replace_first('/', '', $uri);
|
||||
}
|
||||
|
||||
$page = str_replace('index.php/', '', $uri);
|
||||
if (empty($page)) {
|
||||
$page = 'news';
|
||||
}
|
||||
|
||||
$file = BASE . $path;
|
||||
}
|
||||
|
||||
unset($tmp, $uri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$page = '404';
|
||||
$file = SYSTEM . 'pages/404.php';
|
||||
}
|
||||
|
||||
define('PAGE', $page);
|
||||
|
||||
ob_start();
|
||||
|
||||
global $config;
|
||||
$hooks = app()->get('hooks');
|
||||
|
||||
if($hooks->trigger(HOOK_BEFORE_PAGE)) {
|
||||
if(!$ignore && $file !== false) {
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
|
||||
$content .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
$hooks->trigger(HOOK_AFTER_PAGE);
|
||||
|
||||
if(!isset($title)) {
|
||||
$title = str_replace('index.php/', '', $page);
|
||||
$title = ucfirst($title);
|
||||
}
|
||||
|
||||
return [
|
||||
'title' => $title,
|
||||
'content' => $content,
|
||||
];
|
||||
}
|
||||
|
||||
public function getDatabasePages($withHidden = false): array
|
||||
{
|
||||
global $logged_access;
|
||||
$pages = Pages::where('access', '<=', $logged_access)->when(!$withHidden, function ($q) {
|
||||
$q->isPublic();
|
||||
})->get('name');
|
||||
|
||||
$ret = [];
|
||||
foreach($pages as $page) {
|
||||
$ret[] = $page->name;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private function loadPageFromFileSystem($page, &$found): string
|
||||
{
|
||||
$file = SYSTEM . 'pages/' . $page . '.php';
|
||||
if (!is_file($file)) {
|
||||
// feature: load pages from templates/ dir
|
||||
global $template_path;
|
||||
$file = $template_path . '/pages/' . $page . '.php';
|
||||
if (!is_file($file)) {
|
||||
$found = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
134
system/src/Services/StatusService.php
Normal file
134
system/src/Services/StatusService.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace MyAAC\Services;
|
||||
|
||||
use MyAAC\Cache\Cache;
|
||||
use MyAAC\Models\Config;
|
||||
use MyAAC\Models\Player;
|
||||
use MyAAC\Models\PlayerOnline;
|
||||
|
||||
class StatusService
|
||||
{
|
||||
public function checkStatus(): array
|
||||
{
|
||||
$status = [];
|
||||
$status['online'] = false;
|
||||
$status['players'] = 0;
|
||||
$status['playersMax'] = 0;
|
||||
$status['lastCheck'] = 0;
|
||||
$status['uptime'] = '0h 0m';
|
||||
$status['monsters'] = 0;
|
||||
|
||||
if(setting('core.status_enabled') === false) {
|
||||
return $status;
|
||||
}
|
||||
|
||||
$fetch_from_db = true;
|
||||
/**
|
||||
* @var Cache $cache
|
||||
*/
|
||||
$cache = app()->get('cache');
|
||||
if($cache->enabled()) {
|
||||
$tmp = '';
|
||||
if($cache->fetch('status', $tmp)) {
|
||||
return unserialize($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
$status_query = Config::where('name', 'LIKE', '%status%')->get();
|
||||
if (!$status_query || !$status_query->count()) {
|
||||
foreach($status as $key => $value) {
|
||||
registerDatabaseConfig('status_' . $key, $value);
|
||||
}
|
||||
} else {
|
||||
foreach($status_query as $tmp) {
|
||||
$status[str_replace('status_', '', $tmp->name)] = $tmp->value;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($config['lua']['statustimeout'])) {
|
||||
$config['lua']['statusTimeout'] = $config['lua']['statustimeout'];
|
||||
}
|
||||
|
||||
// get status timeout from server config
|
||||
$status_timeout = eval('return ' . $config['lua']['statusTimeout'] . ';') / 1000 + 1;
|
||||
$status_interval = setting('core.status_interval');
|
||||
if($status_interval && $status_timeout < $status_interval) {
|
||||
$status_timeout = $status_interval;
|
||||
}
|
||||
|
||||
if($status['lastCheck'] + $status_timeout < time()) {
|
||||
return $this->updateStatus();
|
||||
}
|
||||
|
||||
$cache = app()->get('cache');
|
||||
}
|
||||
|
||||
public function updateStatus(): array
|
||||
{
|
||||
$db = app()->get('db');
|
||||
$cache = app()->get('cache');
|
||||
|
||||
// get server status and save it to database
|
||||
$serverInfo = new \OTS_ServerInfo(setting('core.status_ip'), setting('core.status_port'));
|
||||
$serverStatus = $serverInfo->status();
|
||||
if(!$serverStatus) {
|
||||
$status['online'] = false;
|
||||
$status['players'] = 0;
|
||||
$status['playersMax'] = 0;
|
||||
}
|
||||
else {
|
||||
$status['lastCheck'] = time(); // this should be set only if server respond
|
||||
|
||||
$status['online'] = true;
|
||||
$status['players'] = $serverStatus->getOnlinePlayers(); // counts all players logged in-game, or only connected clients (if enabled on server side)
|
||||
$status['playersMax'] = $serverStatus->getMaxPlayers();
|
||||
|
||||
// for status afk thing
|
||||
if (setting('core.online_afk')) {
|
||||
// get amount of players that are currently logged in-game, including disconnected clients (exited)
|
||||
if($db->hasTable('players_online')) { // tfs 1.x
|
||||
$status['playersTotal'] = PlayerOnline::count();
|
||||
}
|
||||
else {
|
||||
$status['playersTotal'] = Player::online()->count();
|
||||
}
|
||||
}
|
||||
|
||||
$uptime = $status['uptime'] = $serverStatus->getUptime();
|
||||
$m = date('m', $uptime);
|
||||
$m = $m > 1 ? "$m months, " : ($m == 1 ? 'month, ' : '');
|
||||
$d = date('d', $uptime);
|
||||
$d = $d > 1 ? "$d days, " : ($d == 1 ? 'day, ' : '');
|
||||
$h = date('H', $uptime);
|
||||
$min = date('i', $uptime);
|
||||
$status['uptimeReadable'] = "{$m}{$d}{$h}h {$min}m";
|
||||
|
||||
$status['monsters'] = $serverStatus->getMonstersCount();
|
||||
$status['motd'] = $serverStatus->getMOTD();
|
||||
|
||||
$status['mapAuthor'] = $serverStatus->getMapAuthor();
|
||||
$status['mapName'] = $serverStatus->getMapName();
|
||||
$status['mapWidth'] = $serverStatus->getMapWidth();
|
||||
$status['mapHeight'] = $serverStatus->getMapHeight();
|
||||
|
||||
$status['server'] = $serverStatus->getServer();
|
||||
$status['serverVersion'] = $serverStatus->getServerVersion();
|
||||
$status['clientVersion'] = $serverStatus->getClientVersion();
|
||||
}
|
||||
|
||||
if($cache->enabled()) {
|
||||
$cache->set('status', serialize($status), 120);
|
||||
}
|
||||
|
||||
$tmpVal = null;
|
||||
foreach($status as $key => $value) {
|
||||
if(fetchDatabaseConfig('status_' . $key, $tmpVal)) {
|
||||
updateDatabaseConfig('status_' . $key, $value);
|
||||
}
|
||||
else {
|
||||
registerDatabaseConfig('status_' . $key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class Settings implements \ArrayAccess
|
||||
|
||||
$settings = $this->settingsFile[$pluginName];
|
||||
|
||||
global $hooks;
|
||||
$hooks = app()->get('hooks');
|
||||
if (!$hooks->trigger(HOOK_ADMIN_SETTINGS_BEFORE_SAVE, [
|
||||
'name' => $pluginName,
|
||||
'values' => $values,
|
||||
|
||||
Reference in New Issue
Block a user