Merge branch 'develop' into feature/debug-bar

This commit is contained in:
slawkens 2023-08-21 10:20:04 +02:00
commit c227fd4e96
111 changed files with 2182 additions and 1331 deletions

6
.gitignore vendored
View File

@ -35,6 +35,12 @@ images/guilds/*
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

View File

@ -1,19 +1,25 @@
# [MyAAC](https://my-aac.org)
[![Build Status Master](https://img.shields.io/travis/slawkens/myaac/master)](https://travis-ci.org/github/slawkens/myaac)
[![License: GPL-3.0](https://img.shields.io/github/license/slawkens/myaac)](https://opensource.org/licenses/gpl-license)
[![Downloads Count](https://img.shields.io/github/downloads/slawkens/myaac/total)](https://github.com/slawkens/myaac/releases)
[![PHP Versions](https://img.shields.io/travis/php-v/slawkens/myaac/master)](https://github.com/slawkens/myaac/blob/d8b3b4135827ee17e3c6d41f08a925e718c587ed/.travis.yml#L3)
[![OpenTibia Discord](https://img.shields.io/discord/288399552581468162)](https://discord.gg/2J39Wus)
[![Closed Issues](https://img.shields.io/github/issues-closed-raw/slawkens/myaac)](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed)
MyAAC is a free and open-source Automatic Account Creator (AAC) written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases.
Official website: https://my-aac.org
[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/slawkens/myaac/cypress.yml)](https://github.com/slawkens/myaac/actions)
[![License: GPL-3.0](https://img.shields.io/github/license/slawkens/myaac)](https://opensource.org/licenses/gpl-license)
[![Downloads Count](https://img.shields.io/github/downloads/slawkens/myaac/total)](https://github.com/slawkens/myaac/releases)
[![OpenTibia Discord](https://img.shields.io/discord/288399552581468162)](https://discord.gg/2J39Wus)
[![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 |
|:-----------|:------------------------------------------|:--------|:---------------|
| **0.10.x** | **Active development** | develop | **PHP >= 8.0** |
| 0.9.x | Active support | 0.9 | 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
- PHP 7.2.5 or later
- PHP 8.0 or later
- MySQL database
- PDO PHP Extension
- XML PHP Extension
@ -71,7 +77,13 @@ Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our w
### Other Notes
If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org
If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org
## Project supported by JetBrains
Many thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects.
[![JetBrains](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://www.jetbrains.com/?from=https://github.com/slawkens)
### License

View File

@ -7,6 +7,9 @@
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Account editor';
@ -272,7 +275,7 @@ else if (isset($_REQUEST['search'])) {
</li>
<?php endif;
if ($db->hasTable('store_history')) : ?>
if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) : ?>
<li class="nav-item">
<a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a>
</li>
@ -424,8 +427,7 @@ else if (isset($_REQUEST['search'])) {
<div class="row">
<?php
if (isset($account) && $account->isLoaded()) {
$account_players = $account->getPlayersList();
$account_players->orderBy('id');
$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get();
if (isset($account_players)) { ?>
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
@ -438,25 +440,13 @@ else if (isset($_REQUEST['search'])) {
</tr>
</thead>
<tbody>
<?php $i= 0;
foreach ($account_players as $i => $player):
$i++;
$player_vocation = $player->getVocation();
$player_promotion = $player->getPromotion();
if (isset($player_promotion)) {
if ((int)$player_promotion > 0)
$player_vocation += ($player_promotion * $config['vocations_amount']);
}
if (isset($config['vocations'][$player_vocation])) {
$vocation_name = $config['vocations'][$player_vocation];
} ?>
<?php foreach ($account_players as $i => $player): ?>
<tr>
<th><?php echo $i; ?></th>
<td><?php echo $player->getName(); ?></td>
<td><?php echo $player->getLevel(); ?></td>
<td><?php echo $vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getId() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
<th><?php echo $i + 1; ?></th>
<td><?php echo $player->name; ?></td>
<td><?php echo $player->level; ?></td>
<td><?php echo $player->vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
</tr>
<?php endforeach ?>
</tbody>
@ -523,7 +513,7 @@ else if (isset($_REQUEST['search'])) {
} ?>
</div>
<?php endif;
if ($db->hasTable('store_history')) { ?>
if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) { ?>
<div class="tab-pane fade" id="accounts-store">
<?php $store_history = $db->query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?>
<table class="table table-striped table-condensed table-responsive d-md-table">

View File

@ -8,6 +8,9 @@
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Changelog as ModelsChangelog;
defined('MYAAC') or die('Direct access not allowed!');
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
@ -78,7 +81,7 @@ if(!empty($action))
error(implode(", ", $errors));
}
$changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog' . '` ORDER BY `id` DESC')->fetchAll();
$changelogs = ModelsChangelog::orderBy('id')->get()->toArray();
$i = 0;

View File

@ -9,6 +9,9 @@
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Account Actions';
@ -26,15 +29,14 @@ function admin_give_points($points)
return;
}
$statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points');
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return;
}
if (!$statement->execute([
'points' => $points
])) {
if (!Account::query()->increment('premium_points', $points)) {
displayMessage('Failed to add points.');
return;
}
@ -50,15 +52,7 @@ function admin_give_coins($coins)
return;
}
$statement = $db->prepare('UPDATE `accounts` SET `coins` = `coins` + :coins');
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return;
}
if (!$statement->execute([
'coins' => $coins
])) {
if (!Account::query()->increment('coins', $coins)) {
displayMessage('Failed to add coins.');
return;
}

View File

@ -8,22 +8,19 @@
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Player;
use MyAAC\Models\PlayerOnline;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Teleport Actions';
function admin_teleport_position($x, $y, $z) {
global $db;
$statement = $db->prepare('UPDATE `players` SET `posx` = :x, `posy` = :y, `posz` = :z');
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return;
}
if (!$statement->execute([
'x' => $x, 'y' => $y, 'z' => $z
if (!Player::query()->update([
'posx' => $x, 'posy' => $y, 'posz' => $z
])) {
displayMessage('Failed to execute query.');
displayMessage('Failed to execute query. Probably already updated.');
return;
}
@ -31,17 +28,10 @@ function admin_teleport_position($x, $y, $z) {
}
function admin_teleport_town($town_id) {
global $db;
$statement = $db->prepare('UPDATE `players` SET `town_id` = :town_id');
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return;
}
if (!$statement->execute([
'town_id' => $town_id
if (!Player::query()->update([
'town_id' => $town_id,
])) {
displayMessage('Failed to execute query.');
displayMessage('Failed to execute query. Probably already updated.');
return;
}
@ -58,13 +48,12 @@ if (isset($_POST['action']) && $_POST['action']) {
$playersOnline = 0;
if($db->hasTable('players_online')) {// tfs 1.0
$query = $db->query('SELECT count(*) AS `count` FROM `players_online`');
$playersOnline = PlayerOnline::count();
} else {
$query = $db->query('SELECT count(*) AS `count` FROM `players` WHERE `players`.`online` > 0');
$playersOnline = Player::online()->count();
}
$playersOnline = $query->fetch(PDO::FETCH_ASSOC);
if ($playersOnline['count'] > 0) {
if ($playersOnline > 0) {
displayMessage('Please, close the server before execute this action otherwise players will not be affected.');
return;
}

View File

@ -7,6 +7,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Menu;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Menus';
@ -28,14 +31,22 @@ if (isset($_REQUEST['template'])) {
return;
}
$db->query('DELETE FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($template));
Menu::where('template', $template)->delete();
foreach ($post_menu as $category => $menus) {
foreach ($menus as $i => $menu) {
if (empty($menu)) // don't save empty menu item
continue;
try {
$db->insert(TABLE_PREFIX . 'menu', array('template' => $template, 'name' => $menu, 'link' => $post_menu_link[$category][$i], 'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0, 'color' => str_replace('#', '', $post_menu_color[$category][$i]), 'category' => $category, 'ordering' => $i));
Menu::create([
'template' => $template,
'name' => $menu,
'link' => $post_menu_link[$category][$i],
'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0,
'color' => str_replace('#', '', $post_menu_color[$category][$i]),
'category' => $category,
'ordering' => $i
]);
} catch (PDOException $error) {
warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage());
}
@ -58,6 +69,15 @@ if (isset($_REQUEST['template'])) {
return;
}
if (isset($_REQUEST['reset_colors'])) {
if (isset($config['menu_default_color'])) {
Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]);
}
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;
@ -71,17 +91,29 @@ if (isset($_REQUEST['template'])) {
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?');">
<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 = array();
$menus_db = $db->query('SELECT `name`, `link`, `blank`, `color`, `category`, `ordering` FROM `' . TABLE_PREFIX . 'menu` WHERE `enabled` = 1 AND `template` = ' . $db->quote($template) . ' ORDER BY `ordering` ASC;')->fetchAll();
foreach ($menus_db as $menu) {
$menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']);
}
$menus = Menu::query()
->select('name', 'link', 'blank', 'color', 'category', 'ordering')
->where('enabled', 1)
->where('template', $template)
->orderBy('ordering')
->get()
->groupBy('category')
->toArray();
$last_id = array();
?>
<form method="post" id="menus-form" action="?p=menus">
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<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">
@ -113,7 +145,7 @@ if (isset($_REQUEST['template'])) {
</div>
<div class="row pb-2">
<div class="col-md-12">
<button type="submit" class="btn btn-info"><i class="fas fa-update"></i> 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>';
?>
@ -129,7 +161,7 @@ if (isset($_REQUEST['template'])) {
?>
<?php
} else {
$templates = $db->query('SELECT `template` FROM `' . TABLE_PREFIX . 'menu` GROUP BY `template`;')->fetchAll();
$templates = Menu::select('template')->distinct()->get()->toArray();
foreach ($templates as $key => $value) {
$file = TEMPLATES . $value['template'] . '/config.php';
if (!file_exists($file)) {

View File

@ -1,7 +1,14 @@
<?php
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$balance = ($db->hasColumn('players', 'balance') ? $db->query('SELECT `balance`, `id`, `name`,`level` FROM `players` ORDER BY `balance` DESC LIMIT 10;') : 0);
$balance = 0;
if ($db->hasColumn('players', 'balance')) {
$balance = Player::orderByDesc('balance')->limit(10)->get(['balance', 'id','name', 'level'])->toArray();
}
$twig->display('balance.html.twig', array(
'balance' => $balance

View File

@ -1,7 +1,14 @@
<?php
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!');
$coins = ($db->hasColumn('accounts', 'coins') ? $db->query('SELECT `coins`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `coins` DESC LIMIT 10;') : 0);
$coins = 0;
if ($db->hasColumn('accounts', 'coins')) {
$coins = Account::orderByDesc('coins')->limit(10)->get(['coins', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray();
}
$twig->display('coins.html.twig', array(
'coins' => $coins

View File

@ -1,8 +1,15 @@
<?php
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!');
$players = ($db->hasColumn('accounts', 'created') ? $db->query('SELECT `created`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `created` DESC LIMIT 10;') : 0);
$accounts = 0;
if ($db->hasColumn('accounts', 'created')) {
$accounts = Account::orderByDesc('created')->limit(10)->get(['created', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray();
}
$twig->display('created.html.twig', array(
'players' => $players,
'accounts' => $accounts,
));

View File

@ -1,7 +1,15 @@
<?php
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$players = ($db->hasColumn('players', 'lastlogin') ? $db->query('SELECT name, level, lastlogin FROM players ORDER BY lastlogin DESC LIMIT 10;') : 0);
$players = 0;
if ($db->hasColumn('players', 'lastlogin')) {
$players = Player::orderByDesc('lastlogin')->limit(10)->get(['name', 'level', 'lastlogin'])->toArray();
}
$twig->display('lastlogin.html.twig', array(
'players' => $players,
));

View File

@ -1,7 +1,14 @@
<?php
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!');
$points = ($db->hasColumn('accounts', 'premium_points') ? $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;') : 0);
$points = 0;
if ($db->hasColumn('accounts', 'premium_points')) {
$coins = Account::orderByDesc('premium_points')->limit(10)->get(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray();
}
$twig->display('points.html.twig', array(
'points' => $points,

View File

@ -1,11 +1,20 @@
<?php
use MyAAC\Models\Account;
use MyAAC\Models\Guild;
use MyAAC\Models\House;
use MyAAC\Models\Monster;
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$count = $db->query('SELECT
(SELECT COUNT(*) FROM `accounts`) as total_accounts,
(SELECT COUNT(*) FROM `players`) as total_players,
(SELECT COUNT(*) FROM `guilds`) as total_guilds,
(SELECT COUNT(*) FROM `' . TABLE_PREFIX . 'monsters`) as total_monsters,
(SELECT COUNT(*) FROM `houses`) as total_houses;')->fetch();
$count = $eloquentConnection->query()
->select([
'total_accounts' => Account::selectRaw('COUNT(id)'),
'total_players' => Player::selectRaw('COUNT(id)'),
'total_guilds' => Guild::selectRaw('COUNT(id)'),
'total_monsters' => Monster::selectRaw('COUNT(id)'),
'total_houses' => House::selectRaw('COUNT(id)'),
])->first();
$twig->display('statistics.html.twig', array(
'count' => $count,

View File

@ -1,4 +1,4 @@
{% if players is iterable %}
{% if accounts is iterable %}
<div class=" col-md-6 col-lg-3">
<div class="card card-info card-outline">
<div class="card-header">
@ -15,7 +15,7 @@
</thead>
<tbody>
{% set i = 0 %}
{% for result in players %}
{% for result in accounts %}
{% set i = i + 1 %}
<tr>
<th>{{ i }}</th>

View File

@ -7,46 +7,33 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Notepad as ModelsNotepad;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Notepad';
$notepad_content = Notepad::get($account_logged->getId());
/**
* @var $account_logged OTS_Account
*/
$_content = '';
$notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first();
if (isset($_POST['content'])) {
$_content = html_entity_decode(stripslashes($_POST['content']));
if (!$notepad_content)
Notepad::create($account_logged->getId(), $_content);
else
Notepad::update($account_logged->getId(), $_content);
if (!$notepad) {
ModelsNotepad::create([
'account_id' => $account_logged->getId(),
'content' => $_content
]);
}
else {
ModelsNotepad::where('account_id', $account_logged->getId())->update(['content' => $_content]);
}
echo '<div class="success" style="text-align: center;">Saved at ' . date('H:i') . '</div>';
success('Saved at ' . date('H:i'));
} else {
if ($notepad_content !== false)
$_content = $notepad_content;
if ($notepad)
$_content = $notepad->content;
}
$twig->display('admin.notepad.html.twig', array('content' => isset($_content) ? $_content : null));
class Notepad
{
static public function get($account_id)
{
global $db;
$query = $db->select(TABLE_PREFIX . 'notepad', array('account_id' => $account_id));
if ($query !== false)
return $query['content'];
return false;
}
static public function create($account_id, $content = '')
{
global $db;
$db->insert(TABLE_PREFIX . 'notepad', array('account_id' => $account_id, 'content' => $content));
}
static public function update($account_id, $content = '')
{
global $db;
$db->update(TABLE_PREFIX . 'notepad', array('content' => $content), array('account_id' => $account_id));
}
}
$twig->display('admin.notepad.html.twig', ['content' => $_content]);

View File

@ -7,6 +7,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Pages as ModelsPages;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Pages';
$use_datatable = true;
@ -94,19 +97,15 @@ if (!empty($action)) {
error(implode(", ", $errors));
}
$query =
$db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'pages'));
$pages = array();
foreach ($query as $_page) {
$pages[] = array(
'link' => getFullLink($_page['name'], $_page['name'], true),
'title' => substr($_page['title'], 0, 20),
'php' => $_page['php'] == '1',
'id' => $_page['id'],
'hidden' => $_page['hidden']
);
}
$pages = ModelsPages::all()->map(function ($e) {
return [
'link' => getFullLink($e->name, $e->name, true),
'title' => substr($e->title, 0, 20),
'php' => $e->php == '1',
'id' => $e->id,
'hidden' => $e->hidden
];
})->toArray();
$twig->display('admin.pages.form.html.twig', array(
'action' => $action,
@ -170,10 +169,10 @@ class Pages
static public function get($id)
{
global $db;
$query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id));
if ($query !== false)
return $query;
$row = ModelsPages::find($id);
if ($row) {
return $row->toArray();
}
return false;
}
@ -184,20 +183,16 @@ class Pages
return false;
}
global $db;
$query = $db->select(TABLE_PREFIX . 'pages', array('name' => $name));
if ($query === false)
$db->insert(TABLE_PREFIX . 'pages',
array(
'name' => $name,
'title' => $title,
'body' => $body,
'player_id' => $player_id,
'php' => $php ? '1' : '0',
'enable_tinymce' => $enable_tinymce ? '1' : '0',
'access' => $access
)
);
if (!ModelsPages::where('name', $name)->exists())
ModelsPages::create([
'name' => $name,
'title' => $title,
'body' => $body,
'player_id' => $player_id,
'php' => $php ? '1' : '0',
'enable_tinymce' => $enable_tinymce ? '1' : '0',
'access' => $access
]);
else
$errors[] = 'Page with this link already exists.';
@ -210,28 +205,25 @@ class Pages
return false;
}
global $db;
$db->update(TABLE_PREFIX . 'pages',
array(
'name' => $name,
'title' => $title,
'body' => $body,
'player_id' => $player_id,
'php' => $php ? '1' : '0',
'enable_tinymce' => $enable_tinymce ? '1' : '0',
'access' => $access
),
array('id' => $id));
ModelsPages::where('id', $id)->update([
'name' => $name,
'title' => $title,
'body' => $body,
'player_id' => $player_id,
'php' => $php ? '1' : '0',
'enable_tinymce' => $enable_tinymce ? '1' : '0',
'access' => $access
]);
return true;
}
static public function delete($id, &$errors)
{
global $db;
if (isset($id)) {
if ($db->select(TABLE_PREFIX . 'pages', array('id' => $id)) !== false)
$db->delete(TABLE_PREFIX . 'pages', array('id' => $id));
$row = ModelsPages::find($id);
if ($row) {
$row->delete();
}
else
$errors[] = 'Page with id ' . $id . ' does not exists.';
} else
@ -242,12 +234,12 @@ class Pages
static public function toggleHidden($id, &$errors, &$status)
{
global $db;
if (isset($id)) {
$query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id));
if ($query !== false) {
$db->update(TABLE_PREFIX . 'pages', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
$status = $query['hidden'];
$row = ModelsPages::find($id);
if ($row) {
$row->hidden = $row->hidden == 1 ? 0 : 1;
$row->save();
$status = $row->hidden;
}
else {
$errors[] = 'Page with id ' . $id . ' does not exists.';

View File

@ -7,6 +7,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Player editor';
@ -744,8 +747,7 @@ else if (isset($_REQUEST['search'])) {
<div class="row">
<?php
if (isset($account) && $account->isLoaded()) {
$account_players = $account->getPlayersList();
$account_players->orderBy('id');
$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get();
if (isset($account_players)) { ?>
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
@ -758,23 +760,13 @@ else if (isset($_REQUEST['search'])) {
</tr>
</thead>
<tbody>
<?php foreach ($account_players as $i => $player):
$player_vocation = $player->getVocation();
$player_promotion = $player->getPromotion();
if (isset($player_promotion)) {
if ((int)$player_promotion > 0)
$player_vocation += ($player_promotion * $config['vocations_amount']);
}
if (isset($config['vocations'][$player_vocation])) {
$vocation_name = $config['vocations'][$player_vocation];
} ?>
<?php foreach ($account_players as $i => $player): ?>
<tr>
<th><?php echo $i; ?></th>
<td><?php echo $player->getName(); ?></td>
<td><?php echo $player->getLevel(); ?></td>
<td><?php echo $vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getId() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
<th><?php echo $i + 1; ?></th>
<td><?php echo $player->name; ?></td>
<td><?php echo $player->level; ?></td>
<td><?php echo $player->vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
</tr>
<?php endforeach ?>
</tbody>

View File

@ -7,26 +7,25 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Account;
use MyAAC\Models\Guild;
use MyAAC\Models\House;
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Statistics';
$query = $db->query('SELECT count(*) as `how_much` FROM `accounts`;');
$query = $query->fetch();
$total_accounts = $query['how_much'];
$total_accounts = Account::count();
$total_players = Player::count();
$total_guilds = Guild::count();
$total_houses = House::count();
$query = $db->query('SELECT count(*) as `how_much` FROM `players`;');
$query = $query->fetch();
$total_players = $query['how_much'];
$query = $db->query('SELECT count(*) as `how_much` FROM `guilds`;');
$query = $query->fetch();
$total_guilds = $query['how_much'];
$query = $db->query('SELECT count(*) as `how_much` FROM `houses`;');
$query = $query->fetch();
$total_houses = $query['how_much'];
$points = $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;');
$points = Account::select(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')])
->orderByDesc('premium_points')
->limit(10)
->get()
->toArray();
$twig->display('admin.statistics.html.twig', array(
'total_accounts' => $total_accounts,

View File

@ -23,7 +23,7 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.');
if (version_compare(phpversion(), '8.0', '<')) die('PHP version 8.0 or higher is required.');
const MYAAC = true;
const MYAAC_VERSION = '0.10.0-dev';

View File

@ -1,6 +1,6 @@
{
"require": {
"php": "^7.2.5 || ^8.0",
"php": "^8.0",
"ext-pdo": "*",
"ext-pdo_mysql": "*",
"ext-json": "*",
@ -11,10 +11,16 @@
"twig/twig": "^2.0",
"erusev/parsedown": "^1.7",
"nikic/fast-route": "^1.3",
"matomo/device-detector": "^6.0"
"matomo/device-detector": "^6.0",
"illuminate/database": "^10.18"
},
"require-dev": {
"filp/whoops": "^2.15",
"maximebf/debugbar": "dev-master"
},
"autoload": {
"psr-4": {
"MyAAC\\": "system/src"
}
}
}

View File

@ -0,0 +1,174 @@
describe('Check Public Pages', () => {
/// news
it('Go to news page', () => {
cy.visit({
url: Cypress.env('URL') + '/news',
method: 'GET',
})
})
it('Go to news archive page', () => {
cy.visit({
url: Cypress.env('URL') + '/news/archive',
method: 'GET',
})
})
it('Go to changelog page', () => {
cy.visit({
url: Cypress.env('URL') + '/changelog',
method: 'GET',
})
})
/// account management
it('Go to account manage page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/manage',
method: 'GET',
})
})
it('Go to account create page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/create',
method: 'GET',
})
})
it('Go to account lost page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/lost',
method: 'GET',
})
})
it('Go to rules page', () => {
cy.visit({
url: Cypress.env('URL') + '/rules',
method: 'GET',
})
})
// community
it('Go to online page', () => {
cy.visit({
url: Cypress.env('URL') + '/online',
method: 'GET',
})
})
it('Go to characters list page', () => {
cy.visit({
url: Cypress.env('URL') + '/characters',
method: 'GET',
})
})
it('Go to guilds page', () => {
cy.visit({
url: Cypress.env('URL') + '/guilds',
method: 'GET',
})
})
it('Go to highscores page', () => {
cy.visit({
url: Cypress.env('URL') + '/highscores',
method: 'GET',
})
})
it('Go to last kills page', () => {
cy.visit({
url: Cypress.env('URL') + '/lastkills',
method: 'GET',
})
})
it('Go to houses page', () => {
cy.visit({
url: Cypress.env('URL') + '/houses',
method: 'GET',
})
})
it('Go to bans page', () => {
cy.visit({
url: Cypress.env('URL') + '/bans',
method: 'GET',
})
})
it('Go to forum page', () => {
cy.visit({
url: Cypress.env('URL') + '/forum',
method: 'GET',
})
})
it('Go to team page', () => {
cy.visit({
url: Cypress.env('URL') + '/team',
method: 'GET',
})
})
// library
it('Go to creatures page', () => {
cy.visit({
url: Cypress.env('URL') + '/creatures',
method: 'GET',
})
})
it('Go to spells page', () => {
cy.visit({
url: Cypress.env('URL') + '/spells',
method: 'GET',
})
})
it('Go to server info page', () => {
cy.visit({
url: Cypress.env('URL') + '/serverInfo',
method: 'GET',
})
})
it('Go to commands page', () => {
cy.visit({
url: Cypress.env('URL') + '/commands',
method: 'GET',
})
})
it('Go to downloads page', () => {
cy.visit({
url: Cypress.env('URL') + '/downloads',
method: 'GET',
})
})
it('Go to gallery page', () => {
cy.visit({
url: Cypress.env('URL') + '/gallery',
method: 'GET',
})
})
it('Go to experience table page', () => {
cy.visit({
url: Cypress.env('URL') + '/experienceTable',
method: 'GET',
})
})
it('Go to faq page', () => {
cy.visit({
url: Cypress.env('URL') + '/faq',
method: 'GET',
})
})
})

View File

@ -0,0 +1,81 @@
const REQUIRED_LOGIN_MESSAGE = 'Please enter your account name and your password.';
const YOU_ARE_NOT_LOGGEDIN = 'You are not logged in.';
describe('Check Protected Pages', () => {
// character actions
it('Go to accouht character creation page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/character/create',
method: 'GET',
})
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
it('Go to accouht character deletion page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/character/delete',
method: 'GET',
})
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
// account actions
it('Go to accouht email change page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/email',
method: 'GET',
})
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
it('Go to accouht password change page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/password',
method: 'GET',
})
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
it('Go to accouht info change page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/info',
method: 'GET',
})
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
it('Go to accouht logout change page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/logout',
method: 'GET',
})
cy.contains(REQUIRED_LOGIN_MESSAGE)
})
// guild actions
it('Go to guild creation page', () => {
cy.visit({
url: Cypress.env('URL') + '/?subtopic=guilds&action=create',
method: 'GET',
})
cy.contains(YOU_ARE_NOT_LOGGEDIN)
})
it('Go to guilds cleanup players action page', () => {
cy.visit({
url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_players',
method: 'GET',
})
cy.contains(YOU_ARE_NOT_LOGGEDIN)
})
it('Go to guilds cleanup guilds action page', () => {
cy.visit({
url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_guilds',
method: 'GET',
})
cy.contains(YOU_ARE_NOT_LOGGEDIN)
})
})

View File

View File

@ -127,70 +127,6 @@ CREATE TABLE `myaac_menu`
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
/* MENU_CATEGORY_NEWS kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Latest News', 'news', 1, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'News Archive', 'news/archive', 1, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Changelog', 'changelog', 1, 2);
/* MENU_CATEGORY_ACCOUNT kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Account Management', 'account/manage', 2, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Create Account', 'account/create', 2, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Lost Account?', 'account/lost', 2, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Rules', 'rules', 2, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Downloads', 'downloads', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Report Bug', 'bugtracker', 2, 5);
/* MENU_CATEGORY_COMMUNITY kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Who is Online?', 'online', 3, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Characters', 'characters', 3, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Guilds', 'guilds', 3, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Highscores', 'highscores', 3, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Last Deaths', 'lastkills', 3, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Houses', 'houses', 3, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Bans', 'bans', 3, 6);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Forum', 'forum', 3, 7);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Team', 'team', 3, 8);
/* MENU_CATEGORY_LIBRARY kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Monsters', 'creatures', 5, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Spells', 'spells', 5, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Info', 'serverInfo', 5, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Commands', 'commands', 5, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Gallery', 'gallery', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Experience Table', 'experienceTable', 5, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'FAQ', 'faq', 5, 6);
/* MENU_CATEGORY_SHOP kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop Offer', 'gifts', 6, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop History', 'gifts/history', 6, 2);
/* MENU_CATEGORY_NEWS tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Latest News', 'news', 1, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'News Archive', 'news/archive', 1, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Changelog', 'changelog', 1, 2);
/* MENU_CATEGORY_ACCOUNT tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Account Management', 'account/manage', 2, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Create Account', 'account/create', 2, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Lost Account?', 'account/lost', 2, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Rules', 'rules', 2, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Downloads', 'downloads', 2, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Report Bug', 'bugtracker', 2, 5);
/* MENU_CATEGORY_COMMUNITY tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Characters', 'characters', 3, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Who Is Online?', 'online', 3, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Highscores', 'highscores', 3, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Last Kills', 'lastkills', 3, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Houses', 'houses', 3, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Guilds', 'guilds', 3, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Polls', 'polls', 3, 6);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Bans', 'bans', 3, 7);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Support List', 'team', 3, 8);
/* MENU_CATEGORY_FORUM tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Forum', 'forum', 4, 0);
/* MENU_CATEGORY_LIBRARY tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Creatures', 'creatures', 5, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Spells', 'spells', 5, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Commands', 'commands', 5, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Exp Stages', 'experienceStages', 5, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Gallery', 'gallery', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Info', 'serverInfo', 5, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Experience Table', 'experienceTable', 5, 6);
/* MENU_CATEGORY_SHOP tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop Offer', 'gifts', 6, 1);

View File

@ -34,6 +34,8 @@ if(!$error) {
}
}
$configToSave['gzip_output'] = false;
$configToSave['cache_engine'] = 'auto';
$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true);
require BASE . 'install/includes/config.php';

View File

@ -45,6 +45,10 @@ if($success) {
success($locale['step_database_imported_players']);
}
require_once LIBS . 'plugins.php';
Plugins::installMenus('kathrine', require TEMPLATES . 'kathrine/menus.php');
Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php');
require LIBS . 'DataLoader.php';
DataLoader::setLocale($locale);
DataLoader::load();
@ -59,6 +63,14 @@ require_once SYSTEM . 'migrations/22.php';
require_once SYSTEM . 'migrations/27.php';
require_once SYSTEM . 'migrations/30.php';
use MyAAC\Models\FAQ as ModelsFAQ;
if(ModelsFAQ::count() == 0) {
ModelsFAQ::create([
'question' => 'What is this?',
'answer' => 'This is website for OTS powered by MyAAC.',
]);
}
$locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(str_replace('tools/', '', BASE_URL), $locale['step_finish_homepage'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$LINK$', generateLink('https://my-aac.org', 'https://my-aac.org', true), $locale['step_finish_desc']);

100
login.php
View File

@ -1,4 +1,8 @@
<?php
use MyAAC\Models\BoostedCreature;
use MyAAC\Models\PlayerOnline;
require_once 'common.php';
require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php';
@ -43,9 +47,9 @@ $action = $request->type ?? '';
switch ($action) {
case 'cacheinfo':
$playersonline = $db->query("select count(*) from `players_online`")->fetchAll();
$playersonline = PlayerOnline::count();
die(json_encode([
'playersonline' => (intval($playersonline[0][0])),
'playersonline' => $playersonline,
'twitchstreams' => 0,
'twitchviewer' => 0,
'gamingyoutubestreams' => 0,
@ -79,13 +83,11 @@ switch ($action) {
die(json_encode(['eventlist' => $eventlist, 'lastupdatetimestamp' => time()]));
case 'boostedcreature':
$boostDB = $db->query("select * from " . $db->tableName('boosted_creature'))->fetchAll();
foreach ($boostDB as $Tableboost) {
$boostedCreature = BoostedCreature::latest();
die(json_encode([
'boostedcreature' => true,
'raceid' => intval($Tableboost['raceid'])
'raceid' => $boostedCreature->raceid
]));
}
break;
case 'login':
@ -112,29 +114,32 @@ switch ($action) {
];
$characters = [];
$account = new OTS_Account();
$inputEmail = $request->email ?? false;
$inputAccountName = $request->accountname ?? false;
$inputToken = $request->token ?? false;
$account = Account::query();
if ($inputEmail != false) { // login by email
$account->findByEmail($request->email);
$account->where('email', $inputEmail);
}
else if($inputAccountName != false) { // login by account name
$account->find($inputAccountName);
$account->where('name', $inputAccountName);
}
$current_password = encrypt((USE_ACCOUNT_SALT ? $account->getCustomField('salt') : '') . $request->password);
if (!$account->isLoaded() || $account->getPassword() != $current_password) {
$account = $account->first();
if (!$account) {
sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.');
}
$current_password = encrypt((USE_ACCOUNT_SALT ? $account->salt : '') . $request->password);
if (!$account || $account->password != $current_password) {
sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.');
}
//log_append('test.log', var_export($account->getCustomField('secret'), true));
$accountHasSecret = false;
if (fieldExist('secret', 'accounts')) {
$accountSecret = $account->getCustomField('secret');
$accountSecret = $account->secret;
if ($accountSecret != null && $accountSecret != '') {
$accountHasSecret = true;
if ($inputToken === false) {
@ -159,18 +164,9 @@ switch ($action) {
$columns .= ', istutorial';
}
$players = $db->query("select {$columns} from players where account_id = " . $account->getId() . " AND deletion = 0");
if($players && $players->rowCount() > 0) {
$players = $players->fetchAll();
$highestLevelId = 0;
$highestLevel = 0;
foreach ($players as $player) {
if ($player['level'] >= $highestLevel) {
$highestLevel = $player['level'];
$highestLevelId = $player['id'];
}
}
$players = Player::where('account_id', $account->id)->notDeleted()->selectRaw($columns)->get();
if($players && $players->count()) {
$highestLevelId = $players->sortByDesc('experience')->first()->getKey();
foreach ($players as $player) {
$characters[] = create_char($player, $highestLevelId);
@ -180,15 +176,10 @@ switch ($action) {
if (fieldExist('premdays', 'accounts') && fieldExist('lastday', 'accounts')) {
$save = false;
$timeNow = time();
$query = $db->query("select `premdays`, `lastday` from `accounts` where `id` = " . $account->getId());
if ($query->rowCount() > 0) {
$query = $query->fetch();
$premDays = (int)$query['premdays'];
$lastDay = (int)$query['lastday'];
$lastLogin = $lastDay;
} else {
sendError("Error while fetching your account data. Please contact admin.");
}
$premDays = $account->premdays;
$lastDay = $account->lastday;
$lastLogin = $lastDay;
if ($premDays != 0 && $premDays != PHP_INT_MAX) {
if ($lastDay == 0) {
$lastDay = $timeNow;
@ -213,7 +204,9 @@ switch ($action) {
$save = true;
}
if ($save) {
$db->query("update `accounts` set `premdays` = " . $premDays . ", `lastday` = " . $lastDay . " where `id` = " . $account->getId());
$account->premdays = $premDays;
$account->lastday = $lastDay;
$account->save();
}
}
@ -235,13 +228,11 @@ switch ($action) {
$sessionKey .= "\n".floor(time() / 30);
}
//log_append('slaw.log', $sessionKey);
$session = [
'sessionkey' => $sessionKey,
'lastlogintime' => 0,
'ispremium' => $config['lua']['freePremium'] || $account->isPremium(),
'premiumuntil' => ($account->getPremDays()) > 0 ? (time() + ($account->getPremDays() * 86400)) : 0,
'ispremium' => $account->is_premium,
'premiumuntil' => ($account->premium_days) > 0 ? (time() + ($account->premium_days * 86400)) : 0,
'status' => 'active', // active, frozen or suspended
'returnernotification' => false,
'showrewardnews' => true,
@ -259,24 +250,23 @@ switch ($action) {
}
function create_char($player, $highestLevelId) {
global $config;
return [
'worldid' => 0,
'name' => $player['name'],
'ismale' => intval($player['sex']) === 1,
'tutorial' => isset($player['istutorial']) && $player['istutorial'],
'level' => intval($player['level']),
'vocation' => $config['vocations'][$player['vocation']],
'outfitid' => intval($player['looktype']),
'headcolor' => intval($player['lookhead']),
'torsocolor' => intval($player['lookbody']),
'legscolor' => intval($player['looklegs']),
'detailcolor' => intval($player['lookfeet']),
'addonsflags' => intval($player['lookaddons']),
'ishidden' => isset($player['deletion']) && (int)$player['deletion'] === 1,
'name' => $player->name,
'ismale' => $player->sex === 1,
'tutorial' => isset($player->istutorial) && $player->istutorial,
'level' => $player->level,
'vocation' => $player->vocation_name,
'outfitid' => $player->looktype,
'headcolor' => $player->lookhead,
'torsocolor' => $player->lookbody,
'legscolor' => $player->looklegs,
'detailcolor' => $player->lookfeet,
'addonsflags' => $player->lookaddons,
'ishidden' => $player->is_deleted,
'istournamentparticipant' => false,
'ismaincharacter' => $highestLevelId == $player['id'],
'dailyrewardstate' => isset($player['isreward']) ? intval($player['isreward']) : 0,
'ismaincharacter' => $highestLevelId === $player->getKey(),
'dailyrewardstate' => $player->isreward ?? 0,
'remainingdailytournamentplaytime' => 0
];
}

View File

@ -1,4 +1,7 @@
{
"scripts": {
"cypress:open": "cypress open"
},
"devDependencies": {
"cypress": "^12.12.0"
}

View File

@ -34,8 +34,18 @@ $deprecatedConfig = [
'news_limit',
'news_ticker_limit',
'news_date_format',
'guild_management',
'guild_need_level',
'guild_need_premium',
'guild_image_size_kb',
'guild_description_default',
'guild_description_chars_limit',
'guild_motd_chars_limit',
'highscores_groups_hidden',
'highscores_ids_hidden',
'highscores_vocation_box',
'highscores_vocation',
'highscores_outfit',
'online_record',
'online_vocations',
'online_vocations_images',
@ -61,6 +71,9 @@ $deprecatedConfig = [
'account_login_by_email',
'account_login_by_email_fallback',
'account_mail_verify',
'account_mail_unique',
'account_premium_days',
'account_premium_points',
'account_create_character_create',
'account_change_character_name',
'account_change_character_name_points' => 'account_change_character_name_price',

View File

@ -7,6 +7,9 @@
* @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'])) {
@ -91,21 +94,34 @@ 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']
)
);
'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']
));
$db = POT::getInstance()->getDBHandle();
}
catch(PDOException $error) {
$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');
}
@ -119,5 +135,5 @@ catch(PDOException $error) {
'<ul>' .
'<li>MySQL is not configured propertly in <i>config.lua</i>.</li>' .
'<li>MySQL server is not running.</li>' .
'</ul>' . $error->getMessage());
'</ul>' . $e->getMessage());
}

View File

@ -9,6 +9,11 @@
*/
defined('MYAAC') or die('Direct access not allowed!');
use MyAAC\Models\Config;
use MyAAC\Models\Guild;
use MyAAC\Models\House;
use MyAAC\Models\Pages;
use MyAAC\Models\Player;
use PHPMailer\PHPMailer\PHPMailer;
use Twig\Loader\ArrayLoader as Twig_ArrayLoader;
@ -99,16 +104,15 @@ function getMonsterLink($name, $generate = true): string
function getHouseLink($name, $generate = true): string
{
global $db;
if(is_numeric($name))
{
$house = $db->query(
'SELECT `name` FROM `houses` WHERE `id` = ' . (int)$name);
if($house->rowCount() > 0)
$name = $house->fetchColumn();
$house = House::find(intval($name), ['name']);
if ($house) {
$name = $house->name;
}
}
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses/' . urlencode($name);
if(!$generate) return $url;
@ -118,10 +122,8 @@ function getHouseLink($name, $generate = true): string
function getGuildLink($name, $generate = true): string
{
if(is_numeric($name)) {
$name = getGuildNameById($name);
if ($name === false) {
$name = 'Unknown';
}
$guild = Guild::find(intval($name), ['name']);
$name = $guild->name ?? 'Unknown';
}
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'guilds/' . urlencode($name);
@ -272,13 +274,12 @@ function getForumBoards()
*/
function fetchDatabaseConfig($name, &$value)
{
global $db;
$query = $db->query('SELECT `value` FROM `' . TABLE_PREFIX . 'config` WHERE `name` = ' . $db->quote($name));
if($query->rowCount() <= 0)
$config = Config::select('value')->where('name', '=', $name)->first();
if (!$config) {
return false;
}
$value = $query->fetchColumn();
$value = $config->value;
return true;
}
@ -303,8 +304,7 @@ function getDatabaseConfig($name)
*/
function registerDatabaseConfig($name, $value)
{
global $db;
$db->insert(TABLE_PREFIX . 'config', array('name' => $name, 'value' => $value));
Config::create(compact('name', 'value'));
}
/**
@ -315,8 +315,9 @@ function registerDatabaseConfig($name, $value)
*/
function updateDatabaseConfig($name, $value)
{
global $db;
$db->update(TABLE_PREFIX . 'config', array('value' => $value), array('name' => $name));
Config::where('name', '=', $name)->update([
'value' => $value
]);
}
/**
@ -343,47 +344,55 @@ function encrypt($str)
//delete player with name
function delete_player($name)
{
global $db;
$player = new OTS_Player();
$player->find($name);
if($player->isLoaded()) {
try { $db->exec("DELETE FROM player_skills WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM guild_invites WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_items WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_depotitems WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_spells WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_storage WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_viplist WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_deaths WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_deaths WHERE killed_by = '".$player->getId()."';"); } catch(PDOException $error) {}
$rank = $player->getRank();
if($rank->isLoaded()) {
$guild = $rank->getGuild();
if($guild->getOwner()->getId() == $player->getId()) {
$rank_list = $guild->getGuildRanksList();
if(count($rank_list) > 0) {
$rank_list->orderBy('level');
foreach($rank_list as $rank_in_guild) {
$players_with_rank = $rank_in_guild->getPlayersList();
$players_with_rank->orderBy('name');
$players_with_rank_number = count($players_with_rank);
if($players_with_rank_number > 0) {
foreach($players_with_rank as $player_in_guild) {
$player_in_guild->setRank();
$player_in_guild->save();
}
}
$rank_in_guild->delete();
}
$guild->delete();
}
}
}
$player->delete();
return true;
// DB::beginTransaction();
global $capsule;
$player = Player::where(compact('name'))->first();
if (!$player) {
return false;
}
return false;
// global $db;
// $player = new OTS_Player();
// $player->find($name);
// if($player->isLoaded()) {
// try { $db->exec("DELETE FROM player_skills WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM guild_invites WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_items WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_depotitems WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_spells WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_storage WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_viplist WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_deaths WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_deaths WHERE killed_by = '".$player->getId()."';"); } catch(PDOException $error) {}
// $rank = $player->getRank();
// if($rank->isLoaded()) {
// $guild = $rank->getGuild();
// if($guild->getOwner()->getId() == $player->getId()) {
// $rank_list = $guild->getGuildRanksList();
// if(count($rank_list) > 0) {
// $rank_list->orderBy('level');
// foreach($rank_list as $rank_in_guild) {
// $players_with_rank = $rank_in_guild->getPlayersList();
// $players_with_rank->orderBy('name');
// $players_with_rank_number = count($players_with_rank);
// if($players_with_rank_number > 0) {
// foreach($players_with_rank as $player_in_guild) {
// $player_in_guild->setRank();
// $player_in_guild->save();
// }
// }
// $rank_in_guild->delete();
// }
// $guild->delete();
// }
// }
// }
// $player->delete();
// return true;
// }
// return false;
}
//delete guild with id
@ -492,7 +501,7 @@ function template_place_holder($type): string
function template_header($is_admin = false): string
{
global $title_full, $config, $twig;
$charset = isset($config['charset']) ? $config['charset'] : 'utf-8';
$charset = $config['charset'] ?? 'utf-8';
return $twig->render('templates.header.html.twig',
[
@ -1059,26 +1068,38 @@ function getTopPlayers($limit = 5) {
}
if (!isset($players)) {
$deleted = 'deleted';
if($db->hasColumn('players', 'deletion'))
$deleted = 'deletion';
$columns = [
'id', 'name', 'level', 'vocation', 'experience',
'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet'
];
$is_tfs10 = $db->hasTable('players_online');
$players = $db->query('SELECT `id`, `name`, `level`, `vocation`, `experience`, `looktype`' . ($db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `lookhead`, `lookbody`, `looklegs`, `lookfeet`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . setting('core.highscores_groups_hidden') . ' AND `id` NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll();
if($is_tfs10) {
foreach($players as &$player) {
$query = $db->query('SELECT `player_id` FROM `players_online` WHERE `player_id` = ' . $player['id']);
$player['online'] = ($query->rowCount() > 0 ? 1 : 0);
}
unset($player);
if ($db->hasColumn('players', 'lookaddons')) {
$columns[] = 'lookaddons';
}
$i = 0;
foreach($players as &$player) {
$player['rank'] = ++$i;
if ($db->hasColumn('players', 'online')) {
$columns[] = 'online';
}
unset($player);
$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('experience')
->limit($limit)
->get()
->map(function ($e, $i) {
$row = $e->toArray();
$row['online'] = $e->online_status;
$row['rank'] = $i + 1;
unset($row['online_table']);
return $row;
})->toArray();
if($cache->enabled()) {
$cache->set('top_' . $limit . '_level', serialize($players), 120);
@ -1212,49 +1233,44 @@ function clearCache()
return true;
}
function getCustomPageInfo($page)
function getCustomPageInfo($name)
{
global $db, $logged_access;
$query =
$db->query(
'SELECT `id`, `title`, `body`, `php`, `hidden`' .
' FROM `' . TABLE_PREFIX . 'pages`' .
' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access));
if($query->rowCount() > 0) // found page
{
return $query->fetch(PDO::FETCH_ASSOC);
global $logged_access;
$page = Pages::isPublic()
->where('name', 'LIKE', $name)
->where('access', '<=', $logged_access)
->first();
if (!$page) {
return null;
}
return null;
return $page->toArray();
}
function getCustomPage($page, &$success): string
function getCustomPage($name, &$success): string
{
global $db, $twig, $title, $ignore, $logged_access;
global $twig, $title, $ignore;
$success = false;
$content = '';
$query =
$db->query(
'SELECT `id`, `title`, `body`, `php`, `hidden`' .
' FROM `' . TABLE_PREFIX . 'pages`' .
' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access));
if($query->rowCount() > 0) // found page
$page = getCustomPageInfo($name);
if($page) // found page
{
$success = $ignore = true;
$query = $query->fetch();
$title = $query['title'];
$title = $page['title'];
if($query['php'] == '1') // execute it as php code
if($page['php'] == '1') // execute it as php code
{
$tmp = substr($query['body'], 0, 10);
$tmp = substr($page['body'], 0, 10);
if(($pos = strpos($tmp, '<?php')) !== false) {
$tmp = preg_replace('/<\?php/', '', $query['body'], 1);
$tmp = preg_replace('/<\?php/', '', $page['body'], 1);
}
else if(($pos = strpos($tmp, '<?')) !== false) {
$tmp = preg_replace('/<\?/', '', $query['body'], 1);
$tmp = preg_replace('/<\?/', '', $page['body'], 1);
}
else
$tmp = $query['body'];
$tmp = $page['body'];
$php_errors = array();
function error_handler($errno, $errstr) {
@ -1282,7 +1298,7 @@ function getCustomPage($page, &$success): string
$oldLoader = $twig->getLoader();
$twig_loader_array = new Twig_ArrayLoader(array(
'content.html' => $query['body']
'content.html' => $page['body']
));
$twig->setLoader($twig_loader_array);
@ -1397,39 +1413,42 @@ function getChangelogWhere($v)
return 'unknown';
}
function getPlayerNameByAccount($id)
function getPlayerNameByAccountId($id)
{
global $vowels, $ots, $db;
if(is_numeric($id))
{
$player = new OTS_Player();
$player->load($id);
if($player->isLoaded())
return $player->getName();
else
{
$playerQuery = $db->query('SELECT `id` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;')->fetch();
if (!is_numeric($id)) {
return '';
}
$tmp = "*Error*";
/*
$acco = new OTS_Account();
$acco->load($id);
if(!$acco->isLoaded())
return "Unknown name";
foreach($acco->getPlayersList() as $p)
{
$player= new OTS_Player();
$player->find($p);*/
$player->load($playerQuery['id']);
//echo 'id gracza = ' . $p . '<br/>';
if($player->isLoaded())
$tmp = $player->getName();
// break;
//}
return $tmp;
$account = \MyAAC\Models\Account::find(intval($id), ['id']);
if ($account) {
$player = \MyAAC\Models\Player::where('account_id', $account->id)->orderByDesc('lastlogin')->select('name')->first();
if (!$player) {
return '';
}
return $player->name;
}
return '';
}
function getPlayerNameByAccount($account) {
if (is_numeric($account)) {
return getPlayerNameByAccountId($account);
}
return '';
}
function getPlayerNameById($id)
{
if (!is_numeric($id)) {
return '';
}
$player = \MyAAC\Models\Player::find((int)$id, ['name']);
if ($player) {
return $player->name;
}
return '';
@ -1437,13 +1456,13 @@ function getPlayerNameByAccount($id)
function echo_success($message)
{
echo '<div class="col-12 success mb-2">' . $message . '</div>';
echo '<div class="col-12 alert alert-success mb-2">' . $message . '</div>';
}
function echo_error($message)
{
global $error;
echo '<div class="col-12 error mb-2">' . $message . '</div>';
echo '<div class="col-12 alert alert-error mb-2">' . $message . '</div>';
$error = true;
}
@ -1584,12 +1603,9 @@ function escapeHtml($html) {
function getGuildNameById($id)
{
global $db;
$guild = $db->query('SELECT `name` FROM `guilds` WHERE `id` = ' . (int)$id);
if($guild->rowCount() > 0) {
return $guild->fetchColumn();
$guild = Guild::where('id', intval($id))->select('name')->first();
if ($guild) {
return $guild->name;
}
return false;
@ -1597,15 +1613,11 @@ function getGuildNameById($id)
function getGuildLogoById($id)
{
global $db;
$logo = 'default.gif';
$query = $db->query('SELECT `logo_name` FROM `guilds` WHERE `id` = ' . (int)$id);
if ($query->rowCount() == 1) {
$query = $query->fetch(PDO::FETCH_ASSOC);
$guildLogo = $query['logo_name'];
$guild = Guild::where('id', intval($id))->select('logo_name')->first();
if ($guild) {
$guildLogo = $query->logo_name;
if (!empty($guildLogo) && file_exists(GUILD_IMAGES_DIR . $guildLogo)) {
$logo = $guildLogo;

View File

@ -121,9 +121,11 @@ if(!isset($foundValue)) {
$config['data_path'] = $foundValue;
unset($foundValue);
// POT
require_once SYSTEM . 'libs/pot/OTS.php';
$ots = POT::getInstance();
$eloquentConnection = null;
require_once SYSTEM . 'database.php';
// execute migrations

View File

@ -1,60 +0,0 @@
<?php
/**
* Item parser
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
require_once SYSTEM . 'libs/items_images.php';
Items_Images::$files = array(
'otb' => SYSTEM . 'data/items.otb',
'spr' => SYSTEM . 'data/Tibia.spr',
'dat' => SYSTEM . 'data/Tibia.dat'
);
Items_Images::$outputDir = BASE . 'images/items/';
function generateItem($id = 100, $count = 1) {
Items_Images::generate($id, $count);
}
function itemImageExists($id, $count = 1)
{
if(!isset($id))
throw new RuntimeException('ERROR - itemImageExists: id has been not set!');
$file_name = $id;
if($count > 1)
$file_name .= '-' . $count;
$file_name = Items_Images::$outputDir . $file_name . '.gif';
return file_exists($file_name);
}
function outputItem($id = 100, $count = 1)
{
if(!(int)$count)
$count = 1;
if(!itemImageExists($id, $count))
{
//echo 'plik istnieje';
Items_Images::generate($id, $count);
}
$expires = 60 * 60 * 24 * 30; // 30 days
header('Content-type: image/gif');
header('Cache-Control: public');
header('Cache-Control: maxage=' . $expires);
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT');
$file_name = $id;
if($count > 1)
$file_name .= '-' . $count;
$file_name = Items_Images::$outputDir . $file_name . '.gif';
readfile($file_name);
}

View File

@ -1,4 +1,7 @@
<?php
use MyAAC\Models\Player;
/**
* CreateCharacter
*
@ -52,9 +55,7 @@ class CreateCharacter
return false;
}
$player = new OTS_Player();
$player->find($name);
if($player->isLoaded()) {
if(Player::where('name', '=', $name)->exists()) {
$errors['name'] = 'Character with this name already exist.';
return false;
}

View File

@ -1,4 +1,7 @@
<?php
use MyAAC\Models\Settings as ModelsSettings;
/**
* CreateCharacter
*
@ -40,13 +43,10 @@ class Settings implements ArrayAccess
}
}
global $db;
$settings = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'settings`');
if($settings->rowCount() > 0) {
foreach ($settings->fetchAll(PDO::FETCH_ASSOC) as $setting) {
$this->settingsDatabase[$setting['name']][$setting['key']] = $setting['value'];
}
$settings = ModelsSettings::all();
foreach ($settings as $setting)
{
$this->settingsDatabase[$setting->name][$setting->key] = $setting->value;
}
if ($cache->enabled()) {
@ -55,8 +55,6 @@ class Settings implements ArrayAccess
}
public function save($pluginName, $values) {
global $db;
if (!isset($this->settingsFile[$pluginName])) {
throw new RuntimeException('Error on save settings: plugin does not exist');
}
@ -69,7 +67,7 @@ class Settings implements ArrayAccess
}
$this->errors = [];
$db->query('DELETE FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($pluginName) . ';');
ModelsSettings::where('name', $pluginName)->delete();
foreach ($values as $key => $value) {
$errorMessage = '';
if (isset($settings['settings'][$key]['callbacks']['beforeSave']) && !$settings['settings'][$key]['callbacks']['beforeSave']($key, $value, $errorMessage)) {
@ -78,7 +76,11 @@ class Settings implements ArrayAccess
}
try {
$db->insert(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key, 'value' => $value]);
ModelsSettings::create([
'name' => $pluginName,
'key' => $key,
'value' => $value
]);
} catch (PDOException $error) {
$this->errors[] = 'Error while saving setting (' . $pluginName . ' - ' . $key . '): ' . $error->getMessage();
}
@ -94,36 +96,22 @@ class Settings implements ArrayAccess
public function updateInDatabase($pluginName, $key, $value)
{
global $db;
$db->update(TABLE_PREFIX . 'settings', ['value' => $value], ['name' => $pluginName, 'key' => $key]);
ModelsSettings::where(['name' => $pluginName, 'key' => $key])->update(['value' => $value]);
}
public function deleteFromDatabase($pluginName, $key = null)
{
global $db;
if (!isset($key)) {
$db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName], -1);
ModelsSettings::where('name', $pluginName)->delete();
}
else {
$db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key]);
ModelsSettings::where('name', $pluginName)->where('key', $key)->delete();
}
}
public static function display($plugin, $settings): array
{
global $db;
$query = 'SELECT `key`, `value` FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($plugin) . ';';
$query = $db->query($query);
$settingsDb = [];
if($query->rowCount() > 0) {
foreach($query->fetchAll(PDO::FETCH_ASSOC) as $value) {
$settingsDb[$value['key']] = $value['value'];
}
}
$settingsDb = ModelsSettings::where('name', $plugin)->pluck('value', 'key')->toArray();
$config = [];
require BASE . 'config.local.php';

View File

@ -23,6 +23,8 @@
* @link https://my-aac.org
*/
use MyAAC\Models\Town;
/**
* Class Towns
*/
@ -124,15 +126,6 @@ class Towns
*/
public static function getFromDatabase()
{
global $db;
$query = $db->query('SELECT `id`, `name` FROM `towns`;')->fetchAll(PDO::FETCH_ASSOC);
$towns = [];
foreach($query as $town) {
$towns[$town['id']] = $town['name'];
}
return $towns;
return Town::pluck('name', 'id')->toArray();
}
}

View File

@ -1,5 +1,7 @@
<?php
use MyAAC\Models\Changelog as ModelsChangelog;
class Changelog
{
static public function verify($body,$date, &$errors)
@ -19,43 +21,61 @@ class Changelog
static public function add($body, $type, $where, $player_id, $cdate, &$errors)
{
global $db;
if(!self::verify($body,$cdate, $errors))
return false;
$db->insert(TABLE_PREFIX . 'changelog', array('body' => $body, 'type' => $type, 'date' => $cdate, 'where' => $where, 'player_id' => isset($player_id) ? $player_id : 0));
self::clearCache();
return true;
$row = new ModelsChangelog;
$row->body = $body;
$row->type = $type;
$row->date = $cdate;
$row->where = $where;
$row->player_id = $player_id ?? 0;
if ($row->save()) {
self::clearCache();
return true;
}
return false;
}
static public function get($id) {
global $db;
return $db->select(TABLE_PREFIX . 'changelog', array('id' => $id));
return ModelsChangelog::find($id);
}
static public function update($id, $body, $type, $where, $player_id, $date, &$errors)
{
global $db;
if(!self::verify($body,$date, $errors))
return false;
$db->update(TABLE_PREFIX . 'changelog', array('body' => $body, 'type' => $type, 'where' => $where, 'player_id' => isset($player_id) ? $player_id : 0, 'date' => $date), array('id' => $id));
self::clearCache();
return true;
if (ModelsChangelog::where('id', '=', $id)->update([
'body' => $body,
'type' => $type,
'where' => $where,
'player_id' => $player_id ?? 0,
'date' => $date
])) {
self::clearCache();
return true;
}
return false;
}
static public function delete($id, &$errors)
{
global $db;
if(isset($id))
{
if($db->select(TABLE_PREFIX . 'changelog', array('id' => $id)) !== false)
$db->delete(TABLE_PREFIX . 'changelog', array('id' => $id));
else
$row = ModelsChangelog::find($id);
if ($row) {
if (!$row->delete()) {
$errors[] = 'Fail during delete Changelog.';
}
} else {
$errors[] = 'Changelog with id ' . $id . ' does not exist.';
}
else
}
} else {
$errors[] = 'Changelog id not set.';
}
if(count($errors)) {
return false;
@ -67,17 +87,18 @@ class Changelog
static public function toggleHidden($id, &$errors, &$status)
{
global $db;
if(isset($id))
{
$query = $db->select(TABLE_PREFIX . 'changelog', array('id' => $id));
if($query !== false)
{
$db->update(TABLE_PREFIX . 'changelog', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
$status = $query['hidden'];
}
else
$row = ModelsChangelog::find($id);
if ($row) {
$row->hidden = $row->hidden == 1 ? 0 : 1;
if (!$row->save()) {
$errors[] = 'Fail during toggle hidden Changelog.';
}
} else {
$errors[] = 'Changelog with id ' . $id . ' does not exists.';
}
}
else
$errors[] = 'Changelog id not set.';

View File

@ -8,6 +8,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Monster;
defined('MYAAC') or die('Direct access not allowed!');
require_once LIBS . 'items.php';
@ -19,9 +22,9 @@ class Creatures {
private static $lastError = '';
public static function loadFromXML($show = false) {
global $db;
try { $db->exec('DELETE FROM `' . TABLE_PREFIX . 'monsters`;'); } catch(PDOException $error) {}
try {
Monster::query()->delete();
} catch(Exception $error) {}
if($show) {
echo '<h2>Reload monsters.</h2>';
@ -93,9 +96,9 @@ class Creatures {
$flags['convinceable'] = '0';
if(!isset($flags['pushable']))
$flags['pushable'] = '0';
$flags['pushable'] = '0';
if(!isset($flags['canpushitems']))
$flags['canpushitems'] = '0';
$flags['canpushitems'] = '0';
if(!isset($flags['canpushcreatures']))
$flags['canpushcreatures'] = '0';
if(!isset($flags['runonhealth']))
@ -112,7 +115,7 @@ class Creatures {
$flags['attackable'] = '0';
if(!isset($flags['rewardboss']))
$flags['rewardboss'] = '0';
$summons = $monster->getSummons();
$loot = $monster->getLoot();
foreach($loot as &$item) {
@ -124,7 +127,7 @@ class Creatures {
}
if(!in_array($name, $names_added)) {
try {
$db->insert(TABLE_PREFIX . 'monsters', array(
Monster::create(array(
'name' => $name,
'mana' => empty($mana) ? 0 : $mana,
'exp' => $monster->getExperience(),
@ -132,7 +135,7 @@ class Creatures {
'speed_lvl' => $speed_lvl,
'use_haste' => $use_haste,
'voices' => json_encode($monster->getVoices()),
'immunities' => json_encode($monster->getImmunities()),
'immunities' => json_encode($monster->getImmunities()),
'elements' => json_encode($monster->getElements()),
'summonable' => $flags['summonable'] > 0 ? 1 : 0,
'convinceable' => $flags['convinceable'] > 0 ? 1 : 0,
@ -158,7 +161,7 @@ class Creatures {
success('Added: ' . $name . '<br/>');
}
}
catch(PDOException $error) {
catch(Exception $error) {
if($show) {
warning('Error while adding monster (' . $name . '): ' . $error->getMessage());
}

View File

@ -78,8 +78,6 @@ class Items
}
public static function getDescription($id, $count = 1) {
global $db;
$item = self::get($id);
$attr = $item['attributes'];
@ -112,17 +110,15 @@ class Items
$s .= 'an item of type ' . $item['id'];
if(isset($attr['type']) && strtolower($attr['type']) == 'rune') {
$query = $db->query('SELECT `level`, `maglevel`, `vocations` FROM `' . TABLE_PREFIX . 'spells` WHERE `item_id` = ' . $id);
if($query->rowCount() == 1) {
$query = $query->fetch();
if($query['level'] > 0 && $query['maglevel'] > 0) {
$item = Spells::where('item_id', $id)->first();
if($item) {
if($item->level > 0 && $item->maglevel > 0) {
$s .= '. ' . ($count > 1 ? "They" : "It") . ' can only be used by ';
}
$configVocations = config('vocations');
if(!empty(trim($query['vocations']))) {
$vocations = json_decode($query['vocations']);
if(!empty(trim($item->vocations))) {
$vocations = json_decode($item->vocations);
if(count($vocations) > 0) {
foreach($vocations as $voc => $show) {
$vocations[$configVocations[$voc]] = $show;

View File

@ -1,265 +0,0 @@
<?php
/**
* Items_Images class
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
if ( !function_exists( 'stackId' ) )
{
function stackId( $count )
{
if ( $count >= 50 )
$stack = 8;
elseif ( $count >= 25 )
$stack = 7;
elseif ( $count >= 10 )
$stack = 6;
elseif ( $count >= 5 )
$stack = 5;
elseif ( $count >= 4 )
$stack = 4;
elseif ( $count >= 3 )
$stack = 3;
elseif ( $count >= 2 )
$stack = 2;
else
$stack = 1;
return $stack;
}
}
class Items_Images
{
public static $outputDir = '';
public static $files = array();
private static $otb, $dat, $spr;
private static $lastItem;
private static $loaded = false;
public function __destruct()
{
if(self::$otb)
fclose(self::$otb);
if(self::$dat)
fclose(self::$dat);
if(self::$spr)
fclose(self::$spr);
}
public static function generate($id = 100, $count = 1)
{
if(!self::$loaded)
self::load();
$originalId = $id;
if($id < 100)
return false;
//die('ID cannot be lower than 100.');
rewind(self::$otb);
rewind(self::$dat);
rewind(self::$spr);
$nostand = false;
$init = false;
$originalId = $id;
// parse info from otb
while( false !== ( $char = fgetc( self::$otb ) ) )
{
$byte = HEX_PREFIX.bin2hex( $char );
if ( $byte == 0xFE )
$init = true;
elseif ( $byte == 0x10 and $init ) {
extract( unpack( 'x2/Ssid', fread( self::$otb, 4 ) ) );
if ( $id == $sid ) {
if ( HEX_PREFIX.bin2hex( fread( self::$otb, 1 ) ) == 0x11 ) {
extract( unpack( 'x2/Sid', fread( self::$otb, 4 ) ) );
break;
}
}
$init = false;
}
}
self::$lastItem = array_sum( unpack( 'x4/S*', fread( self::$dat, 12 )));
if($id > self::$lastItem)
return false;
//ini_set('max_execution_time', 300);
// parse info from dat
for( $i = 100; $i <= $id; $i++ ) {
while( ( $byte = HEX_PREFIX.bin2hex( fgetc( self::$dat ) ) ) != 0xFF ) {
$offset = 0;
switch( $byte ) {
case 0x00:
case 0x09:
case 0x0A:
case 0x1A:
case 0x1D:
case 0x1E:
$offset = 2;
break;
case 0x16:
case 0x19:
$offset = 4;
break;
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x17:
case 0x18:
case 0x1B:
case 0x1C:
case 0x1F:
case 0x20:
break;
default:
return false; #trigger_error( sprintf( 'Unknown .DAT byte %s (previous byte: %s; address %x)', $byte, $prev, ftell( $dat ), E_USER_ERROR ) );
break;
}
$prev = $byte;
fseek( self::$dat, $offset, SEEK_CUR );
}
extract( unpack( 'Cwidth/Cheight', fread( self::$dat, 2 ) ) );
if ( $width > 1 or $height > 1 ) {
fseek( self::$dat, 1, SEEK_CUR );
$nostand = true;
}
$sprites_c = array_product( unpack( 'C*', fread( self::$dat, 5 ) ) ) * $width * $height;
$sprites = unpack( 'S*', fread( self::$dat, 2 * $sprites_c ) );
}
if ( array_key_exists( stackId( $count ), $sprites ) ) {
$sprites = (array) $sprites[stackId( $count )];
}
else {
$sprites = (array) $sprites[array_rand( $sprites ) ];
}
fseek( self::$spr, 6 );
$sprite = imagecreatetruecolor( 32 * $width, 32 * $height );
imagecolortransparent( $sprite, imagecolorallocate( $sprite, 0, 0, 0 ) );
foreach( $sprites as $key => $value ) {
fseek( self::$spr, 6 + ( $value - 1 ) * 4 );
extract( unpack( 'Laddress', fread( self::$spr, 4 ) ) );
fseek( self::$spr, $address + 3 );
extract( unpack( 'Ssize', fread( self::$spr, 2 ) ) );
list( $num, $bit ) = array( 0, 0 );
while( $bit < $size ) {
$pixels = unpack( 'Strans/Scolored', fread( self::$spr, 4 ) );
$num += $pixels['trans'];
for( $i = 0; $i < $pixels['colored']; $i++ )
{
extract( unpack( 'Cred/Cgreen/Cblue', fread( self::$spr, 3 ) ) );
$red = ( $red == 0 ? ( $green == 0 ? ( $blue == 0 ? 1 : $red ) : $red ) : $red );
imagesetpixel( $sprite,
$num % 32 + ( $key % 2 == 1 ? 32 : 0 ),
$num / 32 + ( $key % 4 != 1 and $key % 4 != 0 ? 32 : 0 ),
imagecolorallocate( $sprite, $red, $green, $blue ) );
$num++;
}
$bit += 4 + 3 * $pixels['colored'];
}
}
if ( $count >= 2 ) {
if ( $count > 100 )
$count = 100;
$font = 3;
$length = imagefontwidth( $font ) * strlen( $count );
$pos = array(
'x' => ( 32 * $width ) - ( $length + 1 ),
'y' => ( 32 * $height ) - 13
);
imagestring( $sprite, $font, $pos['x'] - 1, $pos['y'] - 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
imagestring( $sprite, $font, $pos['x'], $pos['y'] - 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
imagestring( $sprite, $font, $pos['x'] - 1, $pos['y'], $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
imagestring( $sprite, $font, $pos['x'], $pos['y'] + 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
imagestring( $sprite, $font, $pos['x'] + 1, $pos['y'], $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
imagestring( $sprite, $font, $pos['x'] + 1, $pos['y'] + 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
imagestring( $sprite, $font, $pos['x'], $pos['y'], $count, imagecolorallocate( $sprite, 219, 219, 219 ) );
}
$imagePath = self::$outputDir . ($count > 1 ? $originalId . '-' . $count : $originalId ) . '.gif';
// save image
imagegif($sprite, $imagePath);
}
public static function load()
{
if(!defined( 'HEX_PREFIX'))
define('HEX_PREFIX', '0x');
self::$otb = fopen(self::$files['otb'], 'rb');
self::$dat = fopen(self::$files['dat'], 'rb');
self::$spr = fopen(self::$files['spr'], 'rb');
if(!self::$otb || !self::$dat || !self::$spr)
throw new RuntimeException('ERROR: Cannot load data files.');
/*
if ( $nostand )
{
for( $i = 0; $i < count( $sprites ) / 4; $i++ )
{
$sprites = array_merge( (array) $sprites, array_reverse( array_slice( $sprites, $i * 4, 4 ) ) );
}
}
else
{
$sprites = (array) $sprites[array_rand( $sprites ) ];
}
*/
self::$loaded = true;
}
public static function loaded() {
return self::$loaded;
}
}

View File

@ -1,5 +1,7 @@
<?php
use MyAAC\Models\News as ModelsNews;
class News
{
static public function verify($title, $body, $article_text, $article_image, &$errors)
@ -29,38 +31,57 @@ class News
static public function add($title, $body, $type, $category, $player_id, $comments, $article_text, $article_image, &$errors)
{
global $db;
if(!self::verify($title, $body, $article_text, $article_image, $errors))
return false;
$db->insert(TABLE_PREFIX . 'news', array('title' => $title, 'body' => $body, 'type' => $type, 'date' => time(), 'category' => $category, 'player_id' => isset($player_id) ? $player_id : 0, 'comments' => $comments, 'article_text' => ($type == 3 ? $article_text : ''), 'article_image' => ($type == 3 ? $article_image : '')));
ModelsNews::create([
'title' => $title,
'body' => $body,
'type' => $type,
'date' => time(),
'category' => $category,
'player_id' => isset($player_id) ? $player_id : 0,
'comments' => $comments,
'article_text' => ($type == 3 ? $article_text : ''),
'article_image' => ($type == 3 ? $article_image : '')
]);
self::clearCache();
return true;
}
static public function get($id) {
global $db;
return $db->select(TABLE_PREFIX . 'news', array('id' => $id));
return ModelsNews::find($id)->toArray();
}
static public function update($id, $title, $body, $type, $category, $player_id, $comments, $article_text, $article_image, &$errors)
{
global $db;
if(!self::verify($title, $body, $article_text, $article_image, $errors))
return false;
$db->update(TABLE_PREFIX . 'news', array('title' => $title, 'body' => $body, 'type' => $type, 'category' => $category, 'last_modified_by' => isset($player_id) ? $player_id : 0, 'last_modified_date' => time(), 'comments' => $comments, 'article_text' => $article_text, 'article_image' => $article_image), array('id' => $id));
ModelsNews::where('id', $id)->update([
'title' => $title,
'body' => $body,
'type' => $type,
'category' => $category,
'last_modified_by' => isset($player_id) ? $player_id : 0,
'last_modified_date' => time(),
'comments' => $comments,
'article_text' => $article_text,
'article_image' => $article_image
]);
self::clearCache();
return true;
}
static public function delete($id, &$errors)
{
global $db;
if(isset($id))
{
if($db->select(TABLE_PREFIX . 'news', array('id' => $id)) !== false)
$db->delete(TABLE_PREFIX . 'news', array('id' => $id));
$row = ModelsNews::find($id);
if($row)
if (!$row->delete()) {
$errors[] = 'Fail during delete News.';
}
else
$errors[] = 'News with id ' . $id . ' does not exists.';
}
@ -77,14 +98,16 @@ class News
static public function toggleHidden($id, &$errors, &$status)
{
global $db;
if(isset($id))
{
$query = $db->select(TABLE_PREFIX . 'news', array('id' => $id));
if($query !== false)
$row = ModelsNews::find($id);
if($row)
{
$db->update(TABLE_PREFIX . 'news', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
$status = $query['hidden'];
$row->hidden = $row->hidden == 1 ? 0 : 1;
if (!$row->save()) {
$errors[] = 'Fail during toggle hidden News.';
}
$status = $row->hidden;
}
else
$errors[] = 'News with id ' . $id . ' does not exists.';

View File

@ -39,6 +39,7 @@ function is_sub_dir($path = NULL, $parent_folder = BASE) {
}
use Composer\Semver\Semver;
use MyAAC\Models\Menu;
class Plugins {
private static $warnings = [];
@ -649,11 +650,9 @@ class Plugins {
*/
public static function installMenus($templateName, $categories)
{
global $db;
// check if menus already exist
$query = $db->query('SELECT `id` FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($templateName) . ' LIMIT 1;');
if ($query->rowCount() > 0) {
$menuInstalled = Menu::where('template', $templateName)->select('id')->first();
if ($menuInstalled) {
return;
}
@ -687,7 +686,7 @@ class Plugins {
'color' => $color,
];
$db->insert(TABLE_PREFIX . 'menu', $insert_array);
Menu::create($insert_array);
}
}
}

View File

@ -276,7 +276,7 @@ class OTS_Monster extends DOMDocument
/**
* Returns look of the monster.
*
*
* @return array Look with all the attributes of the look.
* @throws DOMException On DOM operation error.
*/
@ -286,6 +286,10 @@ class OTS_Monster extends DOMDocument
$element = $this->documentElement->getElementsByTagName('look')->item(0);
if (!$element) {
return $look;
}
$look['type'] = $element->getAttribute('type');
$look['typeex'] = $element->getAttribute('typeex');
$look['head'] = $element->getAttribute('head');

View File

@ -8,6 +8,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Spell;
defined('MYAAC') or die('Direct access not allowed!');
class Spells {
@ -31,9 +34,11 @@ class Spells {
}
public static function loadFromXML($show = false) {
global $config, $db;
global $config;
try { $db->exec('DELETE FROM `' . TABLE_PREFIX . 'spells`;'); } catch(PDOException $error) {}
try {
Spell::query()->delete();
} catch(Exception $error) {}
if($show) {
echo '<h2>Reload spells.</h2>';
@ -63,7 +68,7 @@ class Spells {
continue;
try {
$db->insert(TABLE_PREFIX . 'spells', array(
Spell::create(array(
'name' => $name,
'words' => $words,
'type' => 2,
@ -105,7 +110,7 @@ class Spells {
continue;
try {
$db->insert(TABLE_PREFIX . 'spells', array(
Spell::create(array(
'name' => $name,
'words' => $words,
'type' => 1,
@ -142,7 +147,7 @@ class Spells {
$name = $spell->getName() . ' Rune';
try {
$db->insert(TABLE_PREFIX . 'spells', array(
Spell::create(array(
'name' => $name,
'words' => $spell->getWords(),
'type' => 3,
@ -178,4 +183,4 @@ class Spells {
public static function getLastError() {
return self::$lastError;
}
}
}

View File

@ -7,6 +7,10 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Monster;
use MyAAC\Models\Spell;
defined('MYAAC') or die('Direct access not allowed!');
class Validator
@ -307,8 +311,7 @@ class Validator
$monstersCheck = setting('core.create_character_name_monsters_check');
if ($monstersCheck) {
$monsters = $db->query('SELECT `name` FROM `' . TABLE_PREFIX . 'monsters` WHERE `name` LIKE ' . $db->quote($name_lower));
if ($monsters->rowCount() > 0) {
if (Monster::where('name', 'like', $name_lower)->exists()) {
self::$lastError = 'Your name cannot contains monster name.';
return false;
}
@ -316,14 +319,12 @@ class Validator
$spellsCheck = setting('core.create_character_name_spells_check');
if ($spellsCheck) {
$spells_name = $db->query('SELECT `name` FROM `' . TABLE_PREFIX . 'spells` WHERE `name` LIKE ' . $db->quote($name_lower));
if ($spells_name->rowCount() > 0) {
if (Spell::where('name', 'like', $name_lower)->exists()) {
self::$lastError = 'Your name cannot contains spell name.';
return false;
}
$spells_words = $db->query('SELECT `words` FROM `' . TABLE_PREFIX . 'spells` WHERE `words` = ' . $db->quote($name_lower));
if ($spells_words->rowCount() > 0) {
if (Spell::where('words', $name_lower)->exists()) {
self::$lastError = 'Your name cannot contains spell name.';
return false;
}

View File

@ -7,6 +7,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Visitor;
defined('MYAAC') or die('Direct access not allowed!');
class Visitors
@ -54,9 +57,7 @@ class Visitors
return isset($this->data[$ip]);
}
global $db;
$users = $db->query('SELECT COUNT(`ip`) as count FROM `' . TABLE_PREFIX . 'visitors' . '` WHERE ' . $db->fieldName('ip') . ' = ' . $db->quote($ip))->fetch();
return ($users['count'] > 0);
return Visitor::where('ip', $ip)->exists();
}
private function cleanVisitors()
@ -73,8 +74,7 @@ class Visitors
return;
}
global $db;
$db->exec('DELETE FROM ' . $db->tableName(TABLE_PREFIX . 'visitors') . ' WHERE ' . $db->fieldName('lastvisit') . ' < ' . (time() - $this->sessionTime * 60));
Visitor::where('lastvisit', '<', (time() - $this->sessionTime * 60))->delete();
}
private function updateVisitor($ip, $page, $userAgent)
@ -84,8 +84,7 @@ class Visitors
return;
}
global $db;
$db->update(TABLE_PREFIX . 'visitors', ['lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent], ['ip' => $ip]);
Visitor::where('ip', $ip)->update(['lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent]);
}
private function addVisitor($ip, $page, $userAgent)
@ -95,8 +94,7 @@ class Visitors
return;
}
global $db;
$db->insert(TABLE_PREFIX . 'visitors', ['ip' => $ip, 'lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent]);
Visitor::create(['ip' => $ip, 'lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent]);
}
public function getVisitors()
@ -108,8 +106,7 @@ class Visitors
return $this->data;
}
global $db;
return $db->query('SELECT ' . $db->fieldName('ip') . ', ' . $db->fieldName('lastvisit') . ', ' . $db->fieldName('page') . ', ' . $db->fieldName('user_agent') . ' FROM ' . $db->tableName(TABLE_PREFIX . 'visitors') . ' ORDER BY ' . $db->fieldName('lastvisit') . ' DESC')->fetchAll();
return Visitor::orderByDesc('lastvisit')->get()->toArray();
}
public function getAmountVisitors()
@ -118,9 +115,7 @@ class Visitors
return count($this->data);
}
global $db;
$users = $db->query('SELECT COUNT(`ip`) as count FROM `' . TABLE_PREFIX . 'visitors`')->fetch();
return $users['count'];
return Visitor::count();
}
public function show() {

View File

@ -8,6 +8,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Weapon;
defined('MYAAC') or die('Direct access not allowed!');
class Weapons {
@ -15,10 +18,10 @@ class Weapons {
public static function loadFromXML($show = false)
{
global $config, $db;
global $config;
try {
$db->exec("DELETE FROM `myaac_weapons`;");
Weapon::query()->delete();
} catch (PDOException $error) {
}
@ -45,7 +48,7 @@ class Weapons {
}
public static function parseNode($node, $show = false) {
global $config, $db;
global $config;
$id = (int)$node->getAttribute('id');
$vocations_ids = array_flip($config['vocations']);
@ -64,18 +67,19 @@ class Weapons {
$vocations[$voc_id] = strlen($show) == 0 || $show != '0';
}
$exist = $db->query('SELECT `id` FROM `' . TABLE_PREFIX . 'weapons` WHERE `id` = ' . $id);
if($exist->rowCount() > 0) {
if(Weapon::find($id)) {
if($show) {
warning('Duplicated weapon with id: ' . $id);
}
}
else {
$db->insert(TABLE_PREFIX . 'weapons', array('id' => $id, 'level' => $level, 'maglevel' => $maglevel, 'vocations' => json_encode($vocations)));
Weapon::create([
'id' => $id, 'level' => $level, 'maglevel' => $maglevel, 'vocations' => json_encode($vocations)
]);
}
}
public static function getError() {
return self::$error;
}
}
}

View File

@ -13,4 +13,4 @@
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
");
?>
?>

View File

@ -15,74 +15,7 @@ CREATE TABLE `myaac_menu`
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
");
$db->query("
/* MENU_CATEGORY_NEWS kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Latest News', 'news', 1, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'News Archive', 'news/archive', 1, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Changelog', 'changelog', 1, 2);
/* MENU_CATEGORY_ACCOUNT kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Account Management', 'account/manage', 2, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Create Account', 'account/create', 2, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Lost Account?', 'account/lost', 2, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Rules', 'rules', 2, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Downloads', 'downloads', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Report Bug', 'bugtracker', 2, 5);
/* MENU_CATEGORY_COMMUNITY kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Who is Online?', 'online', 3, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Characters', 'characters', 3, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Guilds', 'guilds', 3, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Highscores', 'highscores', 3, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Last Deaths', 'lastkills', 3, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Houses', 'houses', 3, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Bans', 'bans', 3, 6);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Forum', 'forum', 3, 7);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Team', 'team', 3, 8);
/* MENU_CATEGORY_LIBRARY kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Monsters', 'creatures', 5, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Spells', 'spells', 5, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Info', 'serverInfo', 5, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Commands', 'commands', 5, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Gallery', 'gallery', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Experience Table', 'experienceTable', 5, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'FAQ', 'faq', 5, 6);
/* MENU_CATEGORY_SHOP kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop Offer', 'gifts', 6, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop History', 'gifts/history', 6, 2);
/* MENU_CATEGORY_NEWS tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Latest News', 'news', 1, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'News Archive', 'news/archive', 1, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Changelog', 'changelog', 1, 2);
/* MENU_CATEGORY_ACCOUNT tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Account Management', 'account/manage', 2, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Create Account', 'account/create', 2, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Lost Account?', 'account/lost', 2, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Rules', 'rules', 2, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Downloads', 'downloads', 2, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Report Bug', 'bugtracker', 2, 5);
/* MENU_CATEGORY_COMMUNITY tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Characters', 'characters', 3, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Who Is Online?', 'online', 3, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Highscores', 'highscores', 3, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Last Kills', 'lastkills', 3, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Houses', 'houses', 3, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Guilds', 'guilds', 3, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Polls', 'polls', 3, 6);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Bans', 'bans', 3, 7);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Support List', 'team', 3, 8);
/* MENU_CATEGORY_FORUM tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Forum', 'forum', 4, 0);
/* MENU_CATEGORY_LIBRARY tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Creatures', 'creatures', 5, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Spells', 'spells', 5, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Commands', 'commands', 5, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Exp Stages', 'experienceStages', 5, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Gallery', 'gallery', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Info', 'serverInfo', 5, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Experience Table', 'experienceTable', 5, 6);
/* MENU_CATEGORY_SHOP tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop Offer', 'gifts', 6, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop History', 'gifts/history', 6, 2);
");
require_once LIBS . 'plugins.php';
Plugins::installMenus('kathrine', require TEMPLATES . 'kathrine/menus.php');
Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php');
}

View File

@ -8,6 +8,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Change Comment';
@ -17,36 +20,36 @@ if(!$logged) {
return;
}
$player = null;
$player_name = isset($_REQUEST['name']) ? stripslashes(urldecode($_REQUEST['name'])) : null;
$new_comment = isset($_POST['comment']) ? htmlspecialchars(stripslashes(substr($_POST['comment'],0,2000))) : NULL;
$new_hideacc = isset($_POST['accountvisible']) ? (int)$_POST['accountvisible'] : NULL;
if($player_name != null) {
if (Validator::characterName($player_name)) {
$player = new OTS_Player();
$player->find($player_name);
if ($player->isLoaded()) {
$player_account = $player->getAccount();
if ($account_logged->getId() == $player_account->getId()) {
if ($player->isDeleted()) {
$errors[] = 'This character is deleted.';
$player = null;
}
$player = Player::query()
->where('name', $player_name)
->where('account_id', $account_logged->getId())
->first();
if (isset($_POST['changecommentsave']) && $_POST['changecommentsave'] == 1) {
if(empty($errors)) {
$player->setCustomField("hidden", $new_hideacc);
$player->setCustomField("comment", $new_comment);
$account_logged->logAction('Changed comment for character <b>' . $player->getName() . '</b>.');
$twig->display('success.html.twig', array(
'title' => 'Character Information Changed',
'description' => 'The character information has been changed.'
));
$show_form = false;
}
if ($player) {
if ($player->is_deleted) {
$errors[] = 'This character is deleted.';
$player = null;
}
if (isset($_POST['changecommentsave']) && $_POST['changecommentsave'] == 1) {
if(empty($errors)) {
$player->hidden = $new_hideacc;
$player->comment = $new_comment;
$player->save();
$account_logged->logAction('Changed comment for character <b>' . $player->name . '</b>.');
$twig->display('success.html.twig', array(
'title' => 'Character Information Changed',
'description' => 'The character information has been changed.'
));
$show_form = false;
}
} else {
$errors[] = 'Error. Character <b>' . $player_name . '</b> is not on your account.';
}
} else {
$errors[] = "Error. Character with this name doesn't exist.";
@ -64,9 +67,9 @@ if($show_form) {
$twig->display('error_box.html.twig', array('errors' => $errors));
}
if(isset($player) && $player->isLoaded()) {
if(isset($player) && $player) {
$twig->display('account.change_comment.html.twig', array(
'player' => $player
'player' => $player->toArray()
));
}
}

View File

@ -8,6 +8,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Change Info';
@ -20,6 +23,8 @@ if(!$logged) {
if($config['account_country'])
require SYSTEM . 'countries.conf.php';
$account = Account::find($account_logged->getId());
$show_form = true;
$new_rlname = isset($_POST['info_rlname']) ? htmlspecialchars(stripslashes($_POST['info_rlname'])) : NULL;
$new_location = isset($_POST['info_location']) ? htmlspecialchars(stripslashes($_POST['info_location'])) : NULL;
@ -30,9 +35,10 @@ if(isset($_POST['changeinfosave']) && $_POST['changeinfosave'] == 1) {
if(empty($errors)) {
//save data from form
$account_logged->setCustomField("rlname", $new_rlname);
$account_logged->setCustomField("location", $new_location);
$account_logged->setCustomField("country", $new_country);
$account->rlname = $new_rlname;
$account->location = $new_location;
$account->country = $new_country;
$account->save();
$account_logged->logAction('Changed Real Name to <b>' . $new_rlname . '</b>, Location to <b>' . $new_location . '</b> and Country to <b>' . $config['countries'][$new_country] . '</b>.');
$twig->display('success.html.twig', array(
'title' => 'Public Information Changed',
@ -47,10 +53,10 @@ if(isset($_POST['changeinfosave']) && $_POST['changeinfosave'] == 1) {
//show form
if($show_form) {
$account_rlname = $account_logged->getCustomField("rlname");
$account_location = $account_logged->getCustomField("location");
$account_rlname = $account->rlname;
$account_location = $account->location;
if ($config['account_country']) {
$account_country = $account_logged->getCustomField("country");
$account_country = $account->country;
$countries = array();
foreach (array('pl', 'se', 'br', 'us', 'gb',) as $country)

View File

@ -7,6 +7,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Confirm Email';
@ -17,14 +20,12 @@ if(empty($hash)) {
return;
}
$res = $db->query('SELECT `email_hash` FROM `accounts` WHERE `email_hash` = ' . $db->quote($hash));
if(!$res->rowCount()) {
if(!Account::where('email_hash', $hash)->exists()) {
note("Your email couldn't be verified. Please contact staff to do it manually.");
}
else
{
$query = $db->query('SELECT id FROM accounts WHERE email_hash = ' . $db->quote($hash) . ' AND email_verified = 0');
if ($query->rowCount() == 1) {
if (Account::where('email_hash', $hash)->where('email_verified', 0)->exists()) {
$query = $query->fetch(PDO::FETCH_ASSOC);
$account = new OTS_Account();
$account->load($query['id']);
@ -33,7 +34,7 @@ else
}
}
$db->update('accounts', array('email_verified' => '1'), array('email_hash' => $hash));
Account::where('email_hash', $hash)->update('email_verified', 1);
success('You have now verified your e-mail, this will increase the security of your account. Thank you for doing this.');
}
?>

View File

@ -11,8 +11,8 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Bans list';
$configBansPerPage = config('bans_per_page');
$_page = isset($_GET['page']) ? $_GET['page'] : 1;
$configBansPerPage = setting('core.bans_per_page');
$_page = $_GET['page'] ?? 1;
if(!is_numeric($_page) || $_page < 1 || $_page > PHP_INT_MAX) {
$_page = 1;
@ -50,7 +50,8 @@ if(!$bansQuery->rowCount())
$nextPage = false;
$i = 0;
$bans = $bansQuery->fetchAll();
$bans = $bansQuery->fetchAll(PDO::FETCH_ASSOC);
foreach ($bans as $id => &$ban)
{
if(++$i > $configBansPerPage)
@ -69,11 +70,22 @@ foreach ($bans as $id => &$ban)
$accountId = $ban['account_id'];
}
$ban['player'] = getPlayerLink(getPlayerNameByAccount($accountId));
$playerName = 'Unknown';
if ($configBans['hasType']) {
$ban['type'] = getBanType($ban['type']);
if ($ban['type'] == 2) { // namelock
$playerName = getPlayerNameById($accountId);
}
else {
$playerName = getPlayerNameByAccount($accountId);
}
}
else {
$playerName = getPlayerNameByAccount($accountId);
}
$ban['player'] = getPlayerLink($playerName);
$expiresColumn = 'expires_at';
if ($db->hasColumn('bans', 'expires')) {
@ -104,7 +116,7 @@ foreach ($bans as $id => &$ban)
}
}
else {
$addedBy = getPlayerLink(getPlayerNameByAccount($ban['banned_by']));
$addedBy = getPlayerLink(getPlayerNameById($ban['banned_by']));
}
if ($db->hasColumn('bans', 'added')) {

View File

@ -8,6 +8,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\BugTracker;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Bug tracker';
@ -29,10 +32,10 @@ $showed = $post = $reply = false;
if(admin() and isset($_REQUEST['control']) && $_REQUEST['control'] == "true")
{
if(empty($_REQUEST['id']) and empty($_REQUEST['acc']) or !is_numeric($_REQUEST['acc']) or !is_numeric($_REQUEST['id']) )
$bug[1] = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `type` = 1 order by `uid` desc');
$bug[1] = BugTracker::where('type', 1)->orderByDesc('uid')->get()->toArray();
if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id']) and !empty($_REQUEST['acc']) and is_numeric($_REQUEST['acc']))
$bug[2] = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].' and `type` = 1')->fetch();
$bug[2] = BugTracker::where('type', 1)->where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->get()->toArray();
if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id']) and !empty($_REQUEST['acc']) and is_numeric($_REQUEST['acc']))
{
@ -67,7 +70,7 @@ $showed = $post = $reply = false;
echo '<TR BGCOLOR="'.$light.'"><td colspan=2>'.nl2br($bug[2]['text']).'</td></tr>';
echo '</TABLE>';
$answers = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].' and `type` = 2 order by `reply`');
$answers = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->orderBy('reply')->get()->toArray();
foreach($answers as $answer)
{
if($answer['who'] == 1)
@ -88,9 +91,9 @@ $showed = $post = $reply = false;
{
if($bug[2]['status'] != 3)
{
$reply = $db->query('SELECT MAX(reply) FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].' and `type` = 2')->fetch();
$reply = $reply[0] + 1;
$iswho = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].' and `type` = 2 order by `reply` desc limit 1')->fetch();
$reply = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->max('reply');
$reply = $reply + 1;
$iswho = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->orderByDesc('reply')->first()->toArray();
if(isset($_POST['finish']))
{
@ -109,8 +112,17 @@ $showed = $post = $reply = false;
else
{
$type = 2;
$INSERT = $db->query('INSERT INTO `' . TABLE_PREFIX . 'bugtracker` (`account`,`id`,`text`,`reply`,`type`, `who`) VALUES ('.$db->quote($_REQUEST['acc']).','.$db->quote($_REQUEST['id']).','.$db->quote($_POST['text']).','.$db->quote($reply).','.$db->quote($type).','.$db->quote(1).')');
$UPDATE = $db->query('UPDATE `' . TABLE_PREFIX . 'bugtracker` SET `status` = '.$_POST['status'].' where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].'');
$INSERT = BugTracker::create([
'account' => $_REQUEST['aac'],
'id' => $_REQUEST['id'],
'text' => $_POST['text'],
'reply' => $reply,
'type' => $type,
'who' => 1,
]);
$UPDATE = Bugtracker::where('id', $_REQUEST['id'])->where('account', $_REQUEST['acc'])->update([
'status' => $_POST['status']
]);
header('Location: ?subtopic=bugtracker&control=true&id='.$_REQUEST['id'].'&acc='.$_REQUEST['acc'].'');
}
}
@ -159,10 +171,10 @@ $showed = $post = $reply = false;
$id = addslashes(htmlspecialchars(trim($_REQUEST['id'])));
if(empty($_REQUEST['id']))
$bug[1] = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `account` = '.$account_logged->getId().' and `type` = 1 order by `id` desc');
$bug[1] = BugTracker::where('account', $account_logged->getId())->where('type', 1)->orderBy('id')->get()->toArray();
if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id']))
$bug[2] = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `account` = '.$account_logged->getId().' and `id` = '.$id.' and `type` = 1')->fetch();
$bug[2] = BugTracker::where('account', $account_logged->getId())->where('type', 1)->where('id', $id)->get()->toArray();
else
$bug[2] = NULL;
@ -186,7 +198,7 @@ $showed = $post = $reply = false;
echo '<TR BGCOLOR="'.$dark.'"><td colspan=2>'.nl2br($bug[2]['text']).'</td></tr>';
echo '</TABLE>';
$answers = $db->query('SELECT * FROM '.$db->tableName('myaac_bugtracker').' where `account` = '.$account_logged->getId().' and `id` = '.$id.' and `type` = 2 order by `reply`');
$answers = Bugtracker::where('account', $account_logged->getId())->where('id', $id)->where('type', 2)->orderBy('reply')->get()->toArray();
foreach($answers as $answer)
{
if($answer['who'] == 1)
@ -207,9 +219,9 @@ $showed = $post = $reply = false;
{
if($bug[2]['status'] != 3)
{
$reply = $db->query('SELECT MAX(reply) FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$acc.' and `id` = '.$id.' and `type` = 2')->fetch();
$reply = $reply[0] + 1;
$iswho = $db->query('SELECT * FROM `myaac_bugtracker` where `account` = '.$acc.' and `id` = '.$id.' and `type` = 2 order by `reply` desc limit 1')->fetch();
$reply = BugTracker::where('account', $aac)->where('id', $id)->where('type', 2)->max('reply');
$reply = $reply + 1;
$iswho = BugTracker::where('account', $acc)->where('id', $id)->where('type', 2)->orderByDesc('reply')->first()->toArray();
if(isset($_POST['finish']))
{
@ -228,8 +240,16 @@ $showed = $post = $reply = false;
else
{
$type = 2;
$INSERT = $db->query('INSERT INTO `myaac_bugtracker` (`account`,`id`,`text`,`reply`,`type`) VALUES ('.$db->quote($acc).','.$db->quote($id).','.$db->quote($_POST['text']).','.$db->quote($reply).','.$db->quote($type).')');
$UPDATE = $db->query('UPDATE `myaac_bugtracker` SET `status` = 1 where `account` = '.$acc.' and `id` = '.$id.'');
$INSERT = BugTracker::create([
'account' => $acc,
'id' => $id,
'text' => $_POST['text'],
'reply' => $reply,
'type' => $type
]);
$UPDATE = BugTracker::where('id', $id)->where('account', $acc)->update([
'status' => 1
]);
header('Location: ?subtopic=bugtracker&id='.$id.'');
}
}
@ -289,9 +309,9 @@ $showed = $post = $reply = false;
}
elseif(isset($_REQUEST['add']) && $_REQUEST['add'] == TRUE)
{
$thread = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$acc.' and `type` = 1 order by `id` desc')->fetch();
$id_next = $db->query('SELECT MAX(id) FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$acc.' and `type` = 1')->fetch();
$id_next = $id_next[0] + 1;
$thread = BugTracker::where('account', $acc)->where('type', 1)->orderByDesc('id')->get()->toArray();
$id_next = BugTracker::where('account', $acc)->where('type', 1)->max('id');
$id_next = $id_next + 1;
if(empty($thread))
$thread['status'] = 3;
@ -318,7 +338,16 @@ $showed = $post = $reply = false;
{
$type = 1;
$status = 1;
$INSERT = $db->query('INSERT INTO `' . TABLE_PREFIX . 'bugtracker` (`account`,`id`,`text`,`type`,`subject`, `reply`,`status`,`tag`) VALUES ('.$db->quote($acc).','.$db->quote($id_next).','.$db->quote($_POST['text']).','.$db->quote($type).','.$db->quote($_POST['subject']).', 0,'.$db->quote($status).','.$db->quote($_POST['tags']).')');
$INSERT = BugTracker::create([
'account' => $acc,
'id' => $id_next,
'text' => $_POST['text'],
'type' => $type,
'subject' => $_POST['subject'],
'reply' => 0,
'status' => $status,
'tag' => $_POST['tags']
]);
header('Location: ?subtopic=bugtracker&id='.$id_next.'');
}

View File

@ -10,6 +10,8 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Changelog';
use MyAAC\Models\Changelog;
$_page = isset($_GET['page']) ? (int)$_GET['page'] : 0;
$limit = 30;
$offset = $_page * $limit;
@ -17,7 +19,7 @@ $next_page = false;
$canEdit = hasFlag(FLAG_CONTENT_NEWS) || superAdmin();
$changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog` ' . ($canEdit ? '' : 'WHERE `hidden` = 0').' ORDER BY `id` DESC LIMIT ' . ($limit + 1) . ' OFFSET ' . $offset)->fetchAll();
$changelogs = Changelog::isPublic()->orderByDesc('id')->limit($limit + 1)->offset($offset)->get()->toArray();
$i = 0;
foreach($changelogs as $key => &$log)

View File

@ -11,8 +11,6 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Characters';
require_once SYSTEM . 'item.php';
$groups = new OTS_Groups_List();
function generate_search_form($autofocus = false)
{

View File

@ -9,13 +9,18 @@
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Monster;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Creatures';
if (empty($_REQUEST['name'])) {
// display list of monsters
$preview = config('monsters_images_preview');
$creatures = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'monsters` WHERE `hidden` != 1 '.(empty($_REQUEST['boss']) ? '': 'AND `rewardboss` = 1').' ORDER BY name asc')->fetchAll();
$creatures = Monster::where('hidden', '!=', 1)->when(!empty($_REQUEST['boss']), function ($query) {
$query->where('rewardboss', 1);
})->get()->toArray();
if ($preview) {
foreach($creatures as $key => &$creature)
@ -34,9 +39,7 @@ if (empty($_REQUEST['name'])) {
// display monster
$creature_name = urldecode(stripslashes(ucwords(strtolower($_REQUEST['name']))));
$prep = $db->prepare('SELECT * FROM `' . TABLE_PREFIX . 'monsters` WHERE `hidden` != 1 AND `name` = ? LIMIT 1;');
$prep->execute([$creature_name]);
$creature = $prep->fetch();
$creature = Monster::where('hidden', '!=', 1)->where('name', $creature_name)->first()->toArray();
if (isset($creature['name'])) {
function sort_by_chance($a, $b)

View File

@ -7,6 +7,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\FAQ as ModelsFAQ;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Frequently Asked Questions';
@ -68,21 +71,23 @@ if($canEdit)
));
}
$faqs =
$db->query('SELECT `id`, `question`, `answer`' .
($canEdit ? ', `hidden`, `ordering`' : '') .
' FROM `' . TABLE_PREFIX . 'faq`' .
(!$canEdit ? ' WHERE `hidden` != 1' : '') .
' ORDER BY `ordering`;');
$faqs = ModelsFAQ::select('id', 'question', 'answer')->when(!$canEdit, function ($query) {
$query->where('hidden', '!=', 1);
})->orderBy('ordering');
if(!$faqs->rowCount())
if ($canEdit) {
$faqs->addSelect(['hidden', 'ordering']);
}
$faqs = $faqs->get()->toArray();
if(!count($faqs))
{
?>
There are no questions added yet.
<?php
}
$last = $faqs->rowCount();
$last = count($faqs);
$twig->display('faq.html.twig', array(
'faqs' => $faqs,
'last' => $last,
@ -93,26 +98,17 @@ class FAQ
{
static public function add($question, $answer, &$errors)
{
global $db;
if(isset($question[0]) && isset($answer[0]))
{
$query = $db->select(TABLE_PREFIX . 'faq', array('question' => $question));
if($query === false)
$row = ModelsFAQ::where('question', $question)->first();
if(!$row)
{
$query =
$db->query(
'SELECT ' . $db->fieldName('ordering') .
' FROM ' . $db->tableName(TABLE_PREFIX . 'faq') .
' ORDER BY ' . $db->fieldName('ordering') . ' DESC LIMIT 1'
);
$ordering = 0;
if($query->rowCount() > 0) {
$query = $query->fetch();
$ordering = $query['ordering'] + 1;
}
$db->insert(TABLE_PREFIX . 'faq', array('question' => $question, 'answer' => $answer, 'ordering' => $ordering));
$ordering = ModelsFAQ::max('ordering') ?? 0;
ModelsFAQ::create([
'question' => $question,
'answer' => $answer,
'ordering' => $ordering
]);
}
else
$errors[] = 'FAQ with this question already exists.';
@ -124,22 +120,23 @@ class FAQ
}
static public function get($id) {
global $db;
return $db->select(TABLE_PREFIX . 'faq', array('id' => $id));
return ModelsFAQ::find($id)->toArray();
}
static public function update($id, $question, $answer) {
global $db;
$db->update(TABLE_PREFIX . 'faq', array('question' => $question, 'answer' => $answer), array('id' => $id));
ModelsFAQ::where('id', $id)->update([
'question' => $question,
'answer' => $answer
]);
}
static public function delete($id, &$errors)
{
global $db;
if(isset($id))
{
if(self::get($id) !== false)
$db->delete(TABLE_PREFIX . 'faq', array('id' => $id));
$row = ModelsFAQ::find($id);
if($row)
$row->delete();
else
$errors[] = 'FAQ with id ' . $id . ' does not exists.';
}
@ -151,14 +148,15 @@ class FAQ
static public function toggleHidden($id, &$errors)
{
global $db;
if(isset($id))
{
$query = self::get($id);
if($query !== false)
$db->update(TABLE_PREFIX . 'faq', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
else
$row = ModelsFAQ::find($id);
if ($row) {
$row->hidden = ($row->hidden == 1 ? 0 : 1);
$row->save();
} else {
$errors[] = 'FAQ with id ' . $id . ' does not exists.';
}
}
else
$errors[] = 'id not set';
@ -169,15 +167,18 @@ class FAQ
static public function move($id, $i, &$errors)
{
global $db;
$query = self::get($id);
if($query !== false)
$row = ModelsFAQ::find($id);
if($row)
{
$ordering = $query['ordering'] + $i;
$old_record = $db->select(TABLE_PREFIX . 'faq', array('ordering' => $ordering));
if($old_record !== false)
$db->update(TABLE_PREFIX . 'faq', array('ordering' => $query['ordering']), array('ordering' => $ordering));
$ordering = $row->ordering + $i;
$old_record = ModelsFAQ::where('ordering', $ordering)->first();
if($old_record) {
$old_record->ordering = $row->ordering;
$old_record->save();
}
$db->update(TABLE_PREFIX . 'faq', array('ordering' => $ordering), array('id' => $id));
$row->ordering = $ordering;
$row->save();
}
else
$errors[] = 'FAQ with id ' . $id . ' does not exists.';

View File

@ -7,6 +7,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Gallery as ModelsGallery;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Gallery';
@ -164,22 +167,19 @@ class Gallery
}
static public function get($id) {
global $db;
return $db->select(TABLE_PREFIX . 'gallery', array('id' => $id));
return ModelsGallery::find($id)->toArray();
}
static public function update($id, $comment, $image, $author) {
global $db;
$pathinfo = pathinfo($image);
$extension = strtolower($pathinfo['extension']);
$filename = GALLERY_DIR . $pathinfo['filename'] . '.' . $extension;
if($db->update(TABLE_PREFIX . 'gallery', array(
if(ModelsGallery::where('id', $id)->update([
'comment' => $comment,
'image' => $filename, 'author' => $author),
array('id' => $id)
)) {
'image' => $filename,
'author' => $author
])) {
if(self::generateThumb($id, $image, $errors))
self::resize($image, 650, 500, $filename, $errors);
}
@ -187,11 +187,13 @@ class Gallery
static public function delete($id, &$errors)
{
global $db;
if(isset($id))
{
if(self::get($id) !== false)
$db->delete(TABLE_PREFIX . 'gallery', array('id' => $id));
$row = ModelsGallery::find($id);
if($row)
if (!$row->delete()) {
$errors[] = 'Fail during delete Gallery';
}
else
$errors[] = 'Image with id ' . $id . ' does not exists.';
}
@ -203,13 +205,15 @@ class Gallery
static public function toggleHidden($id, &$errors)
{
global $db;
if(isset($id))
{
$query = self::get($id);
if($query !== false)
$db->update(TABLE_PREFIX . 'gallery', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
else
$row = ModelsGallery::find($id);
if($row) {
$row->hidden = $row->hidden == 1 ? 0 : 1;
if (!$row->save()) {
$errors[] = 'Fail during toggle hidden Gallery';
}
} else
$errors[] = 'Image with id ' . $id . ' does not exists.';
}
else
@ -226,10 +230,15 @@ class Gallery
{
$ordering = $query['ordering'] + $i;
$old_record = $db->select(TABLE_PREFIX . 'gallery', array('ordering' => $ordering));
if($old_record !== false)
$db->update(TABLE_PREFIX . 'gallery', array('ordering' => $query['ordering']), array('ordering' => $ordering));
if($old_record !== false) {
ModelsGallery::where('ordering', $ordering)->update([
'ordering' => $query['ordering'],
]);
}
$db->update(TABLE_PREFIX . 'gallery', array('ordering' => $ordering), array('id' => $id));
ModelsGallery::where('id', $id)->update([
'ordering' => $ordering,
]);
}
else
$errors[] = 'Image with id ' . $id . ' does not exists.';
@ -297,13 +306,13 @@ class Gallery
if(!self::resize($file, 170, 110, $thumb_filename, $errors))
return false;
global $db;
if(isset($id))
{
$query = self::get($id);
if($query !== false)
$db->update(TABLE_PREFIX . 'gallery', array('thumb' => $thumb_filename), array('id' => $id));
else
$row = ModelsGallery::find($id);
if($row) {
$row->thumb = $thumb_filename;
$row->save();
} else
$errors[] = 'Image with id ' . $id . ' does not exists.';
}
else

View File

@ -8,6 +8,11 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Player;
use MyAAC\Models\PlayerDeath;
use MyAAC\Models\PlayerKillers;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Highscores';
@ -23,7 +28,7 @@ if(!is_numeric($page) || $page < 1 || $page > PHP_INT_MAX) {
$page = 1;
}
$add_sql = '';
$query = Player::query();
$settingHighscoresVocationBox = setting('core.highscores_vocation_box');
$configVocations = config('vocations');
@ -41,7 +46,7 @@ if($settingHighscoresVocationBox && $vocation !== 'all')
$i += $configVocationsAmount;
}
$add_sql = 'AND `vocation` IN (' . implode(', ', $add_vocs) . ')';
$query->whereIn('players.vocation', $add_vocs);
break;
}
}
@ -112,15 +117,7 @@ else
$promotion = '';
if($db->hasColumn('players', 'promotion'))
$promotion = ',promotion';
$online = '';
if($db->hasColumn('players', 'online'))
$online = ',online';
$deleted = 'deleted';
if($db->hasColumn('players', 'deletion'))
$deleted = 'deletion';
$promotion = ',players.promotion';
$outfit_addons = false;
$outfit = '';
@ -151,6 +148,16 @@ if ($cache->enabled()) {
}
$offset = ($page - 1) * $configHighscoresPerPage;
$query->join('accounts', 'accounts.id', '=', 'players.account_id')
->withOnlineStatus()
->whereNotIn('players.id', setting('core.highscores_ids_hidden'))
->notDeleted()
->where('players.group_id', '<', setting('core.highscores_groups_hidden'))
->limit($limit)
->offset($offset)
->selectRaw('accounts.country, players.id, players.name, players.account_id, players.level, players.vocation' . $outfit . $promotion)
->orderByDesc('value');
if (!isset($highscores) || empty($highscores)) {
if ($skill >= POT::SKILL_FIRST && $skill <= POT::SKILL_LAST) { // skills
if ($db->hasColumn('players', 'skill_fist')) {// tfs 1.0
@ -164,66 +171,51 @@ if (!isset($highscores) || empty($highscores)) {
POT::SKILL_FISH => 'skill_fishing',
);
$highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,vocation' . $promotion . $outfit . ', ' . $skill_ids[$skill] . ' as value FROM accounts,players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND accounts.id = players.account_id ORDER BY ' . $skill_ids[$skill] . ' DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll();
} else
$highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',value,level,vocation' . $promotion . $outfit . ' FROM accounts,players,player_skills WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND players.id = player_skills.player_id AND player_skills.skillid = ' . $skill . ' AND accounts.id = players.account_id ORDER BY value DESC, count DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll();
$query->addSelect($skill_ids[$skill] . ' as value');
} else {
$query
->join('player_skills', 'player_skills.player_id', '=', 'players.id')
->where('skillid', $skill)
->addSelect('player_skills.skillid as value');
}
} else if ($skill == SKILL_FRAGS) // frags
{
if ($db->hasTable('player_killers')) {
$highscores = $db->query('SELECT accounts.country, players.id, players.name' . $online . ',level, vocation' . $promotion . $outfit . ', COUNT(`player_killers`.`player_id`) as value' .
' FROM `accounts`, `players`, `player_killers` ' .
' WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND players.id = player_killers.player_id AND accounts.id = players.account_id' .
' GROUP BY `player_id`' .
' ORDER BY value DESC' .
' LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll();
$query->addSelect(['value' => PlayerKillers::where('player_killers.player_id', 'players.id')->selectRaw('COUNT(*)')]);
} else {
$db->query("SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));");
$highscores = $db->query('SELECT `a`.country, `p`.id, `p`.name' . $online . ',`p`.level, vocation' . $promotion . $outfit . ', COUNT(`pd`.`killed_by`) as value
FROM `players` p
LEFT JOIN `accounts` a ON `a`.`id` = `p`.`account_id`
LEFT JOIN `player_deaths` pd ON `pd`.`killed_by` = `p`.`name`
WHERE `p`.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ')
AND `p`.' . $deleted . ' = 0
AND `p`.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . '
AND `pd`.`unjustified` = 1
GROUP BY `killed_by`
ORDER BY value DESC
LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll();
$query->addSelect(['value' => PlayerDeath::unjustified()->where('player_deaths.killed_by', 'players.name')->selectRaw('COUNT(*)')]);
}
} else if ($skill == SKILL_BALANCE) // balance
{
$highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,balance as value,vocation' . $promotion . $outfit . ' FROM accounts,players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND accounts.id = players.account_id ORDER BY value DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll();
$query
->addSelect('players.balance as value');
} else {
if ($skill == POT::SKILL__MAGLEVEL) {
$highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',maglevel,level,vocation' . $promotion . $outfit . ' FROM accounts, players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 ' . $add_sql . ' AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' AND accounts.id = players.account_id ORDER BY maglevel DESC, manaspent DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll();
$query
->addSelect('players.maglevel as value', 'players.maglevel')
->orderBy('manaspent');
} else { // level
$highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,experience,vocation' . $promotion . $outfit . ' FROM accounts, players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 ' . $add_sql . ' AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' AND accounts.id = players.account_id ORDER BY level DESC, experience DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll();
$query
->addSelect('players.level as value', 'players.experience')
->orderBy('experience');
$list = 'experience';
}
}
}
$highscores = $query->get()->map(function($row) {
$tmp = $row->toArray();
$tmp['online'] = $row->online_status;
$tmp['vocation'] = $row->vocation_name;
unset($tmp['online_table']);
return $tmp;
})->toArray();
if ($cache->enabled() && $needReCache) {
$cache->set($cacheKey, serialize($highscores), setting('core.highscores_cache_ttl') * 60);
}
$online_exist = false;
if($db->hasColumn('players', 'online'))
$online_exist = true;
$players = array();
foreach($highscores as $player) {
$players[] = $player['id'];
}
if($db->hasTable('players_online') && count($players) > 0) {
$query = $db->query('SELECT `player_id`, 1 FROM `players_online` WHERE `player_id` IN (' . implode(', ', $players) . ')')->fetchAll();
foreach($query as $t) {
$is_online[$t['player_id']] = true;
}
}
$show_link_to_next_page = false;
$i = 0;
@ -231,14 +223,6 @@ $settingHighscoresVocation = setting('core.highscores_vocation');
foreach($highscores as $id => &$player)
{
if(isset($is_online)) {
$player['online'] = (isset($is_online[$player['id']]) ? 1 : 0);
} else {
if(!isset($player['online'])) {
$player['online'] = 0;
}
}
if(++$i <= $configHighscoresPerPage)
{
if($skill == POT::SKILL__MAGIC)
@ -248,22 +232,10 @@ foreach($highscores as $id => &$player)
$player['experience'] = number_format($player['experience']);
}
if($settingHighscoresVocation) {
if(isset($player['promotion'])) {
if((int)$player['promotion'] > 0) {
$player['vocation'] += ($player['promotion'] * $configVocationsAmount);
}
}
$tmp = 'Unknown';
if(isset($configVocations[$player['vocation']])) {
$tmp = $configVocations[$player['vocation']];
}
$player['vocation'] = $tmp;
if(!$settingHighscoresVocation) {
unset($player['vocation']);
}
$player['link'] = getPlayerLink($player['name'], false);
$player['flag'] = getFlagImage($player['country']);
if($settingHighscoresOutfit) {

View File

@ -8,6 +8,10 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\ServerConfig;
use MyAAC\Models\ServerRecord;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Who is online?';
@ -98,21 +102,19 @@ foreach($playersOnline as $player) {
$record = '';
if($players > 0) {
if($config['online_record']) {
$result = null;
$timestamp = false;
if($db->hasTable('server_record')) {
$query =
$db->query(
'SELECT `record`, `timestamp` FROM `server_record` WHERE `world_id` = ' . (int)$config['lua']['worldId'] .
' ORDER BY `record` DESC LIMIT 1');
$timestamp = true;
$result = ServerRecord::where('world_id', $config['lua']['worldId'])->orderByDesc('record')->first()->toArray();
} else if($db->hasTable('server_config')) { // tfs 1.0
$query = $db->query('SELECT `value` as `record` FROM `server_config` WHERE `config` = ' . $db->quote('players_record'));
} else {
$query = NULL;
$row = ServerConfig::where('config', 'players_record')->first();
if ($row) {
$result = ['record' => $row->value];
}
}
if(isset($query) && $query->rowCount() > 0) {
$result = $query->fetch();
if($record) {
$record = 'The maximum on this game world was ' . $result['record'] . ' players' . ($timestamp ? ' on ' . date("M d Y, H:i:s", $result['timestamp']) . '.' : '.');
}
}

View File

@ -8,10 +8,18 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\ServerRecord;
defined('MYAAC') or die('Direct access not allowed!');
$title = "Players Online Records";
if(!$db->hasTable('server_record')) {
echo 'Record History is not supported in your distribution.';
return;
}
echo '
<b><div style="text-align:center">Players online records on '.$config['lua']['serverName'].'</div></b>
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%>
@ -21,7 +29,7 @@ echo '
</TR>';
$i = 0;
$records_query = $db->query('SELECT * FROM `server_record` ORDER BY `record` DESC LIMIT 50;');
$records_query = ServerRecord::limit(50)->orderByDesc('record')->get();
foreach($records_query as $data)
{
echo '<TR BGCOLOR=' . getStyle(++$i) . '>
@ -31,4 +39,4 @@ echo '
}
echo '</TABLE>';
?>
?>

View File

@ -8,6 +8,9 @@
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Spell;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Spells';
@ -34,10 +37,10 @@ else {
$order = 'name';
$spells = array();
$spells_db = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'spells` WHERE `hidden` != 1 AND `type` < 4 ORDER BY ' . $order . '');
$spells_db = Spell::where('hidden', '!=', 1)->where('type', '<', 4)->orderBy($order)->get();
if((string)$vocation_id != 'all') {
foreach($spells_db->fetchAll() as $spell) {
foreach($spells_db as $spell) {
$spell_vocations = json_decode($spell['vocations'], true);
if(in_array($vocation_id, $spell_vocations) || count($spell_vocations) == 0) {
$spell['vocations'] = null;
@ -46,7 +49,7 @@ if((string)$vocation_id != 'all') {
}
}
else {
foreach($spells_db->fetchAll() as $spell) {
foreach($spells_db as $spell) {
$vocations = json_decode($spell['vocations'], true);
foreach($vocations as &$tmp_vocation) {

View File

@ -7,6 +7,9 @@
* @copyright 2023 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Pages;
defined('MYAAC') or die('Direct access not allowed!');
if(!isset($content[0]))
@ -206,6 +209,7 @@ else {
$_REQUEST = array_merge($_REQUEST, $vars);
$_GET = array_merge($_GET, $vars);
extract($vars);
if (strpos($path, '__database__/') !== false) {
$pageName = str_replace('__database__/', '', $path);
@ -287,16 +291,13 @@ unset($page);
function getDatabasePages($withHidden = false): array
{
global $db, $logged_access;
$pages = $db->query('SELECT `name` FROM ' . TABLE_PREFIX . 'pages WHERE ' . ($withHidden ? '' : '`hidden` != 1 AND ') . '`access` <= ' . $db->quote($logged_access));
$ret = [];
global $logged_access;
$pages = Pages::where('access', '<=', $logged_access)->when(!$withHidden, function ($q) {
$q->isPublic();
})->get('name');
if ($pages->rowCount() < 1) {
return $ret;
}
foreach($pages->fetchAll() as $page) {
$ret [] = $page['name'];
foreach($pages as $page) {
$ret[] = $page->name;
}
return $ret;

View File

@ -34,7 +34,7 @@ return [
['GET', 'changelog[/{page:int}]', 'changelog.php'],
[['GET', 'POST'], 'creatures[/{name:string}]', 'creatures.php'],
['GET', 'faq[/{action:string}]', 'faq.php'],
[['GET', 'POST'], 'faq[/{action:string}]', 'faq.php'],
[['GET', 'POST'], 'forum/{action:string}[/]', 'forum.php'],
['GET', 'forum/board/{id:int}[/]', 'forum/show_board.php'],

View File

@ -0,0 +1,69 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Account extends Model {
protected $table = 'accounts';
public $timestamps = false;
protected $casts = [
'lastday' => 'integer',
'premdays' => 'integer',
'premend' => 'integer',
'premium_ends_at' => 'integer',
];
public function players()
{
return $this->hasMany(Player::class);
}
public function viplist()
{
return $this->hasMany(AccountVipList::class);
}
public function getPremiumDaysAttribute()
{
if(isset($this->premium_ends_at) || isset($this->premend)) {
$col = isset($this->premium_ends_at) ? 'premium_ends_at' : 'premend';
$ret = ceil(($this->{$col}- time()) / (24 * 60 * 60));
return $ret > 0 ? $ret : 0;
}
if($this->premdays == 0) {
return 0;
}
global $config;
if(isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium'])) return -1;
if($this->premdays == 65535){
return 65535;
}
$ret = ceil($this->premdays - (date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->lastday))) - date("z", $this->lastday)));
return $ret > 0 ? $ret : 0;
}
public function getIsPremiumAttribute()
{
global $config;
if(isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium'])) return true;
if(isset($this->premium_ends_at)) {
return $this->premium_ends_at > time();
}
if(isset($this->premend)) {
return $this->premend > time();
}
return ($this->premdays - (date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->lastday))) - date("z", $this->lastday)) > 0);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class AccountVipList extends Model {
protected $table = 'account_viplist';
public $timestamps = false;
public function account()
{
return $this->belongsTo(Account::class);
}
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class BoostedCreature extends Model {
protected $table = 'boosted_creature';
protected $casts = [
'raceid' => 'integer',
];
public $timestamps = false;
}

View File

@ -0,0 +1,15 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class BugTracker extends Model {
protected $table = TABLE_PREFIX . 'bugtracker';
public $timestamps = false;
protected $fillable = ['account', 'type', 'status', 'text', 'id', 'subject', 'reply', 'who', 'uid', 'tag'];
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Changelog extends Model {
protected $table = TABLE_PREFIX . 'changelog';
public $timestamps = false;
public function scopeIsPublic($query) {
$query->where('hidden', '!=', 1);
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Config extends Model {
protected $table = TABLE_PREFIX . 'config';
public $timestamps = false;
protected $fillable = ['name', 'value'];
}

14
system/src/Models/FAQ.php Normal file
View File

@ -0,0 +1,14 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class FAQ extends Model {
protected $table = TABLE_PREFIX . 'faq';
public $timestamps = false;
protected $fillable = ['question', 'answer', 'ordering', 'hidden'];
}

View File

@ -0,0 +1,13 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Gallery extends Model {
protected $table = TABLE_PREFIX . 'gallery';
public $timestamps = false;
}

View File

@ -0,0 +1,33 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Guild extends Model {
protected $table = 'guilds';
public $timestamps = false;
public function owner()
{
global $db;
$column = 'ownerid';
if($db->hasColumn('guilds', 'owner_id')) {
$column = 'owner_id';
}
return $this->belongsTo(Player::class, $column);
}
public function members()
{
return $this->belongsToMany(Player::class, 'guild_membership')->withPivot('rank_id', 'nick');
}
public function invites()
{
return $this->belongsToMany(Player::class, 'guild_invites');
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class GuildInvites extends Model {
protected $table = 'guild_invites';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
public function guild()
{
return $this->belongsTo(Guild::class);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class GuildMembership extends Model {
protected $table = 'guild_membership';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
public function guild()
{
return $this->belongsTo(Guild::class);
}
public function rank()
{
return $this->belongsTo(GuildRank::class, 'rank_id');
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class GuildRank extends Model {
protected $table = 'guild_ranks';
public $timestamps = false;
public function guild()
{
return $this->belongsTo(Guild::class);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class House extends Model {
protected $table = 'houses';
public $timestamps = false;
public function owner()
{
return $this->belongsTo(Player::class, 'owner');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Menu extends Model {
protected $table = TABLE_PREFIX . 'menu';
public $timestamps = false;
protected $fillable = ['template', 'name', 'link', 'blank', 'color', 'category', 'ordering', 'enabled'];
}

View File

@ -0,0 +1,15 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Monster extends Model {
protected $table = TABLE_PREFIX . 'monsters';
public $timestamps = false;
protected $guarded = ['id']; // lazy dev
}

View File

@ -0,0 +1,22 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class News extends Model {
protected $table = TABLE_PREFIX . 'news';
public $timestamps = false;
protected $fillable = [
'title', 'body', 'type', 'date', 'category', 'player_id',
'last_modified_by', 'last_modified_date', 'comments', 'article_text',
'article_image', 'hidden'
];
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Notepad extends Model {
protected $table = TABLE_PREFIX . 'notepad';
public $timestamps = false;
protected $fillable = [
'account_id', 'content'
];
public function account()
{
return $this->belongsTo(Account::class);
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Pages extends Model {
protected $table = TABLE_PREFIX . 'pages';
public $timestamps = false;
protected $fillable = ['name', 'title', 'body', 'date', 'player_id', 'php', 'enable_tinymce', 'access', 'hidden'];
protected $casts = [
'player_id' => 'integer',
'enable_tinymce' => 'integer',
'access' => 'integer',
'hidden' => 'integer',
];
public function player()
{
return $this->belongsTo(Player::class);
}
public function scopeIsPublic($query) {
$query->where('hidden', '!=', 1);
}
}

View File

@ -0,0 +1,138 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Player extends Model {
protected $table = 'players';
public $timestamps = false;
protected $casts = [
'worldid' => 'integer',
'sex' => 'integer',
'level' => 'integer',
'vocation' => 'integer',
'promotion' => 'integer',
'looktype' => 'integer',
'lookhead' => 'integer',
'lookbody' => 'integer',
'looklegs' => 'integer',
'lookfeet' => 'integer',
'lookaddons' => 'integer',
'isreward' => 'integer',
];
public function scopeOrderBySkill($query, $value)
{
global $db;
$query->when($db->hasColumn('players', 'skill_fist'), function ($query) {
});
}
public function getVocationNameAttribute()
{
$vocation = $this->vocation;
if (isset($this->promotion)) {
$vocation *= $this->promotion;
}
return config('vocations')[$vocation] ?? 'Unknown';
}
public function getIsDeletedAttribute()
{
if (isset($this->deleted)) {
return $this->deleted !== 0;
}
if (isset($this->deletion)) {
return $this->deletion !== 0;
}
return false;
}
public function scopeNotDeleted($query) {
global $db;
$column = 'deleted';
if($db->hasColumn('players', 'deletion')) {
$column = 'deletion';
}
$query->where($column, 0);
}
public function scopeWithOnlineStatus($query) {
global $db;
$query->when($db->hasTable('players_online'), function ($query) {
$query->with('onlineTable');
});
}
public function getOnlineStatusAttribute()
{
global $db;
if ($db->hasColumn('players', 'online')) {
return $this->online;
}
if ($db->hasTable('players_online')) {
return $this->onlineTable != null;
}
return false;
}
public function onlineTable()
{
return $this->belongsTo(PlayerOnline::class);
}
public function account()
{
return $this->belongsTo(Account::class);
}
public function storages()
{
return $this->hasMany(PlayerStorage::class);
}
public function items()
{
return $this->hasMany(PlayerItem::class);
}
public function kills()
{
return $this->hasMany(PlayerKillers::class);
}
public function deaths()
{
return $this->hasMany(PlayerDeath::class);
}
public function houses()
{
return $this->hasMany(House::class, 'owner');
}
public function skills()
{
return $this->hasMany(PlayerSkill::class);
}
public function viplist()
{
return $this->hasMany(PlayerVipList::class);
}
public function scopeOnline($query) {
$query->where('online', '>', 0);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerDeath extends Model {
protected $table = 'player_deaths';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
public function killer()
{
return $this->belongsTo(Player::class, 'killed_by');
}
public function scopeUnjustified($query) {
$query->where('unjustified', 1);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerDepotItem extends Model {
protected $table = 'player_depotitems';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerKillers extends Model {
protected $table = 'players_killers';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerOnline extends Model {
protected $table = 'players_online';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerSkill extends Model {
protected $table = 'player_skills';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerSpell extends Model {
protected $table = 'player_spells';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerStorage extends Model {
protected $table = 'player_storage';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerVipList extends Model {
protected $table = 'player_viplist';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
public function vip()
{
return $this->belongsTo(Player::class, 'vip_id');
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class PlayerItem extends Model {
protected $table = 'player_items';
public $timestamps = false;
public function player()
{
return $this->belongsTo(Player::class);
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class ServerConfig extends Model {
protected $table = 'server_config';
public $timestamps = false;
protected $fillable = ['config', 'value'];
}

View File

@ -0,0 +1,14 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class ServerRecord extends Model {
protected $table = 'server_record';
public $timestamps = false;
protected $fillable = ['record', 'timestamp'];
}

View File

@ -0,0 +1,14 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Settings extends Model {
protected $table = TABLE_PREFIX . 'settings';
public $timestamps = false;
protected $fillable = ['name', 'key', 'value'];
}

View File

@ -0,0 +1,15 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Spell extends Model {
protected $table = TABLE_PREFIX . 'spells';
public $timestamps = false;
protected $guarded = ['id']; // lazy dev
}

View File

@ -0,0 +1,15 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Town extends Model {
protected $table = 'towns';
public $timestamps = false;
protected $fillable = ['id', 'name', 'posx', 'posy', 'posz'];
}

View File

@ -0,0 +1,15 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Visitor extends Model {
protected $table = TABLE_PREFIX . 'visitors';
public $timestamps = false;
protected $fillable = ['ip', 'lastivist', 'page', 'user_agent'];
}

View File

@ -0,0 +1,15 @@
<?php
namespace MyAAC\Models;
use Illuminate\Database\Eloquent\Model;
class Weapon extends Model {
protected $table = TABLE_PREFIX . 'weapons';
public $timestamps = false;
protected $fillable = ['id', 'level', 'maglevel', 'vocations'];
}

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