mirror of
https://github.com/slawkens/myaac.git
synced 2025-09-14 04:23:34 +02:00
Compare commits
140 Commits
feature/ne
...
v0.9.0-alp
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c247789adf | ||
![]() |
cd22f8def5 | ||
![]() |
52ac011556 | ||
![]() |
f34e5f2ac0 | ||
![]() |
ca8db22639 | ||
![]() |
1846bf5255 | ||
![]() |
dce0ac2f8f | ||
![]() |
9cc60983d0 | ||
![]() |
7c2c88f780 | ||
![]() |
7690811da3 | ||
![]() |
7dc2e404ed | ||
![]() |
080ab56ea9 | ||
![]() |
83915f080c | ||
![]() |
2841f17729 | ||
![]() |
0187ba4938 | ||
![]() |
bedfc0a2e0 | ||
![]() |
ea08c04963 | ||
![]() |
067f2af3e5 | ||
![]() |
8d98306f8e | ||
![]() |
09a045334c | ||
![]() |
bc8e5fc144 | ||
![]() |
77e0d28a9d | ||
![]() |
480a054f0c | ||
![]() |
26c895d475 | ||
![]() |
5cbb55cfb1 | ||
![]() |
dcb9506a1b | ||
![]() |
2acec4df12 | ||
![]() |
4bd761c726 | ||
![]() |
2f732b8411 | ||
![]() |
5aa02055bf | ||
![]() |
6ed15565c8 | ||
![]() |
77a2c55c87 | ||
![]() |
4a9fa01eb7 | ||
![]() |
bd031d8980 | ||
![]() |
b76a037a94 | ||
![]() |
e71daa2520 | ||
![]() |
f372aeb067 | ||
![]() |
ef37bbcb81 | ||
![]() |
944457463e | ||
![]() |
6f7f25bb46 | ||
![]() |
d60d7f2250 | ||
![]() |
2b8c4b3eca | ||
![]() |
7039bda359 | ||
![]() |
d346a8f73f | ||
![]() |
523f2dee7c | ||
![]() |
b33e39491b | ||
![]() |
317ebf4387 | ||
![]() |
31ba780099 | ||
![]() |
d1b30619e2 | ||
![]() |
3fab52296a | ||
![]() |
a6e109799a | ||
![]() |
80af2cd691 | ||
![]() |
d911b55e25 | ||
![]() |
eb73fc4538 | ||
![]() |
75f77ec7a3 | ||
![]() |
a1d969bbfd | ||
![]() |
11f1ad6d76 | ||
![]() |
7facf0adad | ||
![]() |
2b739c2b40 | ||
![]() |
269ae323e0 | ||
![]() |
0d0e5812dd | ||
![]() |
61c2661377 | ||
![]() |
de710dff94 | ||
![]() |
8c524171fb | ||
![]() |
946d24690c | ||
![]() |
bf137189c5 | ||
![]() |
da4e18cb69 | ||
![]() |
85769c1439 | ||
![]() |
4d3ad4b6b9 | ||
![]() |
e900a62e75 | ||
![]() |
c3969364aa | ||
![]() |
e9df9f10dc | ||
![]() |
f78f5b5361 | ||
![]() |
c061438a35 | ||
![]() |
8441dbe007 | ||
![]() |
e21a741a78 | ||
![]() |
955f437e6c | ||
![]() |
fd419076c2 | ||
![]() |
7569536d56 | ||
![]() |
3a6102900f | ||
![]() |
6dbc694409 | ||
![]() |
7a3dcc4dc6 | ||
![]() |
23393b5d3e | ||
![]() |
863f3ad510 | ||
![]() |
e6d86ca280 | ||
![]() |
c22e25e3d2 | ||
![]() |
52ffb195ec | ||
![]() |
92a51af638 | ||
![]() |
d7a9158cf2 | ||
![]() |
f0f84090d2 | ||
![]() |
9d78a3b5cf | ||
![]() |
2fc163af5a | ||
![]() |
10be98e371 | ||
![]() |
e0eb083e44 | ||
![]() |
e17cd78153 | ||
![]() |
0015f511f8 | ||
![]() |
f0f71c9f85 | ||
![]() |
0002543cca | ||
![]() |
c1096415aa | ||
![]() |
6625768228 | ||
![]() |
a27f601fe8 | ||
![]() |
72a877d9ca | ||
![]() |
b7ba09a551 | ||
![]() |
a98cb66c53 | ||
![]() |
6785ecad1d | ||
![]() |
937af536b6 | ||
![]() |
5487314230 | ||
![]() |
51e9bb2a7f | ||
![]() |
376bb981ae | ||
![]() |
ed9d78d2f3 | ||
![]() |
3c4e50dbda | ||
![]() |
523f9dd95a | ||
![]() |
a43742c8b1 | ||
![]() |
c49e4fd63d | ||
![]() |
905cce7021 | ||
![]() |
7a49b5dedc | ||
![]() |
3a2870a6bb | ||
![]() |
9a475f2c57 | ||
![]() |
58598742e8 | ||
![]() |
d04e44f52f | ||
![]() |
c7ec1f44e9 | ||
![]() |
3ed9a5d3d8 | ||
![]() |
61285b6b8c | ||
![]() |
d17c547bca | ||
![]() |
7bc20b0993 | ||
![]() |
6c4b3dea96 | ||
![]() |
6ae1bf5814 | ||
![]() |
8503135ce0 | ||
![]() |
590fe0762d | ||
![]() |
d565b90736 | ||
![]() |
c88156802a | ||
![]() |
7d8dbcbde7 | ||
![]() |
66ec66b291 | ||
![]() |
fc0eb0e793 | ||
![]() |
ed7e9e1eae | ||
![]() |
8985917a96 | ||
![]() |
3a3411c117 | ||
![]() |
1166ddfe87 | ||
![]() |
574e361f90 | ||
![]() |
f3745a2752 |
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -3,8 +3,12 @@
|
||||
.gitignore export-ignore
|
||||
.github export-ignore
|
||||
.editorconfig export-ignore
|
||||
.travis.yml export-ignore
|
||||
_config.yml export-ignore
|
||||
release.sh export-ignore
|
||||
|
||||
# cypress
|
||||
cypress export-ignore
|
||||
cypress.config.js export-ignore
|
||||
cypress.env.json
|
||||
|
||||
*.sh text eol=lf
|
||||
|
120
.github/workflows/cypress.yml
vendored
Normal file
120
.github/workflows/cypress.yml
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
name: Cypress
|
||||
on:
|
||||
pull_request:
|
||||
branches: [develop]
|
||||
push:
|
||||
branches: [develop]
|
||||
|
||||
jobs:
|
||||
cypress:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: myaac
|
||||
MYSQL_USER: myaac
|
||||
MYSQL_PASSWORD: myaac
|
||||
ports:
|
||||
- 3306/tcp
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: [ '7.4', '8.0', '8.1' ]
|
||||
name: MyAAC on PHP ${{ matrix.php-versions }}
|
||||
steps:
|
||||
- name: 📌 MySQL Start & init & show db
|
||||
run: |
|
||||
sudo /etc/init.d/mysql start
|
||||
mysql -e 'CREATE DATABASE myaac;' -uroot -proot
|
||||
mysql -e "SHOW DATABASES" -uroot -proot
|
||||
|
||||
- name: Checkout MyAAC
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: develop
|
||||
|
||||
- name: Checkout TFS
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: otland/forgottenserver
|
||||
ref: 1.4
|
||||
path: tfs
|
||||
|
||||
- name: Import TFS Schema
|
||||
run: |
|
||||
mysql -uroot -proot myaac < tfs/schema.sql
|
||||
|
||||
- name: Rename config.lua
|
||||
run: mv tfs/config.lua.dist tfs/config.lua
|
||||
|
||||
- name: Replace mysqlUser
|
||||
uses: jacobtomlinson/gha-find-replace@v2
|
||||
with:
|
||||
find: 'mysqlUser = "forgottenserver"'
|
||||
replace: 'mysqlUser = "root"'
|
||||
regex: false
|
||||
include: 'tfs/config.lua'
|
||||
|
||||
- name: Replace mysqlPass
|
||||
uses: jacobtomlinson/gha-find-replace@v2
|
||||
with:
|
||||
find: 'mysqlPass = ""'
|
||||
replace: 'mysqlPass = "root"'
|
||||
regex: false
|
||||
include: 'tfs/config.lua'
|
||||
|
||||
- name: Replace mysqlDatabase
|
||||
uses: jacobtomlinson/gha-find-replace@v2
|
||||
with:
|
||||
find: 'mysqlDatabase = "forgottenserver"'
|
||||
replace: 'mysqlDatabase = "myaac"'
|
||||
regex: false
|
||||
include: 'tfs/config.lua'
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: mbstring, dom, fileinfo, mysql, json, xml, pdo, pdo_mysql
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
# Use composer.json for key, if composer.lock is not committed.
|
||||
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: Run PHP server
|
||||
run: nohup php -S localhost:8080 > php.log 2>&1 &
|
||||
|
||||
- name: Cypress Run
|
||||
uses: cypress-io/github-action@v5
|
||||
env:
|
||||
CYPRESS_URL: http://localhost:8080
|
||||
CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/tfs
|
||||
|
||||
- name: Save screenshots
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: cypress-screenshots
|
||||
path: cypress/screenshots
|
||||
|
||||
- name: Upload Cypress Videos
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: cypress-videos
|
||||
path: cypress/videos
|
11
.github/workflows/phplint.yml
vendored
11
.github/workflows/phplint.yml
vendored
@@ -1,13 +1,16 @@
|
||||
name: PHP Linting
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, develop]
|
||||
branches: [develop]
|
||||
push:
|
||||
branches: [master]
|
||||
branches: [develop]
|
||||
|
||||
jobs:
|
||||
phplint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: michaelw90/PHP-Lint@master
|
||||
- uses: actions/checkout@v3
|
||||
- uses: overtrue/phplint@8.2
|
||||
with:
|
||||
path: .
|
||||
options: --exclude=*.log
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -9,6 +9,10 @@ vendor
|
||||
# npm
|
||||
node_modules
|
||||
|
||||
# cypress
|
||||
cypress.env.json
|
||||
cypress/e2e/2-advanced-examples
|
||||
|
||||
# created by release.sh
|
||||
releases
|
||||
tmp
|
||||
|
@@ -6,10 +6,14 @@
|
||||
Options -MultiViews
|
||||
</IfModule>
|
||||
|
||||
<FilesMatch "^(CHANGELOG\.md|README\.md|composer\.json|composer\.lock|package\.json|package-lock\.json|cypress\.env\.json)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
|
||||
#RewriteBase /myaac/
|
||||
#RewriteBase /myaac/
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
18
.travis.yml
18
.travis.yml
@@ -1,18 +0,0 @@
|
||||
|
||||
language: php
|
||||
php:
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- 7.4
|
||||
- 8.0
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
|
||||
before_script:
|
||||
- composer require php-parallel-lint/php-parallel-lint --no-suggest --no-progress --no-interaction --no-ansi --quiet --optimize-autoloader
|
||||
|
||||
script:
|
||||
- php vendor/bin/parallel-lint --no-progress --no-colors --exclude vendor --exclude "system/libs/pot/OTS_DB_PDOQuery.php" .
|
50
CHANGELOG.md
50
CHANGELOG.md
@@ -1,9 +1,55 @@
|
||||
# Changelog
|
||||
|
||||
## [0.9.0 - x.x.2020]
|
||||
## [0.9.0-alpha - 02.06.2023]
|
||||
|
||||
Minimum PHP version for this release is 7.2.5.
|
||||
|
||||
### Added
|
||||
* reworked Admin Panel (@Leesneaks, @gpedro, @slawkens)
|
||||
* updated to Bootstrap v4
|
||||
* new Menu
|
||||
* new Dashboard: statistics, server status
|
||||
* new Admin Bar showed on top when admin logged in
|
||||
* new page: Server Data, to reload server data
|
||||
* new pages: mass account & teleport tools
|
||||
* changelogs editor
|
||||
* revised Accounts & Players editors
|
||||
* option to add/modify menus with plugins
|
||||
* option to enable/disable plugins
|
||||
* better, updated TinyMCE editor (v6.x)
|
||||
* with option to upload images
|
||||
* list of open source libraries used in project
|
||||
* brand new charming installation page (by @fernandomatos)
|
||||
* using Bootstrap
|
||||
* new pages router: nikic/fast-route, allowing for better customisation
|
||||
* Guild Wars support (available as plugin)
|
||||
* support for login and create account only by email (configurable)
|
||||
* with no need for account name
|
||||
* Google ReCAPTCHA v3 support (available as plugin)
|
||||
* automatically load towns names from .OTBM file
|
||||
* support for Account Number
|
||||
* suggest account number option
|
||||
* many new functions, hooks and configurables
|
||||
* better Exception Handler (Whoops - https://github.com/filp/whoops)
|
||||
* add Cypress testing
|
||||
|
||||
### Changed
|
||||
* Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc.
|
||||
* mail support is disabled on fresh install, can be manually enabled by user
|
||||
* disable add php pages in admin panel for security. Option to disable plugins upload
|
||||
* visitors counter shows now user browser, and also if its bot
|
||||
* changes in required and optional PHP extensions
|
||||
* reworked Pages:
|
||||
* Bans
|
||||
* works now for TFS 1.x
|
||||
* Highscores
|
||||
* frags works for TFS 1.x
|
||||
* cached
|
||||
* creatures
|
||||
* moved pages to Twig:
|
||||
* experience stages
|
||||
* update player_deaths entries on name change
|
||||
* change_password email to be more informal
|
||||
|
||||
### Fixed
|
||||
### Fixed
|
||||
* hundrets of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here
|
||||
|
2
CREDITS
2
CREDITS
@@ -1,3 +1,3 @@
|
||||
* Gesior.pl (2007 - 2008)
|
||||
* Slawkens (2009 - 2022)
|
||||
* Slawkens (2009 - 2023)
|
||||
* Contributors listed in CONTRIBUTORS.txt
|
||||
|
@@ -36,7 +36,7 @@ Official website: https://my-aac.org
|
||||
chmod 660 images/guilds
|
||||
chmod 660 images/houses
|
||||
chmod 660 images/gallery
|
||||
chmod -R 770 system/cache
|
||||
chmod -R 760 system/cache
|
||||
|
||||
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.
|
||||
|
||||
|
@@ -29,6 +29,11 @@ define('PAGE', $page);
|
||||
require SYSTEM . 'functions.php';
|
||||
require SYSTEM . 'init.php';
|
||||
|
||||
// verify myaac tables exists in database
|
||||
if(!$db->hasTable('myaac_account_actions')) {
|
||||
throw new RuntimeException('Seems that the table <strong>myaac_account_actions</strong> of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting <a href="' . BASE_URL . 'install">this</a> url.');
|
||||
}
|
||||
|
||||
if(config('env') === 'dev') {
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
@@ -70,7 +75,9 @@ if(!@file_exists($file)) {
|
||||
}
|
||||
|
||||
ob_start();
|
||||
include($file);
|
||||
if($hooks->trigger(HOOK_ADMIN_BEFORE_PAGE)) {
|
||||
require $file;
|
||||
}
|
||||
|
||||
$content .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
@@ -10,12 +10,17 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$title = 'Account editor';
|
||||
$admin_base = BASE_URL . 'admin/?p=accounts';
|
||||
$admin_base = ADMIN_URL . '?p=accounts';
|
||||
$use_datatable = true;
|
||||
|
||||
if ($config['account_country'])
|
||||
require SYSTEM . 'countries.conf.php';
|
||||
|
||||
$nameOrNumberColumn = 'name';
|
||||
if (USE_ACCOUNT_NUMBER) {
|
||||
$nameOrNumberColumn = 'number';
|
||||
}
|
||||
|
||||
$hasSecretColumn = $db->hasColumn('accounts', 'secret');
|
||||
$hasCoinsColumn = $db->hasColumn('accounts', 'coins');
|
||||
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
|
||||
@@ -48,16 +53,16 @@ else if (isset($_REQUEST['search'])) {
|
||||
if (strlen($search_account) < 3 && !Validator::number($search_account)) {
|
||||
echo_error('Player name is too short.');
|
||||
} else {
|
||||
$query = $db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $db->quote($search_account));
|
||||
$query = $db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $db->quote($search_account));
|
||||
if ($query->rowCount() == 1) {
|
||||
$query = $query->fetch();
|
||||
$id = (int)$query['id'];
|
||||
} else {
|
||||
$query = $db->query('SELECT `id`, `name` FROM `accounts` WHERE `name` LIKE ' . $db->quote('%' . $search_account . '%'));
|
||||
$query = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` LIKE ' . $db->quote('%' . $search_account . '%'));
|
||||
if ($query->rowCount() > 0 && $query->rowCount() <= 10) {
|
||||
$str_construct = 'Do you mean?<ul class="mb-0">';
|
||||
foreach ($query as $row)
|
||||
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row['name'] . '</a></li>';
|
||||
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row[$nameOrNumberColumn] . '</a></li>';
|
||||
$str_construct .= '</ul>';
|
||||
echo_error($str_construct);
|
||||
} else if ($query->rowCount() > 10)
|
||||
@@ -145,7 +150,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
$web_lastlogin = strtotime($_POST['web_lastlogin']);
|
||||
verify_number($web_lastlogin, 'Web Last login', 11);
|
||||
|
||||
if (!$error) {
|
||||
if (!$error && $hooks->trigger(HOOK_ADMIN_ACCOUNTS_SAVE_POST, ['account_id' => $account->getId(), 'account_email' => $account->getEMail()])) {
|
||||
if (USE_ACCOUNT_NAME) {
|
||||
$account->setName($name);
|
||||
}
|
||||
@@ -203,7 +208,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
}
|
||||
}
|
||||
} else if ($id == 0) {
|
||||
$accounts_db = $db->query('SELECT `id`, `name`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC');
|
||||
$accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC');
|
||||
?>
|
||||
<div class="col-12 col-sm-12 col-lg-10">
|
||||
<div class="card card-info card-outline">
|
||||
@@ -215,7 +220,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th><?= ($nameOrNumberColumn == 'number' ? 'Number' : 'Name'); ?></th>
|
||||
<?php if($hasTypeColumn || $hasGroupColumn): ?>
|
||||
<th>Position</th>
|
||||
<?php endif; ?>
|
||||
@@ -226,7 +231,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
<?php foreach ($accounts_db as $account_lst): ?>
|
||||
<tr>
|
||||
<th><?php echo $account_lst['id']; ?></th>
|
||||
<td><?php echo $account_lst['name']; ?></a></td>
|
||||
<td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td>
|
||||
<?php if($hasTypeColumn || $hasGroupColumn): ?>
|
||||
<td>
|
||||
<?php if ($hasTypeColumn) {
|
||||
@@ -284,6 +289,11 @@ else if (isset($_REQUEST['search'])) {
|
||||
<label for="name">Account Name:</label>
|
||||
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getName(); ?>"/>
|
||||
</div>
|
||||
<?php elseif (USE_ACCOUNT_NUMBER): ?>
|
||||
<div class="col-12 col-sm-12 col-lg-4">
|
||||
<label for="name">Account Number:</label>
|
||||
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getNumber(); ?>"/>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="col-12 col-sm-12 col-lg-5">
|
||||
<div class="form-check">
|
||||
|
@@ -10,6 +10,12 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
$title = 'Login';
|
||||
|
||||
require PAGES . 'account/login.php';
|
||||
if ($logged) {
|
||||
header('Location: ' . ADMIN_URL);
|
||||
return;
|
||||
}
|
||||
|
||||
$twig->display('admin.login.html.twig', [
|
||||
'logout' => (ACTION == 'logout' ? 'You have been logged out!' : ''),
|
||||
'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number',
|
||||
|
@@ -16,7 +16,7 @@ if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) {
|
||||
}
|
||||
|
||||
if (!config('mail_enabled')) {
|
||||
echo 'Mail support disabled.';
|
||||
echo 'Mail support disabled in config.';
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -76,18 +76,18 @@ if (!empty($action)) {
|
||||
$enable_tinymce = $_page['enable_tinymce'] == '1';
|
||||
$access = $_page['access'];
|
||||
} else {
|
||||
if(Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access)) {
|
||||
if(Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
|
||||
$action = $name = $p_title = $body = '';
|
||||
$player_id = 1;
|
||||
$access = 0;
|
||||
$php = false;
|
||||
$enable_tinymce = true;
|
||||
success("Updated successful.");
|
||||
success('Updated successful.');
|
||||
}
|
||||
}
|
||||
} else if ($action == 'hide') {
|
||||
Pages::toggleHidden($id, $errors, $status);
|
||||
success(($status == 1 ? 'Show' : 'Hide') . " successful.");
|
||||
success(($status == 1 ? 'Show' : 'Hide') . ' successful.');
|
||||
}
|
||||
|
||||
if (!empty($errors))
|
||||
@@ -152,6 +152,10 @@ class Pages
|
||||
$errors[] = 'Enable PHP is wrong.';
|
||||
return false;
|
||||
}
|
||||
if ($php == 1 && !getBoolean(config('admin_pages_php_enable'))) {
|
||||
$errors[] = 'PHP pages disabled on this server. To enable go to config.php and change admin_pages_php_enable to "yes".';
|
||||
return false;
|
||||
}
|
||||
if(!isset($enable_tinymce) || ($enable_tinymce != 0 && $enable_tinymce != 1)) {
|
||||
$errors[] = 'Enable TinyMCE is wrong.';
|
||||
return false;
|
||||
@@ -200,7 +204,7 @@ class Pages
|
||||
return !count($errors);
|
||||
}
|
||||
|
||||
static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access)
|
||||
static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors)
|
||||
{
|
||||
if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
|
||||
return false;
|
||||
|
@@ -16,4 +16,4 @@ if (!function_exists('phpinfo')) { ?>
|
||||
<?php return;
|
||||
}
|
||||
?>
|
||||
<iframe src="<?php echo BASE_URL; ?>admin/tools/phpinfo.php" width="1024" height="550"></iframe>
|
||||
<iframe src="<?php echo ADMIN_URL; ?>tools/phpinfo.php" width="1024" height="550"></iframe>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$title = 'Player editor';
|
||||
$player_base = BASE_URL . 'admin/?p=players';
|
||||
$player_base = ADMIN_URL . '?p=players';
|
||||
|
||||
$use_datatable = true;
|
||||
require_once LIBS . 'forum.php';
|
||||
@@ -663,7 +663,14 @@ else if (isset($_REQUEST['search'])) {
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-lg-6">
|
||||
<label for="lastip" class="control-label">Last IP:</label>
|
||||
<input type="text" class="form-control" id="lastip" name="lastip" autocomplete="off" maxlength="10" value="<?php echo longToIp($player->getLastIP()); ?>" readonly/>
|
||||
<input type="text" class="form-control" id="lastip" name="lastip" autocomplete="off" maxlength="10" value="<?php
|
||||
if (strlen($player->getLastIP()) > 11) {
|
||||
echo inet_ntop($player->getLastIP());
|
||||
}
|
||||
else {
|
||||
echo longToIp($player->getLastIP());
|
||||
}
|
||||
?>" readonly/>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($db->hasColumn('players', 'loss_experience')): ?>
|
||||
|
@@ -13,98 +13,119 @@ $use_datatable = true;
|
||||
|
||||
require_once LIBS . 'plugins.php';
|
||||
|
||||
$twig->display('admin.plugins.form.html.twig');
|
||||
if (!getBoolean(config('admin_plugins_manage_enable'))) {
|
||||
warning('Plugin installation and management is disabled in config.<br/>If you wish to enable, go to config.php and change <b>admin_plugins_manage_enable</b> to "yes".');
|
||||
}
|
||||
else {
|
||||
$twig->display('admin.plugins.form.html.twig');
|
||||
|
||||
if (isset($_REQUEST['uninstall'])) {
|
||||
$uninstall = $_REQUEST['uninstall'];
|
||||
if (isset($_REQUEST['uninstall'])) {
|
||||
$uninstall = $_REQUEST['uninstall'];
|
||||
|
||||
if (Plugins::uninstall($uninstall)) {
|
||||
success('Successfully uninstalled plugin ' . $uninstall);
|
||||
} else {
|
||||
error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError());
|
||||
}
|
||||
} else if (isset($_FILES["plugin"]["name"])) {
|
||||
$file = $_FILES["plugin"];
|
||||
$filename = $file["name"];
|
||||
$tmp_name = $file["tmp_name"];
|
||||
$type = $file["type"];
|
||||
|
||||
$name = explode(".", $filename);
|
||||
$accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', 'application/octet-stream', 'application/zip-compressed');
|
||||
|
||||
if (isset($file['error'])) {
|
||||
$error = 'Error uploading file';
|
||||
switch ($file['error']) {
|
||||
case UPLOAD_ERR_OK:
|
||||
$error = false;
|
||||
break;
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
$error .= ' - file too large (limit of ' . ini_get('upload_max_filesize') . ' bytes). You can enlarge the limits by changing "upload_max_filesize" in php.ini';
|
||||
break;
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
$error .= ' - file upload was not completed.';
|
||||
break;
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
$error .= ' - zero-length file uploaded.';
|
||||
break;
|
||||
default:
|
||||
$error .= ' - internal error #' . $file['error'];
|
||||
break;
|
||||
if (Plugins::uninstall($uninstall)) {
|
||||
success('Successfully uninstalled plugin ' . $uninstall);
|
||||
} else {
|
||||
error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError());
|
||||
}
|
||||
}
|
||||
} else if (isset($_REQUEST['enable'])) {
|
||||
$enable = $_REQUEST['enable'];
|
||||
if (Plugins::enable($enable)) {
|
||||
success('Successfully enabled plugin ' . $enable);
|
||||
} else {
|
||||
error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError());
|
||||
}
|
||||
} else if (isset($_REQUEST['disable'])) {
|
||||
$disable = $_REQUEST['disable'];
|
||||
if (Plugins::disable($disable)) {
|
||||
success('Successfully disabled plugin ' . $disable);
|
||||
} else {
|
||||
error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError());
|
||||
}
|
||||
} else if (isset($_FILES['plugin']['name'])) {
|
||||
$file = $_FILES['plugin'];
|
||||
$filename = $file['name'];
|
||||
$tmp_name = $file['tmp_name'];
|
||||
$type = $file['type'];
|
||||
|
||||
if (isset($error) && $error != false) {
|
||||
error($error);
|
||||
} else {
|
||||
if (is_uploaded_file($file['tmp_name'])) {
|
||||
$filetype = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
if ($filetype == 'zip') // check if it is zipped/compressed file
|
||||
{
|
||||
$tmp_filename = pathinfo($filename, PATHINFO_FILENAME);
|
||||
$targetzip = BASE . 'plugins/' . $tmp_filename . '.zip';
|
||||
$name = explode('.', $filename);
|
||||
$accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', 'application/octet-stream', 'application/zip-compressed');
|
||||
|
||||
if (move_uploaded_file($tmp_name, $targetzip)) { // move uploaded file
|
||||
if (Plugins::install($targetzip)) {
|
||||
foreach (Plugins::getWarnings() as $warning) {
|
||||
warning($warning);
|
||||
if (isset($file['error'])) {
|
||||
$error = 'Error uploading file';
|
||||
switch ($file['error']) {
|
||||
case UPLOAD_ERR_OK:
|
||||
$error = false;
|
||||
break;
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
$error .= ' - file too large (limit of ' . ini_get('upload_max_filesize') . ' bytes). You can enlarge the limits by changing "upload_max_filesize" in php.ini';
|
||||
break;
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
$error .= ' - file upload was not completed.';
|
||||
break;
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
$error .= ' - zero-length file uploaded.';
|
||||
break;
|
||||
default:
|
||||
$error .= ' - internal error #' . $file['error'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($error) && $error != false) {
|
||||
error($error);
|
||||
} else {
|
||||
if (is_uploaded_file($file['tmp_name'])) {
|
||||
$filetype = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
if ($filetype == 'zip') // check if it is zipped/compressed file
|
||||
{
|
||||
$tmp_filename = pathinfo($filename, PATHINFO_FILENAME);
|
||||
$targetzip = BASE . 'plugins/' . $tmp_filename . '.zip';
|
||||
|
||||
if (move_uploaded_file($tmp_name, $targetzip)) { // move uploaded file
|
||||
if (Plugins::install($targetzip)) {
|
||||
foreach (Plugins::getWarnings() as $warning) {
|
||||
warning($warning);
|
||||
}
|
||||
|
||||
$info = Plugins::getPluginJson();
|
||||
success((isset($info['name']) ? '<strong>' . $info['name'] . '</strong> p' : 'P') . 'lugin has been successfully installed.');
|
||||
} else {
|
||||
$error = Plugins::getError();
|
||||
error(!empty($error) ? $error : 'Unexpected error happened while installing plugin. Please try again later.');
|
||||
}
|
||||
|
||||
$info = Plugins::getPluginJson();
|
||||
success((isset($info['name']) ? '<strong>' . $info['name'] . '</strong> p' : 'P') . 'lugin has been successfully installed.');
|
||||
} else {
|
||||
$error = Plugins::getError();
|
||||
error(!empty($error) ? $error : 'Unexpected error happened while installing plugin. Please try again later.');
|
||||
}
|
||||
|
||||
unlink($targetzip); // delete the Zipped file
|
||||
} else
|
||||
error('There was a problem with the upload. Please try again.');
|
||||
unlink($targetzip); // delete the Zipped file
|
||||
} else
|
||||
error('There was a problem with the upload. Please try again.');
|
||||
} else {
|
||||
error('The file you are trying to upload is not a .zip file. Please try again.');
|
||||
}
|
||||
} else {
|
||||
error('The file you are trying to upload is not a .zip file. Please try again.');
|
||||
error('Error uploading file - unknown error.');
|
||||
}
|
||||
} else {
|
||||
error('Error uploading file - unknown error.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$plugins = array();
|
||||
foreach (get_plugins() as $plugin) {
|
||||
foreach (get_plugins(true) as $plugin) {
|
||||
$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json');
|
||||
$string = Plugins::removeComments($string);
|
||||
$plugin_info = json_decode($string, true);
|
||||
|
||||
if ($plugin_info == false) {
|
||||
if (!$plugin_info) {
|
||||
warning('Cannot load plugin info ' . $plugin . '.json');
|
||||
} else {
|
||||
$disabled = (strpos($plugin, 'disabled.') !== false);
|
||||
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
|
||||
$plugins[] = array(
|
||||
'name' => isset($plugin_info['name']) ? $plugin_info['name'] : '',
|
||||
'description' => isset($plugin_info['description']) ? $plugin_info['description'] : '',
|
||||
'version' => isset($plugin_info['version']) ? $plugin_info['version'] : '',
|
||||
'author' => isset($plugin_info['author']) ? $plugin_info['author'] : '',
|
||||
'contact' => isset($plugin_info['contact']) ? $plugin_info['contact'] : '',
|
||||
'file' => $plugin,
|
||||
'name' => $plugin_info['name'] ?? '',
|
||||
'description' => $plugin_info['description'] ?? '',
|
||||
'version' => $plugin_info['version'] ?? '',
|
||||
'author' => $plugin_info['author'] ?? '',
|
||||
'contact' => $plugin_info['contact'] ?? '',
|
||||
'file' => $pluginOriginal,
|
||||
'enabled' => !$disabled,
|
||||
'uninstall' => isset($plugin_info['uninstall'])
|
||||
);
|
||||
}
|
||||
|
@@ -8,6 +8,11 @@
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
use DeviceDetector\DeviceDetector;
|
||||
use DeviceDetector\Parser\Client\Browser;
|
||||
use DeviceDetector\Parser\OperatingSystem;
|
||||
|
||||
$title = 'Visitors';
|
||||
$use_datatable = true;
|
||||
|
||||
@@ -30,6 +35,31 @@ function compare($a, $b)
|
||||
$tmp = $visitors->getVisitors();
|
||||
usort($tmp, 'compare');
|
||||
|
||||
foreach ($tmp as &$visitor) {
|
||||
$userAgent = $visitor['user_agent'] ?? '';
|
||||
if (!strlen($userAgent) || $userAgent == 'unknown') {
|
||||
$browser = 'Unknown';
|
||||
}
|
||||
else {
|
||||
$dd = new DeviceDetector($userAgent);
|
||||
$dd->parse();
|
||||
|
||||
if ($dd->isBot()) {
|
||||
$bot = $dd->getBot();
|
||||
$message = '(Bot) %s, <a href="%s" target="_blank">%s</a>';
|
||||
$browser = sprintf($message, $bot['category'], $bot['url'], $bot['name']);
|
||||
}
|
||||
else {
|
||||
$osFamily = OperatingSystem::getOsFamily($dd->getOs('name'));
|
||||
$browserFamily = Browser::getBrowserFamily($dd->getClient('name'));
|
||||
|
||||
$browser = $osFamily . ', ' . $browserFamily;
|
||||
}
|
||||
}
|
||||
|
||||
$visitor['browser'] = $browser;
|
||||
}
|
||||
|
||||
$twig->display('admin.visitors.html.twig', array(
|
||||
'config_visitors_counter_ttl' => $config['visitors_counter_ttl'],
|
||||
'visitors' => $tmp
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<?php $hooks->trigger(HOOK_ADMIN_HEAD_START); ?>
|
||||
<?php echo template_header(true); ?>
|
||||
<title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
@@ -16,8 +17,10 @@
|
||||
<script src="<?php echo BASE_URL; ?>tools/js/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
|
||||
<?php $hooks->trigger(HOOK_ADMIN_HEAD_END); ?>
|
||||
</head>
|
||||
<body class="sidebar-mini ">
|
||||
<?php $hooks->trigger(HOOK_ADMIN_BODY_START); ?>
|
||||
<?php if ($logged && admin()) { ?>
|
||||
<div class="wrapper">
|
||||
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
|
||||
@@ -195,5 +198,6 @@ if ($logged && admin()) {
|
||||
<script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script>
|
||||
<?php } ?>
|
||||
<script src="<?php echo BASE_URL; ?>tools/js/adminlte.min.js"></script>
|
||||
<?php $hooks->trigger(HOOK_ADMIN_BODY_END); ?>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -26,8 +26,8 @@
|
||||
if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.');
|
||||
|
||||
const MYAAC = true;
|
||||
const MYAAC_VERSION = '0.9.0-dev';
|
||||
const DATABASE_VERSION = 33;
|
||||
const MYAAC_VERSION = '0.9.0-alpha';
|
||||
const DATABASE_VERSION = 35;
|
||||
const TABLE_PREFIX = 'myaac_';
|
||||
define('START_TIME', microtime(true));
|
||||
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
|
||||
@@ -138,11 +138,9 @@ if(!IS_CLI) {
|
||||
|
||||
define('SERVER_URL', 'http' . (isset($_SERVER['HTTPS'][0]) && strtolower($_SERVER['HTTPS']) === 'on' ? 's' : '') . '://' . $baseHost);
|
||||
define('BASE_URL', SERVER_URL . BASE_DIR . '/');
|
||||
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/');
|
||||
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/');
|
||||
|
||||
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
|
||||
|
||||
require SYSTEM . 'exception.php';
|
||||
}
|
||||
|
||||
$autoloadFile = VENDOR . 'autoload.php';
|
||||
|
@@ -10,6 +10,10 @@
|
||||
"composer/semver": "^3.2",
|
||||
"twig/twig": "^2.0",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"nikic/fast-route": "^1.3"
|
||||
"nikic/fast-route": "^1.3",
|
||||
"matomo/device-detector": "^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"filp/whoops": "^2.15"
|
||||
}
|
||||
}
|
||||
|
16
config.php
16
config.php
@@ -142,18 +142,6 @@ $config = array(
|
||||
'smtp_secure' => '', // What kind of encryption to use on the SMTP connection. Options: '', 'ssl' (GMail) or 'tls' (Microsoft Outlook)
|
||||
'smtp_debug' => false, // set true to debug (you will see more info in error.log)
|
||||
|
||||
// Google reCAPTCHA (prevent spam bots)
|
||||
'recaptcha_enabled' => false, // enable recaptcha verification code
|
||||
'recaptcha_type' => 'v3', // 'v2-checkbox', 'v2-invisible', 'v3'
|
||||
'recaptcha_site_key' => '', // get your own site and secret keys at https://www.google.com/recaptcha
|
||||
'recaptcha_secret_key' => '',
|
||||
// following option apply only for ReCaptcha v2-checkbox
|
||||
'recaptcha_v2_theme' => 'light', // light, dark
|
||||
// following option apply only for ReCaptcha v3
|
||||
// min score for validation, between 0 - 1.0
|
||||
// https://developers.google.com/recaptcha/docs/v3#interpreting_the_score
|
||||
'recaptcha_v3_min_score' => 0.5,
|
||||
|
||||
//
|
||||
'generate_new_reckey' => true, // let player generate new recovery key, he will receive e-mail with new rec key (not display on page, hacker can't generate rec key)
|
||||
'generate_new_reckey_price' => 20, // price for new recovery key
|
||||
@@ -311,6 +299,10 @@ $config = array(
|
||||
'status_interval' => 60,
|
||||
|
||||
// admin panel
|
||||
'admin_plugins_manage_enable' => 'yes', // you can disable possibility to upload and uninstall plugins, for security
|
||||
// enable support for plain php pages in admin panel, for security
|
||||
// existing pages still will be working, so you need to delete them manually
|
||||
'admin_pages_php_enable' => 'no',
|
||||
'admin_panel_modules' => 'statistics,web_status,server_status,lastlogin,created,points,coins,balance', // default - statistics,web_status,server_status,lastlogin,created,points,coins,balance
|
||||
|
||||
// other
|
||||
|
9
cypress.config.js
Normal file
9
cypress.config.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { defineConfig } = require("cypress");
|
||||
|
||||
module.exports = defineConfig({
|
||||
e2e: {
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
},
|
||||
},
|
||||
});
|
75
cypress/e2e/1-install.cy.js
Normal file
75
cypress/e2e/1-install.cy.js
Normal file
@@ -0,0 +1,75 @@
|
||||
describe('Install MyAAC', () => {
|
||||
beforeEach(() => {
|
||||
// Cypress starts out with a blank slate for each test
|
||||
// so we must tell it to visit our website with the `cy.visit()` command.
|
||||
// Since we want to visit the same URL at the start of all our tests,
|
||||
// we include it in our beforeEach function so that it runs before each test
|
||||
cy.visit(Cypress.env('URL'))
|
||||
})
|
||||
|
||||
it('Go through installer', () => {
|
||||
cy.visit(Cypress.env('URL') + '/install/?step=welcome')
|
||||
cy.wait(1000)
|
||||
|
||||
cy.screenshot('install-welcome')
|
||||
|
||||
// step 1 - Welcome
|
||||
cy.get('select[name="lang"]').select('en')
|
||||
|
||||
//cy.get('input[type=button]').contains('Next »').click()
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
// step 2 - License
|
||||
// just skip
|
||||
cy.contains('GNU/GPL License');
|
||||
cy.get('form').submit()
|
||||
|
||||
// step 3 - Requirements
|
||||
cy.contains('Requirements check');
|
||||
|
||||
cy.get('#step').then(elem => {
|
||||
elem.val('config');
|
||||
});
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
// step 4 - Configuration
|
||||
cy.contains('Basic configuration');
|
||||
|
||||
cy.get('#vars_server_path').click().clear().type(Cypress.env('SERVER_PATH'))
|
||||
cy.get('#vars_mail_admin').click().clear().type('noone@example.net')
|
||||
|
||||
cy.get('[type="checkbox"]').uncheck() // usage statistics uncheck
|
||||
|
||||
cy.wait(1000)
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
// check if there is any error
|
||||
|
||||
|
||||
// step 5 - Import Schema
|
||||
cy.contains('Import MySQL schema');
|
||||
|
||||
// AAC is not installed yet, this message should not come
|
||||
cy.contains('Seems AAC is already installed. Skipping importing MySQL schema..').should('not.exist')
|
||||
|
||||
cy.contains('[class="alert alert-success"]', 'Local configuration has been saved into file: config.local.php').should('be.visible')
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
// step 6 - Admin Account
|
||||
cy.get('#vars_email').click().clear().type('admin@my-aac.org')
|
||||
cy.get('#vars_account').click().clear().type('admin')
|
||||
cy.get('#vars_password').click().clear().type('test1234')
|
||||
cy.get('#vars_password_confirm').click().clear().type('test1234')
|
||||
cy.get('#vars_player_name').click().clear().type('Admin')
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 30000 }).should('be.visible')
|
||||
|
||||
cy.screenshot('install-finish')
|
||||
})
|
||||
})
|
33
cypress/e2e/2-create-account.cy.js
Normal file
33
cypress/e2e/2-create-account.cy.js
Normal file
@@ -0,0 +1,33 @@
|
||||
describe('Create Account Page', () => {
|
||||
beforeEach(() => {
|
||||
// Cypress starts out with a blank slate for each test
|
||||
// so we must tell it to visit our website with the `cy.visit()` command.
|
||||
// Since we want to visit the same URL at the start of all our tests,
|
||||
// we include it in our beforeEach function so that it runs before each test
|
||||
cy.visit(Cypress.env('URL') + '/index.php/account/create')
|
||||
})
|
||||
|
||||
it('Create Test Account', () => {
|
||||
cy.screenshot('create-account-page')
|
||||
|
||||
cy.get('#account_input').type('tester')
|
||||
cy.get('#email').type('tester@example.com')
|
||||
|
||||
cy.get('#password').type('test1234')
|
||||
cy.get('#password2').type('test1234')
|
||||
|
||||
cy.get('#character_name').type('Slaw')
|
||||
|
||||
cy.get('#sex1').check()
|
||||
cy.get('#vocation1').check()
|
||||
cy.get('#accept_rules').check()
|
||||
|
||||
cy.get('#createaccount').submit()
|
||||
|
||||
// no errors please
|
||||
cy.contains('The Following Errors Have Occurred:').should('not.exist')
|
||||
|
||||
// ss of post page
|
||||
cy.screenshot('create-account-page-post')
|
||||
})
|
||||
})
|
5
cypress/fixtures/example.json
Normal file
5
cypress/fixtures/example.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
25
cypress/support/commands.js
Normal file
25
cypress/support/commands.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
20
cypress/support/e2e.js
Normal file
20
cypress/support/e2e.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/e2e.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
@@ -1,4 +1,4 @@
|
||||
SET @myaac_database_version = 33;
|
||||
SET @myaac_database_version = 35;
|
||||
|
||||
CREATE TABLE `myaac_account_actions`
|
||||
(
|
||||
@@ -203,6 +203,7 @@ CREATE TABLE `myaac_monsters` (
|
||||
`mana` int(11) NOT NULL DEFAULT 0,
|
||||
`exp` int(11) NOT NULL,
|
||||
`health` int(11) NOT NULL,
|
||||
`look` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`speed_lvl` int(11) NOT NULL default 1,
|
||||
`use_haste` tinyint(1) NOT NULL,
|
||||
`voices` text NOT NULL,
|
||||
@@ -330,6 +331,7 @@ CREATE TABLE `myaac_visitors`
|
||||
`ip` VARCHAR(45) NOT NULL,
|
||||
`lastvisit` INT(11) NOT NULL DEFAULT 0,
|
||||
`page` VARCHAR(2048) NOT NULL,
|
||||
`user_agent` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
UNIQUE (`ip`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):<br/><br/><span class="console">chown -R www-data.www-data /var/www/*</span><br/><span class="console">chmod -R 660 system/cache</span>
|
||||
We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):<br/><br/><span class="console">chown -R www-data.www-data /var/www/*</span><br/><span class="console">chmod -R 760 system/cache</span>
|
||||
|
||||
<style type="text/css">
|
||||
.console {
|
||||
|
@@ -26,13 +26,13 @@ $twig = new Twig_Environment($twig_loader, array(
|
||||
));
|
||||
|
||||
// load installation status
|
||||
$step = isset($_POST['step']) ? $_POST['step'] : 'welcome';
|
||||
$step = $_REQUEST['step'] ?? 'welcome';
|
||||
|
||||
$install_status = array();
|
||||
if(file_exists(CACHE . 'install.txt')) {
|
||||
$install_status = unserialize(file_get_contents(CACHE . 'install.txt'));
|
||||
|
||||
if(!isset($_POST['step'])) {
|
||||
if(!isset($_REQUEST['step'])) {
|
||||
$step = isset($install_status['step']) ? $install_status['step'] : '';
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ if($step == 'database') {
|
||||
|
||||
$key = str_replace('var_', '', $key);
|
||||
|
||||
if(in_array($key, array('account', 'password', 'password_confirm', 'email', 'player_name'))) {
|
||||
if(in_array($key, array('account', 'account_id', 'password', 'password_confirm', 'email', 'player_name'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -110,14 +110,12 @@ if($step == 'database') {
|
||||
}
|
||||
}
|
||||
else if($step == 'admin') {
|
||||
$config_failed = true;
|
||||
if(file_exists(BASE . 'config.local.php') && isset($config['installed']) && $config['installed'] && isset($_SESSION['saved'])) {
|
||||
$config_failed = false;
|
||||
}
|
||||
|
||||
if($config_failed) {
|
||||
if(!file_exists(BASE . 'config.local.php') || !isset($config['installed']) || !$config['installed']) {
|
||||
$step = 'database';
|
||||
}
|
||||
else {
|
||||
$_SESSION['saved'] = true;
|
||||
}
|
||||
}
|
||||
else if($step == 'finish') {
|
||||
$email = $_SESSION['var_email'];
|
||||
|
@@ -55,12 +55,30 @@ if(!$error) {
|
||||
error($database_error);
|
||||
}
|
||||
else {
|
||||
$twig->display('install.installer.html.twig', array(
|
||||
'url' => 'tools/5-database.php',
|
||||
'message' => $locale['loading_spinner']
|
||||
));
|
||||
if(!$db->hasTable('accounts')) {
|
||||
$tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
|
||||
error($tmp);
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if(!$db->hasTable('players')) {
|
||||
$tmp = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
|
||||
error($tmp);
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if(!$db->hasTable('guilds')) {
|
||||
$tmp = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
|
||||
error($tmp);
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if(!$error) {
|
||||
$twig->display('install.installer.html.twig', array(
|
||||
'url' => 'tools/5-database.php',
|
||||
'message' => $locale['loading_spinner']
|
||||
));
|
||||
|
||||
if(!Validator::email($_SESSION['var_mail_admin'])) {
|
||||
error($locale['step_config_mail_admin_error']);
|
||||
$error = true;
|
||||
@@ -86,7 +104,7 @@ if(!$error) {
|
||||
unset($_SESSION['saved']);
|
||||
|
||||
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
|
||||
warning($locale['step_database_error_file'] . '<br/>
|
||||
error($locale['step_database_error_file'] . '<br/>
|
||||
<textarea cols="70" rows="10">' . $content . '</textarea>');
|
||||
}
|
||||
}
|
||||
@@ -98,7 +116,7 @@ if(!$error) {
|
||||
<div class="text-center m-3">
|
||||
<form action="<?php echo BASE_URL; ?>install/" method="post">
|
||||
<input type="hidden" name="step" id="step" value="admin" />
|
||||
<?php echo next_buttons(true, $error ? false : true);
|
||||
<?php echo next_buttons(true, !$error);
|
||||
?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -8,7 +8,7 @@ if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['save
|
||||
else {
|
||||
require SYSTEM . 'init.php';
|
||||
if(!$error) {
|
||||
if(USE_ACCOUNT_NAME)
|
||||
if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER)
|
||||
$account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null;
|
||||
else
|
||||
$account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null;
|
||||
@@ -65,7 +65,6 @@ else {
|
||||
$new_account->setPassword(encrypt($password));
|
||||
$new_account->setEMail($email);
|
||||
|
||||
$new_account->unblock();
|
||||
$new_account->save();
|
||||
|
||||
$new_account->setCustomField('created', time());
|
||||
|
@@ -4,14 +4,14 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>MyAAC - <?php echo $locale['installation']; ?></title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
||||
<link rel="stylesheet" type="text/css" href="template/style.css" />
|
||||
<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/js/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="body" class="container">
|
||||
|
||||
|
||||
<header id="header" class="pt-5 pb-4 pb-sm-5">
|
||||
<h1>MyAAC <?php echo $locale['installation']; ?></h1>
|
||||
</header>
|
||||
@@ -28,10 +28,10 @@
|
||||
if ($step == $value) {
|
||||
$progress = ($i == 6) ? 100 : $i * 16;
|
||||
}
|
||||
|
||||
echo '<li' . ($step == $value ? ' class="list-group-item active"' : ' class="list-group-item"') . '>' . ++$i . '. ' . $locale['step_' . $value] . '</li>';
|
||||
|
||||
echo '<li class="list-group-item' . ($step == $value ? ' active' : '') . '">' . ++$i . '. ' . $locale['step_' . $value] . '</li>';
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -71,4 +71,4 @@
|
||||
<p style="text-align: center;"><?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?></p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@@ -23,24 +23,6 @@ if(!$error) {
|
||||
}
|
||||
}
|
||||
|
||||
if(!$db->hasTable('accounts')) {
|
||||
$locale['step_database_error_table'] = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
|
||||
error($locale['step_database_error_table']);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$db->hasTable('players')) {
|
||||
$locale['step_database_error_table'] = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
|
||||
error($locale['step_database_error_table']);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$db->hasTable('guilds')) {
|
||||
$locale['step_database_error_table'] = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
|
||||
error($locale['step_database_error_table']);
|
||||
return;
|
||||
}
|
||||
|
||||
if($db->hasTable(TABLE_PREFIX . 'account_actions')) {
|
||||
$locale['step_database_error_table_exist'] = str_replace('$TABLE$', TABLE_PREFIX . 'account_actions', $locale['step_database_error_table_exist']);
|
||||
warning($locale['step_database_error_table_exist']);
|
||||
@@ -73,13 +55,8 @@ else {
|
||||
success($locale['step_database_adding_field'] . ' accounts.key...');
|
||||
}
|
||||
|
||||
if(!$db->hasColumn('accounts', 'blocked')) {
|
||||
if(query("ALTER TABLE `accounts` ADD `blocked` TINYINT(1) NOT NULL DEFAULT FALSE COMMENT 'internal usage' AFTER `key`;"))
|
||||
success($locale['step_database_adding_field'] . ' accounts.blocked...');
|
||||
}
|
||||
|
||||
if(!$db->hasColumn('accounts', 'created')) {
|
||||
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'blocked') . "`;"))
|
||||
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'key') . "`;"))
|
||||
success($locale['step_database_adding_field'] . ' accounts.created...');
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,23 @@ server {
|
||||
# increase max file upload
|
||||
client_max_body_size 10M;
|
||||
|
||||
# this is very important, be sure its in your nginx conf - it prevents access to logs etc.
|
||||
location ~ /system {
|
||||
deny all;
|
||||
return 404;
|
||||
}
|
||||
|
||||
# block .htaccess
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# block git files and folders
|
||||
location ~ /\.git {
|
||||
return 404;
|
||||
deny all;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php;
|
||||
}
|
||||
@@ -15,15 +32,6 @@ server {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_read_timeout 240;
|
||||
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
# for ubuntu 22.04+ it will be php8.1-sock
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location /system {
|
||||
deny all;
|
||||
return 404;
|
||||
# for ubuntu 22.04+ it will be php8.1-fpm.-sock
|
||||
}
|
||||
}
|
||||
|
1927
package-lock.json
generated
Normal file
1927
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
package.json
Normal file
5
package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"cypress": "^12.12.0"
|
||||
}
|
||||
}
|
@@ -1,11 +1,3 @@
|
||||
<IfModule mod_autoindex.c>
|
||||
Options -Indexes
|
||||
</IfModule>
|
||||
|
||||
<IfVersion < 2.4>
|
||||
order allow,deny
|
||||
deny from all
|
||||
</IfVersion>
|
||||
<IfVersion >= 2.4>
|
||||
Require all denied
|
||||
</IfVersion>
|
||||
|
@@ -1,3 +1,3 @@
|
||||
To play on {{ config.lua.serverName }} you need an account.
|
||||
All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if config.recaptcha_enabled %}, confirm reCAPTCHA{% endif %}{% if config.account_country %}, country{% endif %} and your email address.
|
||||
All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if config.account_country %}, country{% endif %} and your email address.
|
||||
Also you have to agree to the terms presented below. If you have done so, your account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %} will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.<br/><br/>
|
||||
|
@@ -22,7 +22,7 @@ if [ $1 = "prepare" ]; then
|
||||
mkdir -p tmp
|
||||
|
||||
# get myaac from git archive
|
||||
git archive --format zip --output tmp/myaac.zip master
|
||||
git archive --format zip --output tmp/myaac.zip 0.9
|
||||
|
||||
cd tmp/ || exit
|
||||
|
||||
@@ -35,6 +35,11 @@ if [ $1 = "prepare" ]; then
|
||||
unzip -q myaac.zip -d $dir
|
||||
rm myaac.zip
|
||||
|
||||
cd $dir || exit
|
||||
|
||||
# dependencies
|
||||
composer install
|
||||
|
||||
echo "Now you can make changes to $dir. When you are ready, type 'release.sh pack'"
|
||||
exit
|
||||
fi
|
||||
@@ -62,4 +67,4 @@ if [ $1 = "pack" ]; then
|
||||
echo "Done. Released files can be found in 'releases' directory."
|
||||
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
@@ -1,206 +0,0 @@
|
||||
<?php
|
||||
namespace MyAAC;
|
||||
|
||||
$loader = new \MyAAC\Psr4AutoloaderClass;
|
||||
|
||||
// register the autoloader
|
||||
$loader->register();
|
||||
|
||||
// register the base directories for the namespace prefix
|
||||
$loader->addNamespace('Composer\Semver', LIBS . 'semver');
|
||||
$loader->addNamespace('Twig', LIBS . 'Twig');
|
||||
/**
|
||||
* An example of a general-purpose implementation that includes the optional
|
||||
* functionality of allowing multiple base directories for a single namespace
|
||||
* prefix.
|
||||
*
|
||||
* Given a foo-bar package of classes in the file system at the following
|
||||
* paths ...
|
||||
*
|
||||
* /path/to/packages/foo-bar/
|
||||
* src/
|
||||
* Baz.php # Foo\Bar\Baz
|
||||
* Qux/
|
||||
* Quux.php # Foo\Bar\Qux\Quux
|
||||
* tests/
|
||||
* BazTest.php # Foo\Bar\BazTest
|
||||
* Qux/
|
||||
* QuuxTest.php # Foo\Bar\Qux\QuuxTest
|
||||
*
|
||||
* ... add the path to the class files for the \Foo\Bar\ namespace prefix
|
||||
* as follows:
|
||||
*
|
||||
* <?php
|
||||
* // instantiate the loader
|
||||
* $loader = new \Example\Psr4AutoloaderClass;
|
||||
*
|
||||
* // register the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // register the base directories for the namespace prefix
|
||||
* $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
|
||||
* $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
|
||||
*
|
||||
* The following line would cause the autoloader to attempt to load the
|
||||
* \Foo\Bar\Qux\Quux class from /path/to/packages/foo-bar/src/Qux/Quux.php:
|
||||
*
|
||||
* <?php
|
||||
* new \Foo\Bar\Qux\Quux;
|
||||
*
|
||||
* The following line would cause the autoloader to attempt to load the
|
||||
* \Foo\Bar\Qux\QuuxTest class from /path/to/packages/foo-bar/tests/Qux/QuuxTest.php:
|
||||
*
|
||||
* <?php
|
||||
* new \Foo\Bar\Qux\QuuxTest;
|
||||
*/
|
||||
class Psr4AutoloaderClass
|
||||
{
|
||||
/**
|
||||
* An associative array where the key is a namespace prefix and the value
|
||||
* is an array of base directories for classes in that namespace.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $prefixes = array();
|
||||
|
||||
/**
|
||||
* Register loader with SPL autoloader stack.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a base directory for a namespace prefix.
|
||||
*
|
||||
* @param string $prefix The namespace prefix.
|
||||
* @param string $base_dir A base directory for class files in the
|
||||
* namespace.
|
||||
* @param bool $prepend If true, prepend the base directory to the stack
|
||||
* instead of appending it; this causes it to be searched first rather
|
||||
* than last.
|
||||
* @return void
|
||||
*/
|
||||
public function addNamespace($prefix, $base_dir, $prepend = false)
|
||||
{
|
||||
// normalize namespace prefix
|
||||
$prefix = trim($prefix, '\\') . '\\';
|
||||
|
||||
// normalize the base directory with a trailing separator
|
||||
$base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';
|
||||
|
||||
// initialize the namespace prefix array
|
||||
if (isset($this->prefixes[$prefix]) === false) {
|
||||
$this->prefixes[$prefix] = array();
|
||||
}
|
||||
|
||||
// retain the base directory for the namespace prefix
|
||||
if ($prepend) {
|
||||
array_unshift($this->prefixes[$prefix], $base_dir);
|
||||
} else {
|
||||
array_push($this->prefixes[$prefix], $base_dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the class file for a given class name.
|
||||
*
|
||||
* @param string $class The fully-qualified class name.
|
||||
* @return mixed The mapped file name on success, or boolean false on
|
||||
* failure.
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if (0 === strpos($class, 'Twig_')) {
|
||||
$file = LIBS . 'Twig/' . str_replace(array('_', "\0"), array('/', ''), $class).'.php';
|
||||
|
||||
if((config('env') === 'dev') && !is_file($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
require $file;
|
||||
return false;
|
||||
}
|
||||
|
||||
// the current namespace prefix
|
||||
$prefix = $class;
|
||||
|
||||
// work backwards through the namespace names of the fully-qualified
|
||||
// class name to find a mapped file name
|
||||
while (false !== $pos = strrpos($prefix, '\\')) {
|
||||
|
||||
// retain the trailing namespace separator in the prefix
|
||||
$prefix = substr($class, 0, $pos + 1);
|
||||
|
||||
// the rest is the relative class name
|
||||
$relative_class = substr($class, $pos + 1);
|
||||
|
||||
// try to load a mapped file for the prefix and relative class
|
||||
$mapped_file = $this->loadMappedFile($prefix, $relative_class);
|
||||
if ($mapped_file) {
|
||||
return $mapped_file;
|
||||
}
|
||||
|
||||
// remove the trailing namespace separator for the next iteration
|
||||
// of strrpos()
|
||||
$prefix = rtrim($prefix, '\\');
|
||||
}
|
||||
|
||||
// never found a mapped file
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the mapped file for a namespace prefix and relative class.
|
||||
*
|
||||
* @param string $prefix The namespace prefix.
|
||||
* @param string $relative_class The relative class name.
|
||||
* @return mixed Boolean false if no mapped file can be loaded, or the
|
||||
* name of the mapped file that was loaded.
|
||||
*/
|
||||
protected function loadMappedFile($prefix, $relative_class)
|
||||
{
|
||||
// are there any base directories for this namespace prefix?
|
||||
if (isset($this->prefixes[$prefix]) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// look through base directories for this namespace prefix
|
||||
foreach ($this->prefixes[$prefix] as $base_dir) {
|
||||
|
||||
// replace the namespace prefix with the base directory,
|
||||
// replace namespace separators with directory separators
|
||||
// in the relative class name, append with .php
|
||||
$file = $base_dir
|
||||
. str_replace('\\', '/', $relative_class)
|
||||
. '.php';
|
||||
|
||||
// if the mapped file exists, require it
|
||||
if ($this->requireFile($file)) {
|
||||
// yes, we're done
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// never found it
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a file exists, require it from the file system.
|
||||
*
|
||||
* @param string $file The file to require.
|
||||
* @return bool True if the file exists, false if not.
|
||||
*/
|
||||
protected function requireFile($file)
|
||||
{
|
||||
if (config('env') !== 'dev' || file_exists($file)) {
|
||||
require $file;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,4 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception handler
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2023 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
|
||||
if (class_exists(\Whoops\Run::class)) {
|
||||
$whoops = new \Whoops\Run;
|
||||
if(IS_CLI) {
|
||||
$whoops->pushHandler(new \Whoops\Handler\PlainTextHandler);
|
||||
}
|
||||
else {
|
||||
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
|
||||
}
|
||||
|
||||
$whoops->register();
|
||||
return;
|
||||
}
|
||||
|
||||
require LIBS . 'SensitiveException.php';
|
||||
|
||||
@@ -23,6 +44,8 @@ function exception_handler($exception) {
|
||||
|
||||
$backtrace_formatted = nl2br($exception->getTraceAsString());
|
||||
|
||||
$message = $message . "<br/><br/>File: {$exception->getFile()}<br/>Line: {$exception->getLine()}";
|
||||
|
||||
// display basic error message without template
|
||||
// template is missing, why? probably someone deleted templates dir, or it wasn't downloaded right
|
||||
$template_file = SYSTEM . 'templates/exception.html.twig';
|
||||
|
@@ -7,12 +7,11 @@
|
||||
* @copyright 2019 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use Twig\Loader\ArrayLoader as Twig_ArrayLoader;
|
||||
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
function message($message, $type, $return)
|
||||
{
|
||||
if(IS_CLI) {
|
||||
@@ -126,14 +125,13 @@ function getHouseLink($name, $generate = true)
|
||||
|
||||
function getGuildLink($name, $generate = true)
|
||||
{
|
||||
global $db, $config;
|
||||
global $config;
|
||||
|
||||
if(is_numeric($name))
|
||||
{
|
||||
$guild = $db->query(
|
||||
'SELECT `name` FROM `guilds` WHERE `id` = ' . (int)$name);
|
||||
if($guild->rowCount() > 0)
|
||||
$name = $guild->fetchColumn();
|
||||
if(is_numeric($name)) {
|
||||
$name = getGuildNameById($name);
|
||||
if ($name === false) {
|
||||
$name = 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
$url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'guilds/' . urlencode($name);
|
||||
@@ -756,10 +754,10 @@ function get_browser_languages()
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
$acceptLang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
||||
if(!isset($acceptLang[0]))
|
||||
if(empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
|
||||
return $ret;
|
||||
|
||||
$acceptLang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
||||
$languages = strtolower($acceptLang);
|
||||
// $languages = 'pl,en-us;q=0.7,en;q=0.3 ';
|
||||
// need to remove spaces from strings to avoid error
|
||||
@@ -792,16 +790,21 @@ function get_templates()
|
||||
* Generates list of installed plugins
|
||||
* @return array $plugins
|
||||
*/
|
||||
function get_plugins()
|
||||
function get_plugins($disabled = false): array
|
||||
{
|
||||
$ret = array();
|
||||
$ret = [];
|
||||
|
||||
$path = PLUGINS;
|
||||
foreach(scandir($path, 0) as $file) {
|
||||
foreach(scandir($path, SCANDIR_SORT_ASCENDING) as $file) {
|
||||
$file_ext = pathinfo($file, PATHINFO_EXTENSION);
|
||||
$file_name = pathinfo($file, PATHINFO_FILENAME);
|
||||
if ($file === '.' || $file === '..' || $file === 'disabled' || $file === 'example.json' || $file_ext !== 'json' || is_dir($path . $file))
|
||||
if ($file === '.' || $file === '..' || $file === 'example.json' || $file_ext !== 'json' || is_dir($path . $file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$disabled && strpos($file, 'disabled.') !== false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ret[] = str_replace('.json', '', $file_name);
|
||||
}
|
||||
@@ -1189,7 +1192,7 @@ function getCustomPageInfo($page)
|
||||
|
||||
return null;
|
||||
}
|
||||
function getCustomPage($page, &$success)
|
||||
function getCustomPage($page, &$success): string
|
||||
{
|
||||
global $db, $twig, $title, $ignore, $logged_access;
|
||||
|
||||
@@ -1544,6 +1547,39 @@ function escapeHtml($html) {
|
||||
return htmlentities($html, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
}
|
||||
|
||||
function getGuildNameById($id)
|
||||
{
|
||||
global $db;
|
||||
|
||||
$guild = $db->query('SELECT `name` FROM `guilds` WHERE `id` = ' . (int)$id);
|
||||
|
||||
if($guild->rowCount() > 0) {
|
||||
return $guild->fetchColumn();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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'];
|
||||
|
||||
if (!empty($guildLogo) && file_exists(GUILD_IMAGES_DIR . $guildLogo)) {
|
||||
$logo = $guildLogo;
|
||||
}
|
||||
}
|
||||
|
||||
return BASE_URL . GUILD_IMAGES_DIR . $logo;
|
||||
}
|
||||
|
||||
// validator functions
|
||||
require_once LIBS . 'validator.php';
|
||||
require_once SYSTEM . 'compat/base.php';
|
||||
|
@@ -30,6 +30,7 @@ define('HOOK_CHARACTERS_AFTER_CHARACTERS', ++$i);
|
||||
define('HOOK_LOGIN', ++$i);
|
||||
define('HOOK_LOGIN_ATTEMPT', ++$i);
|
||||
define('HOOK_LOGOUT', ++$i);
|
||||
define('HOOK_ACCOUNT_CHANGE_PASSWORD_POST', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BEFORE_FORM', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BEFORE_BOXES', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1', ++$i);
|
||||
@@ -39,8 +40,8 @@ define('HOOK_ACCOUNT_CREATE_BEFORE_ACCOUNT', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_ACCOUNT', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_EMAIL', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_COUNTRY', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_PASSWORD', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_PASSWORDS', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_RECAPTCHA', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BEFORE_CHARACTER_NAME', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_CHARACTER_NAME', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_SEX', ++$i);
|
||||
@@ -48,11 +49,30 @@ define('HOOK_ACCOUNT_CREATE_AFTER_VOCATION', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_TOWNS', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BEFORE_SUBMIT_BUTTON', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_FORM', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_SUBMIT', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_POST', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_BEFORE_PAGE', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_BEFORE_ACCOUNT', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_AFTER_ACCOUNT', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_BEFORE_PASSWORD', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_AFTER_PASSWORD', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_AFTER_REMEMBER_ME', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_AFTER_PAGE', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_POST', ++$i);
|
||||
define('HOOK_ADMIN_HEAD_END', ++$i);
|
||||
define('HOOK_ADMIN_HEAD_START', ++$i);
|
||||
define('HOOK_ADMIN_BODY_START', ++$i);
|
||||
define('HOOK_ADMIN_BODY_END', ++$i);
|
||||
define('HOOK_ADMIN_BEFORE_PAGE', ++$i);
|
||||
define('HOOK_ADMIN_MENU', ++$i);
|
||||
define('HOOK_ADMIN_LOGIN_AFTER_ACCOUNT', ++$i);
|
||||
define('HOOK_ADMIN_LOGIN_AFTER_PASSWORD', ++$i);
|
||||
define('HOOK_ADMIN_LOGIN_AFTER_SIGN_IN', ++$i);
|
||||
define('HOOK_ADMIN_ACCOUNTS_SAVE_POST', ++$i);
|
||||
define('HOOK_EMAIL_CONFIRMED', ++$i);
|
||||
define('HOOK_FIRST', HOOK_STARTUP);
|
||||
define('HOOK_LAST', HOOK_EMAIL_CONFIRMED);
|
||||
define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i);
|
||||
|
||||
const HOOK_FIRST = HOOK_STARTUP;
|
||||
define('HOOK_LAST', $i);
|
||||
|
||||
require_once LIBS . 'plugins.php';
|
||||
class Hook
|
||||
|
@@ -18,6 +18,10 @@ if(!isset($config['installed']) || !$config['installed']) {
|
||||
throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.');
|
||||
}
|
||||
|
||||
if(config('env') === 'dev') {
|
||||
require SYSTEM . 'exception.php';
|
||||
}
|
||||
|
||||
date_default_timezone_set($config['date_timezone']);
|
||||
// take care of trailing slash at the end
|
||||
if($config['server_path'][strlen($config['server_path']) - 1] !== '/')
|
||||
|
@@ -251,10 +251,12 @@ class CreateCharacter
|
||||
}
|
||||
}
|
||||
|
||||
$loaded_items_to_copy = $db->query("SELECT * FROM player_items WHERE player_id = ".$char_to_copy->getId()."");
|
||||
foreach($loaded_items_to_copy as $save_item) {
|
||||
$blob = $db->quote($save_item['attributes']);
|
||||
$db->query("INSERT INTO `player_items` (`player_id` ,`pid` ,`sid` ,`itemtype`, `count`, `attributes`) VALUES ('".$player->getId()."', '".$save_item['pid']."', '".$save_item['sid']."', '".$save_item['itemtype']."', '".$save_item['count']."', $blob);");
|
||||
if ($db->hasTable('player_items') && $db->hasColumn('player_items', 'pid') && $db->hasColumn('player_items', 'sid') && $db->hasColumn('player_items', 'itemtype')) {
|
||||
$loaded_items_to_copy = $db->query("SELECT * FROM player_items WHERE player_id = ".$char_to_copy->getId()."");
|
||||
foreach($loaded_items_to_copy as $save_item) {
|
||||
$blob = $db->quote($save_item['attributes']);
|
||||
$db->query("INSERT INTO `player_items` (`player_id` ,`pid` ,`sid` ,`itemtype`, `count`, `attributes`) VALUES ('".$player->getId()."', '".$save_item['pid']."', '".$save_item['sid']."', '".$save_item['itemtype']."', '".$save_item['count']."', $blob);");
|
||||
}
|
||||
}
|
||||
|
||||
global $twig;
|
||||
|
@@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
class GoogleReCAPTCHA
|
||||
{
|
||||
private static $errorMessage = '';
|
||||
private static $errorType;
|
||||
|
||||
const ERROR_MISSING_RESPONSE = 1;
|
||||
const ERROR_INVALID_ACTION = 2;
|
||||
const ERROR_LOW_SCORE = 3;
|
||||
const ERROR_NO_SUCCESS = 4;
|
||||
|
||||
public static function verify($action = '')
|
||||
{
|
||||
if (!isset($_POST['g-recaptcha-response']) || empty($_POST['g-recaptcha-response'])) {
|
||||
self::$errorType = self::ERROR_MISSING_RESPONSE;
|
||||
self::$errorMessage = "Please confirm that you're not a robot.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$recaptchaApiUrl = 'https://www.google.com/recaptcha/api/siteverify';
|
||||
$secretKey = config('recaptcha_secret_key');
|
||||
|
||||
$recaptchaResponse = $_POST['g-recaptcha-response'];
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$params = 'secret='.$secretKey.'&response='.$recaptchaResponse.'&remoteip='.$ip;
|
||||
|
||||
if (function_exists('curl_version')) {
|
||||
$curl_connection = curl_init($recaptchaApiUrl);
|
||||
|
||||
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 0);
|
||||
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $params);
|
||||
|
||||
$response = curl_exec($curl_connection);
|
||||
curl_close($curl_connection);
|
||||
} else {
|
||||
$response = file_get_contents($recaptchaApiUrl . '?' . $params);
|
||||
}
|
||||
|
||||
$json = json_decode($response);
|
||||
|
||||
$recaptchaType = config('recaptcha_type');
|
||||
if ($recaptchaType === 'v3') { // score based
|
||||
//log_append('recaptcha.log', 'recaptcha_score: ' . $json->score . ', action:' . $json->action);
|
||||
|
||||
if (!isset($json->action) || $json->action !== $action) {
|
||||
self::$errorType = self::ERROR_INVALID_ACTION;
|
||||
self::$errorMessage = 'Google ReCaptcha returned invalid action.';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($json->score) || $json->score < config('recaptcha_v3_min_score')) {
|
||||
self::$errorType = self::ERROR_LOW_SCORE;
|
||||
self::$errorMessage = 'Your Google ReCaptcha score was too low.';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($json->success) || !$json->success) {
|
||||
self::$errorType = self::ERROR_NO_SUCCESS;
|
||||
self::$errorMessage = "Please confirm that you're not a robot.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getErrorMessage() {
|
||||
return self::$errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public static function getErrorType() {
|
||||
return self::$errorType;
|
||||
}
|
||||
}
|
@@ -110,4 +110,21 @@ class Cache
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled() {return false;}
|
||||
|
||||
public static function remember($key, $ttl, $callback)
|
||||
{
|
||||
$cache = self::getInstance();
|
||||
if(!$cache->enabled()) {
|
||||
return $callback();
|
||||
}
|
||||
|
||||
$value = null;
|
||||
if ($cache->fetch($key, $value)) {
|
||||
return unserialize($value);
|
||||
}
|
||||
|
||||
$value = $callback();
|
||||
$cache->set($key, serialize($value),$ttl);
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
@@ -82,6 +82,9 @@ class Creatures {
|
||||
$armor = $monster->getArmor();
|
||||
$defensev = $monster->getDefense();
|
||||
|
||||
//load look
|
||||
$look = $monster->getLook();
|
||||
|
||||
//load monster flags
|
||||
$flags = $monster->getFlags();
|
||||
if(!isset($flags['summonable']))
|
||||
@@ -147,6 +150,7 @@ class Creatures {
|
||||
'armor' => $armor,
|
||||
'race' => $race,
|
||||
'loot' => json_encode($loot),
|
||||
'look' => json_encode($look),
|
||||
'summons' => json_encode($summons)
|
||||
));
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) {
|
||||
function is_sub_dir($path = NULL, $parent_folder = BASE) {
|
||||
|
||||
//Get directory path minus last folder
|
||||
$dir = dirname($path);
|
||||
@@ -41,9 +41,9 @@ function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) {
|
||||
use Composer\Semver\Semver;
|
||||
|
||||
class Plugins {
|
||||
private static $warnings = array();
|
||||
private static $warnings = [];
|
||||
private static $error = null;
|
||||
private static $plugin_json = array();
|
||||
private static $plugin_json = [];
|
||||
|
||||
public static function getRoutes()
|
||||
{
|
||||
@@ -56,22 +56,8 @@ class Plugins {
|
||||
}
|
||||
|
||||
$routes = [];
|
||||
foreach(get_plugins() as $filename) {
|
||||
$string = file_get_contents(PLUGINS . $filename . '.json');
|
||||
$string = self::removeComments($string);
|
||||
$plugin = json_decode($string, true);
|
||||
self::$plugin_json = $plugin;
|
||||
if ($plugin == null) {
|
||||
self::$warnings[] = 'Cannot load ' . $filename . '.json. File might be not a valid json code.';
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isset($plugin['enabled']) && !getBoolean($plugin['enabled'])) {
|
||||
self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.';
|
||||
continue;
|
||||
}
|
||||
|
||||
$warningPreTitle = 'Plugin: ' . $filename . ' - ';
|
||||
foreach(self::getAllPluginsJson() as $plugin) {
|
||||
$warningPreTitle = 'Plugin: ' . $plugin['name'] . ' - ';
|
||||
|
||||
if (isset($plugin['routes'])) {
|
||||
foreach ($plugin['routes'] as $_name => $info) {
|
||||
@@ -80,7 +66,8 @@ class Plugins {
|
||||
if ($method !== '*') {
|
||||
$methods = is_string($method) ? explode(',', $info['method']) : $method;
|
||||
foreach ($methods as $method) {
|
||||
if (!in_array($method, ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'])) {
|
||||
$method = strtolower($method);
|
||||
if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'head'])) {
|
||||
self::$warnings[] = $warningPreTitle . 'Not allowed method ' . $method . '... Disabling this route...';
|
||||
}
|
||||
}
|
||||
@@ -161,28 +148,14 @@ class Plugins {
|
||||
}
|
||||
|
||||
$hooks = [];
|
||||
foreach(get_plugins() as $filename) {
|
||||
$string = file_get_contents(PLUGINS . $filename . '.json');
|
||||
$string = self::removeComments($string);
|
||||
$plugin = json_decode($string, true);
|
||||
self::$plugin_json = $plugin;
|
||||
if ($plugin == null) {
|
||||
self::$warnings[] = 'Cannot load ' . $filename . '.json. File might be not a valid json code.';
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isset($plugin['enabled']) && !getBoolean($plugin['enabled'])) {
|
||||
self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.';
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach(self::getAllPluginsJson() as $plugin) {
|
||||
if (isset($plugin['hooks'])) {
|
||||
foreach ($plugin['hooks'] as $_name => $info) {
|
||||
if (defined('HOOK_'. $info['type'])) {
|
||||
$hook = constant('HOOK_'. $info['type']);
|
||||
$hooks[] = ['name' => $_name, 'type' => $hook, 'file' => $info['file']];
|
||||
} else {
|
||||
self::$warnings[] = 'Plugin: ' . $filename . '. Unknown event type: ' . $info['type'];
|
||||
self::$warnings[] = 'Plugin: ' . $plugin['name'] . '. Unknown event type: ' . $info['type'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,6 +168,41 @@ class Plugins {
|
||||
return $hooks;
|
||||
}
|
||||
|
||||
public static function getAllPluginsJson($disabled = false)
|
||||
{
|
||||
$cache = Cache::getInstance();
|
||||
if ($cache->enabled()) {
|
||||
$tmp = '';
|
||||
if ($cache->fetch('plugins', $tmp)) {
|
||||
return unserialize($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
$plugins = [];
|
||||
foreach (get_plugins($disabled) as $filename) {
|
||||
$string = file_get_contents(PLUGINS . $filename . '.json');
|
||||
$plugin = json_decode($string, true);
|
||||
self::$plugin_json = $plugin;
|
||||
if ($plugin == null) {
|
||||
self::$warnings[] = 'Cannot load ' . $filename . '.json. File might be not a valid json code.';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($plugin['enabled']) && !getBoolean($plugin['enabled'])) {
|
||||
self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.';
|
||||
continue;
|
||||
}
|
||||
|
||||
$plugins[] = $plugin;
|
||||
}
|
||||
|
||||
if ($cache->enabled()) {
|
||||
$cache->set('plugins', serialize($plugins), 600);
|
||||
}
|
||||
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
public static function install($file) {
|
||||
global $db;
|
||||
|
||||
@@ -235,7 +243,6 @@ class Plugins {
|
||||
}
|
||||
|
||||
$string = file_get_contents($file_name);
|
||||
$string = self::removeComments($string);
|
||||
$plugin_json = json_decode($string, true);
|
||||
self::$plugin_json = $plugin_json;
|
||||
if ($plugin_json == null) {
|
||||
@@ -435,7 +442,35 @@ class Plugins {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function uninstall($plugin_name)
|
||||
public static function enable($pluginFileName): bool
|
||||
{
|
||||
return self::enableDisable($pluginFileName, true);
|
||||
}
|
||||
|
||||
public static function disable($pluginFileName): bool
|
||||
{
|
||||
return self::enableDisable($pluginFileName, false);
|
||||
}
|
||||
|
||||
private static function enableDisable($pluginFileName, $enable): bool
|
||||
{
|
||||
$filenameJson = $pluginFileName . '.json';
|
||||
$fileExist = is_file(PLUGINS . ($enable ? 'disabled.' : '') . $filenameJson);
|
||||
if (!$fileExist) {
|
||||
self::$error = 'Cannot ' . ($enable ? 'enable' : 'disable') . ' plugin: ' . $pluginFileName . '. File does not exist.';
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = rename(PLUGINS . ($enable ? 'disabled.' : '') . $filenameJson, PLUGINS . ($enable ? '' : 'disabled.') . $filenameJson);
|
||||
if (!$result) {
|
||||
self::$error = 'Cannot ' . ($enable ? 'enable' : 'disable') . ' plugin: ' . $pluginFileName . '. Permission problem.';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function uninstall($plugin_name): bool
|
||||
{
|
||||
$filename = BASE . 'plugins/' . $plugin_name . '.json';
|
||||
if(!file_exists($filename)) {
|
||||
@@ -443,9 +478,8 @@ class Plugins {
|
||||
return false;
|
||||
}
|
||||
$string = file_get_contents($filename);
|
||||
$string = self::removeComments($string);
|
||||
$plugin_info = json_decode($string, true);
|
||||
if($plugin_info == false) {
|
||||
if(!$plugin_info) {
|
||||
self::$error = 'Cannot load plugin info ' . $plugin_name . '.json';
|
||||
return false;
|
||||
}
|
||||
@@ -527,22 +561,6 @@ class Plugins {
|
||||
return self::$plugin_json;
|
||||
}
|
||||
|
||||
public static function removeComments($string) {
|
||||
$string = preg_replace('!/\*.*?\*/!s', '', $string);
|
||||
$string = preg_replace('/\n\s*\n/', "\n", $string);
|
||||
// Removes multi-line comments and does not create
|
||||
// a blank line, also treats white spaces/tabs
|
||||
$string = preg_replace('!^[ \t]*/\*.*?\*/[ \t]*[\r\n]!s', '', $string);
|
||||
|
||||
// Removes single line '//' comments, treats blank characters
|
||||
$string = preg_replace('![ \t]*//.*[ \t]*[\r\n]!', '', $string);
|
||||
|
||||
// Strip blank lines
|
||||
$string = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $string);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install menus
|
||||
* Helper function for plugins
|
||||
|
@@ -21,7 +21,6 @@
|
||||
* @property string $password Password.
|
||||
* @property string $eMail Email address.
|
||||
* @property int $premiumEnd Timestamp of PACC end.
|
||||
* @property bool $blocked Blocked flag state.
|
||||
* @property bool $deleted Deleted flag state.
|
||||
* @property bool $warned Warned flag state.
|
||||
* @property bool $banned Ban state.
|
||||
@@ -39,7 +38,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
* @var array
|
||||
* @version 0.1.5
|
||||
*/
|
||||
private $data = array('email' => '', 'blocked' => false, 'rlname' => '','location' => '', 'country' => '','web_flags' => 0, 'lastday' => 0, 'premdays' => 0, 'created' => 0);
|
||||
private $data = array('email' => '', 'rlname' => '','location' => '', 'country' => '','web_flags' => 0, 'lastday' => 0, 'premdays' => 0, 'created' => 0);
|
||||
|
||||
public static $cache = array();
|
||||
|
||||
@@ -231,26 +230,22 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
* @param int $id Account number.
|
||||
* @throws PDOException On PDO operation error.
|
||||
*/
|
||||
public function load($id, $fresh = false, $searchOnlyById = false)
|
||||
public function load($id, $fresh = false)
|
||||
{
|
||||
if(!$fresh && isset(self::$cache[$id])) {
|
||||
$this->data = self::$cache[$id];
|
||||
return;
|
||||
}
|
||||
|
||||
$numberColumn = 'id';
|
||||
$nameOrNumber = '';
|
||||
if (!$searchOnlyById) {
|
||||
if (USE_ACCOUNT_NAME) {
|
||||
$nameOrNumber = '`name`,';
|
||||
} else if (USE_ACCOUNT_NUMBER) {
|
||||
$nameOrNumber = '`number`,';
|
||||
$numberColumn = 'number';
|
||||
}
|
||||
if (USE_ACCOUNT_NAME) {
|
||||
$nameOrNumber = '`name`,';
|
||||
} else if (USE_ACCOUNT_NUMBER) {
|
||||
$nameOrNumber = '`number`,';
|
||||
}
|
||||
|
||||
// SELECT query on database
|
||||
$this->data = $this->db->query('SELECT `id`, ' . $nameOrNumber . '`password`, `email`, `blocked`, `rlname`, `location`, `country`, `web_flags`, ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays`, ' : '') . ($this->db->hasColumn('accounts', 'lastday') ? '`lastday`, ' : ($this->db->hasColumn('accounts', 'premend') ? '`premend`,' : ($this->db->hasColumn('accounts', 'premium_ends_at') ? '`premium_ends_at`,' : ''))) . '`created` FROM `accounts` WHERE `' . $numberColumn . '` = ' . (int) $id)->fetch();
|
||||
$this->data = $this->db->query('SELECT `id`, ' . $nameOrNumber . '`password`, `email`, `rlname`, `location`, `country`, `web_flags`, ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays`, ' : '') . ($this->db->hasColumn('accounts', 'lastday') ? '`lastday`, ' : ($this->db->hasColumn('accounts', 'premend') ? '`premend`,' : ($this->db->hasColumn('accounts', 'premium_ends_at') ? '`premium_ends_at`,' : ''))) . '`created` FROM `accounts` WHERE `id` = ' . (int) $id)->fetch();
|
||||
self::$cache[$id] = $this->data;
|
||||
}
|
||||
|
||||
@@ -268,8 +263,13 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
*/
|
||||
public function find($name)
|
||||
{
|
||||
$nameOrNumberColumn = 'name';
|
||||
if (USE_ACCOUNT_NUMBER) {
|
||||
$nameOrNumberColumn = 'number';
|
||||
}
|
||||
|
||||
// finds player's ID
|
||||
$id = $this->db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $this->db->quote($name) )->fetch();
|
||||
$id = $this->db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $this->db->quote($name) )->fetch();
|
||||
|
||||
// if anything was found
|
||||
if( isset($id['id']) )
|
||||
@@ -345,7 +345,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
}
|
||||
|
||||
// UPDATE query on database
|
||||
$this->db->exec('UPDATE `accounts` SET ' . ($this->db->hasColumn('accounts', 'name') ? '`name` = ' . $this->db->quote($this->data['name']) . ',' : '') . '`password` = ' . $this->db->quote($this->data['password']) . ', `email` = ' . $this->db->quote($this->data['email']) . ', `blocked` = ' . (int) $this->data['blocked'] . ', `rlname` = ' . $this->db->quote($this->data['rlname']) . ', `location` = ' . $this->db->quote($this->data['location']) . ', `country` = ' . $this->db->quote($this->data['country']) . ', `web_flags` = ' . (int) $this->data['web_flags'] . ', ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays` = ' . (int) $this->data['premdays'] . ',' : '') . '`' . $field . '` = ' . (int) $this->data[$field] . ' WHERE `id` = ' . $this->data['id']);
|
||||
$this->db->exec('UPDATE `accounts` SET ' . ($this->db->hasColumn('accounts', 'name') ? '`name` = ' . $this->db->quote($this->data['name']) . ',' : '') . '`password` = ' . $this->db->quote($this->data['password']) . ', `email` = ' . $this->db->quote($this->data['email']) . ', `rlname` = ' . $this->db->quote($this->data['rlname']) . ', `location` = ' . $this->db->quote($this->data['location']) . ', `country` = ' . $this->db->quote($this->data['country']) . ', `web_flags` = ' . (int) $this->data['web_flags'] . ', ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays` = ' . (int) $this->data['premdays'] . ',' : '') . '`' . $field . '` = ' . (int) $this->data[$field] . ' WHERE `id` = ' . $this->data['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -650,53 +650,6 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
$this->data['email'] = (string) $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if account is blocked.
|
||||
*
|
||||
* <p>
|
||||
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded} exception instead of triggering E_USER_WARNING.
|
||||
* </p>
|
||||
*
|
||||
* @version 0.0.3
|
||||
* @return bool Blocked state.
|
||||
* @throws E_OTS_NotLoaded If account is not loaded.
|
||||
*/
|
||||
public function isBlocked()
|
||||
{
|
||||
if( !isset($this->data['blocked']) )
|
||||
{
|
||||
throw new E_OTS_NotLoaded();
|
||||
}
|
||||
|
||||
return $this->data['blocked'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unblocks account.
|
||||
*
|
||||
* <p>
|
||||
* This method only updates object state. To save changes in database you need to use {@link OTS_Account::save() save() method} to flush changed to database.
|
||||
* </p>
|
||||
*/
|
||||
public function unblock()
|
||||
{
|
||||
$this->data['blocked'] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks account.
|
||||
*
|
||||
* <p>
|
||||
* This method only updates object state. To save changes in databaseed to use {@link OTS_Account::save() save() method} to flush changed to database.
|
||||
* </p>
|
||||
*/
|
||||
public function block()
|
||||
{
|
||||
$this->data['blocked'] = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reads custom field.
|
||||
*
|
||||
@@ -1147,9 +1100,6 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
case 'playersList':
|
||||
return $this->getPlayersList();
|
||||
|
||||
case 'blocked':
|
||||
return $this->isBlocked();
|
||||
|
||||
case 'deleted':
|
||||
return $this->isDeleted();
|
||||
|
||||
@@ -1195,17 +1145,6 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
$this->setPremiumEnd($value);
|
||||
break;
|
||||
|
||||
case 'blocked':
|
||||
if($value)
|
||||
{
|
||||
$this->block();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->unblock();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'deleted':
|
||||
if($value)
|
||||
{
|
||||
|
@@ -36,6 +36,7 @@
|
||||
* @property-read int $armor Armor rate.
|
||||
* @property-read array $defenses List of defenses.
|
||||
* @property-read array $attacks List of attacks.
|
||||
* @property-read array $look List of looks.
|
||||
*/
|
||||
class OTS_Monster extends DOMDocument
|
||||
{
|
||||
@@ -273,6 +274,30 @@ class OTS_Monster extends DOMDocument
|
||||
return $loot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns look of the monster.
|
||||
*
|
||||
* @return array Look with all the attributes of the look.
|
||||
* @throws DOMException On DOM operation error.
|
||||
*/
|
||||
public function getLook()
|
||||
{
|
||||
$look = array();
|
||||
|
||||
$element = $this->documentElement->getElementsByTagName('look')->item(0);
|
||||
|
||||
$look['type'] = $element->getAttribute('type');
|
||||
$look['typeex'] = $element->getAttribute('typeex');
|
||||
$look['head'] = $element->getAttribute('head');
|
||||
$look['body'] = $element->getAttribute('body');
|
||||
$look['legs'] = $element->getAttribute('legs');
|
||||
$look['feet'] = $element->getAttribute('feet');
|
||||
$look['addons'] = $element->getAttribute('addons');
|
||||
$look['corpse'] = $element->getAttribute('corpse');
|
||||
|
||||
return $look;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all monster summons.
|
||||
*
|
||||
@@ -560,6 +585,9 @@ class OTS_Monster extends DOMDocument
|
||||
case 'attacks':
|
||||
return $this->getAttacks();
|
||||
|
||||
case 'look':
|
||||
return $this->getLook();
|
||||
|
||||
default:
|
||||
throw new OutOfBoundsException();
|
||||
}
|
||||
|
@@ -174,6 +174,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
* @return OTS_Monster Monster.
|
||||
* @throws DOMException On DOM operation error.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->getMonster( key($this->monsters) );
|
||||
@@ -187,7 +188,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
/**
|
||||
* Moves to next iterator monster.
|
||||
*/
|
||||
public function next()
|
||||
public function next(): void
|
||||
{
|
||||
next($this->monsters);
|
||||
}
|
||||
@@ -197,6 +198,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
*
|
||||
* @return string Current position key.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return key($this->monsters);
|
||||
@@ -207,7 +209,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
*
|
||||
* @return bool If iterator has anything more.
|
||||
*/
|
||||
public function valid()
|
||||
public function valid(): bool
|
||||
{
|
||||
return key($this->monsters) !== null;
|
||||
}
|
||||
@@ -215,7 +217,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
/**
|
||||
* Resets iterator index.
|
||||
*/
|
||||
public function rewind()
|
||||
public function rewind(): void
|
||||
{
|
||||
reset($this->monsters);
|
||||
}
|
||||
@@ -226,6 +228,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
* @param string $offset Array key.
|
||||
* @return bool True if it's set.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->monsters[$offset]);
|
||||
@@ -239,6 +242,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
* @return OTS_Monster Monster instance.
|
||||
* @throws DOMException On DOM operation error.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->getMonster($offset);
|
||||
@@ -251,6 +255,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
* @param mixed $value Field value.
|
||||
* @throws E_OTS_ReadOnly Always - this class is read-only.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
throw new E_OTS_ReadOnly();
|
||||
@@ -262,6 +267,7 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess
|
||||
* @param string|int $offset Array key.
|
||||
* @throws E_OTS_ReadOnly Always - this class is read-only.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
throw new E_OTS_ReadOnly();
|
||||
|
@@ -398,7 +398,7 @@ class OTS_Player extends OTS_Row_DAO
|
||||
}
|
||||
|
||||
// UPDATE query on database
|
||||
$this->db->query('UPDATE ' . $this->db->tableName('players') . ' SET ' . $this->db->fieldName('name') . ' = ' . $this->db->quote($this->data['name']) . ', ' . $this->db->fieldName('account_id') . ' = ' . $this->data['account_id'] . ', ' . $this->db->fieldName('group_id') . ' = ' . $this->data['group_id'] . ', ' . $this->db->fieldName('sex') . ' = ' . $this->data['sex'] . ', ' . $this->db->fieldName('vocation') . ' = ' . $this->data['vocation'] . ', ' . $this->db->fieldName('experience') . ' = ' . $this->data['experience'] . ', ' . $this->db->fieldName('level') . ' = ' . $this->data['level'] . ', ' . $this->db->fieldName('maglevel') . ' = ' . $this->data['maglevel'] . ', ' . $this->db->fieldName('health') . ' = ' . $this->data['health'] . ', ' . $this->db->fieldName('healthmax') . ' = ' . $this->data['healthmax'] . ', ' . $this->db->fieldName('mana') . ' = ' . $this->data['mana'] . ', ' . $this->db->fieldName('manamax') . ' = ' . $this->data['manamax'] . ', ' . $this->db->fieldName('manaspent') . ' = ' . $this->data['manaspent'] . ', ' . $this->db->fieldName('soul') . ' = ' . $this->data['soul'] . ', ' . $this->db->fieldName('lookbody') . ' = ' . $this->data['lookbody'] . ', ' . $this->db->fieldName('lookfeet') . ' = ' . $this->data['lookfeet'] . ', ' . $this->db->fieldName('lookhead') . ' = ' . $this->data['lookhead'] . ', ' . $this->db->fieldName('looklegs') . ' = ' . $this->data['looklegs'] . ', ' . $this->db->fieldName('looktype') . ' = ' . $this->data['looktype'] . $lookaddons . ', ' . $this->db->fieldName('posx') . ' = ' . $this->data['posx'] . ', ' . $this->db->fieldName('posy') . ' = ' . $this->data['posy'] . ', ' . $this->db->fieldName('posz') . ' = ' . $this->data['posz'] . ', ' . $this->db->fieldName('cap') . ' = ' . $this->data['cap'] . ', ' . $this->db->fieldName('lastlogin') . ' = ' . $this->data['lastlogin'] . ', ' . $this->db->fieldName('lastlogout') . ' = ' . $this->data['lastlogout'] . ', ' . $this->db->fieldName('lastip') . ' = ' . $this->data['lastip'] . ', ' . $this->db->fieldName('save') . ' = ' . (int) $this->data['save'] . ', ' . $this->db->fieldName('conditions') . ' = ' . $this->db->quote($this->data['conditions']) . ', `' . $skull_time . '` = ' . $this->data['skulltime'] . ', `' . $skull_type . '` = ' . (int) $this->data['skull'] . $guild_info . ', ' . $this->db->fieldName('town_id') . ' = ' . $this->data['town_id'] . $loss . $loss_items . ', ' . $this->db->fieldName('balance') . ' = ' . $this->data['balance'] . $blessings . $stamina . $direction . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
|
||||
$this->db->query('UPDATE ' . $this->db->tableName('players') . ' SET ' . $this->db->fieldName('name') . ' = ' . $this->db->quote($this->data['name']) . ', ' . $this->db->fieldName('account_id') . ' = ' . $this->data['account_id'] . ', ' . $this->db->fieldName('group_id') . ' = ' . $this->data['group_id'] . ', ' . $this->db->fieldName('sex') . ' = ' . $this->data['sex'] . ', ' . $this->db->fieldName('vocation') . ' = ' . $this->data['vocation'] . ', ' . $this->db->fieldName('experience') . ' = ' . $this->data['experience'] . ', ' . $this->db->fieldName('level') . ' = ' . $this->data['level'] . ', ' . $this->db->fieldName('maglevel') . ' = ' . $this->data['maglevel'] . ', ' . $this->db->fieldName('health') . ' = ' . $this->data['health'] . ', ' . $this->db->fieldName('healthmax') . ' = ' . $this->data['healthmax'] . ', ' . $this->db->fieldName('mana') . ' = ' . $this->data['mana'] . ', ' . $this->db->fieldName('manamax') . ' = ' . $this->data['manamax'] . ', ' . $this->db->fieldName('manaspent') . ' = ' . $this->data['manaspent'] . ', ' . $this->db->fieldName('soul') . ' = ' . $this->data['soul'] . ', ' . $this->db->fieldName('lookbody') . ' = ' . $this->data['lookbody'] . ', ' . $this->db->fieldName('lookfeet') . ' = ' . $this->data['lookfeet'] . ', ' . $this->db->fieldName('lookhead') . ' = ' . $this->data['lookhead'] . ', ' . $this->db->fieldName('looklegs') . ' = ' . $this->data['looklegs'] . ', ' . $this->db->fieldName('looktype') . ' = ' . $this->data['looktype'] . $lookaddons . ', ' . $this->db->fieldName('posx') . ' = ' . $this->data['posx'] . ', ' . $this->db->fieldName('posy') . ' = ' . $this->data['posy'] . ', ' . $this->db->fieldName('posz') . ' = ' . $this->data['posz'] . ', ' . $this->db->fieldName('cap') . ' = ' . $this->data['cap'] . ', ' . $this->db->fieldName('lastlogin') . ' = ' . $this->data['lastlogin'] . ', ' . $this->db->fieldName('lastlogout') . ' = ' . $this->data['lastlogout'] . ', ' . $this->db->fieldName('lastip') . ' = ' . $this->db->quote($this->data['lastip']) . ', ' . $this->db->fieldName('save') . ' = ' . (int) $this->data['save'] . ', ' . $this->db->fieldName('conditions') . ' = ' . $this->db->quote($this->data['conditions']) . ', `' . $skull_time . '` = ' . $this->data['skulltime'] . ', `' . $skull_type . '` = ' . (int) $this->data['skull'] . $guild_info . ', ' . $this->db->fieldName('town_id') . ' = ' . $this->data['town_id'] . $loss . $loss_items . ', ' . $this->db->fieldName('balance') . ' = ' . $this->data['balance'] . $blessings . $stamina . $direction . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
|
||||
}
|
||||
// creates new player
|
||||
else
|
||||
@@ -602,7 +602,7 @@ class OTS_Player extends OTS_Row_DAO
|
||||
}
|
||||
|
||||
$account = new OTS_Account();
|
||||
$account->load($this->data['account_id'], false, true);
|
||||
$account->load($this->data['account_id']);
|
||||
return $account;
|
||||
}
|
||||
|
||||
|
@@ -308,7 +308,7 @@ class OTS_SpellsList implements IteratorAggregate, Countable
|
||||
* @since 0.1.5
|
||||
* @return AppendIterator Iterator for all spells.
|
||||
*/
|
||||
public function getIterator()
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
$iterator = new AppendIterator();
|
||||
$iterator->append( new ArrayIterator($this->runes) );
|
||||
|
@@ -34,10 +34,12 @@ class Visitors
|
||||
$this->cleanVisitors();
|
||||
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$userAgentShortened = substr($_SERVER['HTTP_USER_AGENT'] ?? 'unknown', 0, 255);
|
||||
|
||||
if($this->visitorExists($ip))
|
||||
$this->updateVisitor($ip, $_SERVER['REQUEST_URI']);
|
||||
$this->updateVisitor($ip, $_SERVER['REQUEST_URI'], $userAgentShortened);
|
||||
else
|
||||
$this->addVisitor($ip, $_SERVER['REQUEST_URI']);
|
||||
$this->addVisitor($ip, $_SERVER['REQUEST_URI'], $userAgentShortened);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
@@ -75,26 +77,26 @@ class Visitors
|
||||
$db->exec('DELETE FROM ' . $db->tableName(TABLE_PREFIX . 'visitors') . ' WHERE ' . $db->fieldName('lastvisit') . ' < ' . (time() - $this->sessionTime * 60));
|
||||
}
|
||||
|
||||
private function updateVisitor($ip, $page)
|
||||
private function updateVisitor($ip, $page, $userAgent)
|
||||
{
|
||||
if($this->cacheEnabled) {
|
||||
$this->data[$ip] = array('page' => $page, 'lastvisit' => time());
|
||||
$this->data[$ip] = array('page' => $page, 'lastvisit' => time(), 'user_agent' => $userAgent);
|
||||
return;
|
||||
}
|
||||
|
||||
global $db;
|
||||
$db->exec('UPDATE ' . $db->tableName(TABLE_PREFIX . 'visitors') . ' SET ' . $db->fieldName('lastvisit') . ' = ' . time() . ', ' . $db->fieldName('page') . ' = ' . $db->quote($page) . ' WHERE ' . $db->fieldName('ip') . ' = ' . $db->quote($ip));
|
||||
$db->update(TABLE_PREFIX . 'visitors', ['lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent], ['ip' => $ip]);
|
||||
}
|
||||
|
||||
private function addVisitor($ip, $page)
|
||||
private function addVisitor($ip, $page, $userAgent)
|
||||
{
|
||||
if($this->cacheEnabled) {
|
||||
$this->data[$ip] = array('page' => $page, 'lastvisit' => time());
|
||||
$this->data[$ip] = array('page' => $page, 'lastvisit' => time(), 'user_agent' => $userAgent);
|
||||
return;
|
||||
}
|
||||
|
||||
global $db;
|
||||
$db->exec('INSERT INTO ' . $db->tableName(TABLE_PREFIX . 'visitors') . ' (' . $db->fieldName('ip') . ' ,' . $db->fieldName('lastvisit') . ', ' . $db->fieldName('page') . ') VALUE (' . $db->quote($ip) . ', ' . time() . ', ' . $db->quote($page) . ')');
|
||||
$db->insert(TABLE_PREFIX . 'visitors', ['ip' => $ip, 'lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent]);
|
||||
}
|
||||
|
||||
public function getVisitors()
|
||||
@@ -107,7 +109,7 @@ class Visitors
|
||||
}
|
||||
|
||||
global $db;
|
||||
return $db->query('SELECT ' . $db->fieldName('ip') . ', ' . $db->fieldName('lastvisit') . ', ' . $db->fieldName('page') . ' FROM ' . $db->tableName(TABLE_PREFIX . 'visitors') . ' ORDER BY ' . $db->fieldName('lastvisit') . ' DESC')->fetchAll();
|
||||
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();
|
||||
}
|
||||
|
||||
public function getAmountVisitors()
|
||||
|
@@ -20,7 +20,7 @@ $locale['not_loaded'] = 'Nicht geladen';
|
||||
$locale['loading_spinner'] = 'Bitte warten, installieren...';
|
||||
$locale['importing_spinner'] = 'Bitte warte, Daten werden importiert...';
|
||||
$locale['please_fill_all'] = 'Bitte füllen Sie alle Felder aus!';
|
||||
$locale['already_installed'] = 'MyAAC wurde bereits installiert. Bitte löschen <b>install/<b/> Verzeichnis. Wenn Sie MyAAC neu installieren möchten, löschen Sie die Datei <strong>config.local.php</strong> aus dem Hauptverzeichnis und aktualisieren Sie die Seite.';
|
||||
$locale['already_installed'] = 'MyAAC wurde bereits installiert. Bitte löschen <b>install/</b> Verzeichnis. Wenn Sie MyAAC neu installieren möchten, löschen Sie die Datei <strong>config.local.php</strong> aus dem Hauptverzeichnis und aktualisieren Sie die Seite.';
|
||||
|
||||
// welcome
|
||||
$locale['step_welcome'] = 'Willkommen';
|
||||
|
118
system/login.php
118
system/login.php
@@ -28,124 +28,6 @@ if($current_session !== false)
|
||||
}
|
||||
}
|
||||
|
||||
// new login with data from form
|
||||
if(!$logged && isset($_POST['account_login'], $_POST['password_login']))
|
||||
{
|
||||
$login_account = $_POST['account_login'];
|
||||
$login_password = $_POST['password_login'];
|
||||
$remember_me = isset($_POST['remember_me']);
|
||||
if(!empty($login_account) && !empty($login_password))
|
||||
{
|
||||
if($cache->enabled())
|
||||
{
|
||||
$tmp = '';
|
||||
if($cache->fetch('failed_logins', $tmp))
|
||||
{
|
||||
$tmp = unserialize($tmp);
|
||||
$to_remove = array();
|
||||
foreach($tmp as $ip => $t)
|
||||
{
|
||||
if(time() - $t['last'] >= 5 * 60)
|
||||
$to_remove[] = $ip;
|
||||
}
|
||||
|
||||
foreach($to_remove as $ip)
|
||||
unset($tmp[$ip]);
|
||||
}
|
||||
else
|
||||
$tmp = array();
|
||||
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$t = $tmp[$ip] ?? null;
|
||||
}
|
||||
|
||||
if(config('recaptcha_enabled') && !config('account_create_auto_login'))
|
||||
{
|
||||
require_once LIBS . 'GoogleReCAPTCHA.php';
|
||||
if (!GoogleReCAPTCHA::verify('login')) {
|
||||
$errors[] = GoogleReCAPTCHA::getErrorMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$account_logged = new OTS_Account();
|
||||
if (config('account_login_by_email')) {
|
||||
$account_logged->findByEMail($login_account);
|
||||
}
|
||||
|
||||
if (!config('account_login_by_email') || config('account_login_by_email_fallback')) {
|
||||
if(USE_ACCOUNT_NAME) {
|
||||
$account_logged->find($login_account);
|
||||
} else {
|
||||
$account_logged->load($login_account, true);
|
||||
}
|
||||
}
|
||||
|
||||
if($account_logged->isLoaded() && encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword()
|
||||
&& (!isset($t) || $t['attempts'] < 5)
|
||||
)
|
||||
{
|
||||
setSession('account', $account_logged->getNumber());
|
||||
setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password));
|
||||
if($remember_me) {
|
||||
setSession('remember_me', true);
|
||||
}
|
||||
|
||||
$logged = true;
|
||||
$logged_flags = $account_logged->getWebFlags();
|
||||
|
||||
if(isset($_POST['admin']) && !admin()) {
|
||||
$errors[] = 'This account has no admin privileges.';
|
||||
unsetSession('account');
|
||||
unsetSession('password');
|
||||
unsetSession('remember_me');
|
||||
$logged = false;
|
||||
}
|
||||
else {
|
||||
$account_logged->setCustomField('web_lastlogin', time());
|
||||
}
|
||||
|
||||
$hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me));
|
||||
}
|
||||
else
|
||||
{
|
||||
$hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me));
|
||||
|
||||
$errorMessage = getAccountLoginByLabel() . ' or password is not correct.';
|
||||
|
||||
// temporary solution for blocking failed login attempts
|
||||
if($cache->enabled())
|
||||
{
|
||||
if(isset($t))
|
||||
{
|
||||
$t['attempts']++;
|
||||
$t['last'] = time();
|
||||
|
||||
if($t['attempts'] >= 5)
|
||||
$errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.';
|
||||
else
|
||||
$errors[] = $errorMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
$t = array('attempts' => 1, 'last' => time());
|
||||
$errors[] = $errorMessage;
|
||||
}
|
||||
|
||||
$tmp[$ip] = $t;
|
||||
$cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour
|
||||
}
|
||||
else {
|
||||
$errors[] = $errorMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$errors[] = 'Please enter your ' . getAccountLoginByLabel() . ' and password.';
|
||||
|
||||
$hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me));
|
||||
}
|
||||
}
|
||||
|
||||
if($logged) {
|
||||
$logged_flags = $account_logged->getWebFlags();
|
||||
$twig->addGlobal('logged', true);
|
||||
|
@@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Logout from account
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2019 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
if(isset($account_logged) && $account_logged->isLoaded()) {
|
||||
if($hooks->trigger(HOOK_LOGOUT, ['account_id' => $account_logged->getId()])) {
|
||||
|
@@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Database migrations
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2019 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
// database migrations
|
||||
$tmp = '';
|
||||
@@ -19,4 +28,4 @@ else { // register first version
|
||||
require SYSTEM . 'migrations/' . $i . '.php';
|
||||
updateDatabaseConfig('database_version', $i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
system/migrations/34.php
Normal file
4
system/migrations/34.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
// add user_agent column into visitors
|
||||
|
||||
$db->exec('ALTER TABLE `' . TABLE_PREFIX . "visitors` ADD `user_agent` VARCHAR(255) NOT NULL DEFAULT '';");
|
3
system/migrations/35.php
Normal file
3
system/migrations/35.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
// add look column
|
||||
$db->exec('ALTER TABLE `' . TABLE_PREFIX . "monsters` ADD `look` VARCHAR(255) NOT NULL DEFAULT '' AFTER `health`;");
|
@@ -26,11 +26,11 @@ if(empty($new_password) && empty($new_password2) && empty($old_password)) {
|
||||
else
|
||||
{
|
||||
if(empty($new_password) || empty($new_password2) || empty($old_password)){
|
||||
$errors[] = "Please fill in form.";
|
||||
$errors[] = 'Please fill in form.';
|
||||
}
|
||||
$password_strlen = strlen($new_password);
|
||||
if($new_password != $new_password2) {
|
||||
$errors[] = "The new passwords do not match!";
|
||||
$errors[] = 'The new passwords do not match!';
|
||||
}
|
||||
|
||||
if(empty($errors)) {
|
||||
@@ -41,9 +41,12 @@ else
|
||||
/** @var OTS_Account $account_logged */
|
||||
$old_password = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $old_password);
|
||||
if($old_password != $account_logged->getPassword()) {
|
||||
$errors[] = "Current password is incorrect!";
|
||||
$errors[] = 'Current password is incorrect!';
|
||||
}
|
||||
|
||||
$hooks->trigger(HOOK_ACCOUNT_CHANGE_PASSWORD_POST);
|
||||
}
|
||||
|
||||
if(!empty($errors)){
|
||||
//show errors
|
||||
$twig->display('error_box.html.twig', array('errors' => $errors));
|
||||
@@ -51,12 +54,10 @@ else
|
||||
//show form
|
||||
$twig->display('account.change_password.html.twig');
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
$org_pass = $new_password;
|
||||
|
||||
if(USE_ACCOUNT_SALT)
|
||||
{
|
||||
if(USE_ACCOUNT_SALT) {
|
||||
$salt = generateRandomString(10, false, true, true);
|
||||
$new_password = $salt . $new_password;
|
||||
$account_logged->setCustomField('salt', $salt);
|
||||
@@ -68,17 +69,18 @@ else
|
||||
$account_logged->logAction('Account password changed.');
|
||||
|
||||
$message = '';
|
||||
if($config['mail_enabled'] && $config['send_mail_when_change_password'])
|
||||
{
|
||||
if($config['mail_enabled'] && $config['send_mail_when_change_password']) {
|
||||
$mailBody = $twig->render('mail.password_changed.html.twig', array(
|
||||
'new_password' => $org_pass,
|
||||
'ip' => get_browser_real_ip(),
|
||||
));
|
||||
|
||||
if(_mail($account_logged->getEMail(), $config['lua']['serverName']." - Changed password", $mailBody))
|
||||
$message = '<br/><small>Your new password were send on email address <b>'.$account_logged->getEMail().'</b>.</small>';
|
||||
else
|
||||
if(_mail($account_logged->getEMail(), $config['lua']['serverName']." - Changed password", $mailBody)) {
|
||||
$message = '<br/><small>Your new password were send on email address <b>' . $account_logged->getEMail() . '</b>.</small>';
|
||||
}
|
||||
else {
|
||||
$message = '<br/><p class="error">An error occurred while sending email. For Admin: More info can be found in system/logs/mailer-error.log</p>';
|
||||
}
|
||||
}
|
||||
|
||||
$twig->display('success.html.twig', array(
|
||||
|
@@ -26,8 +26,13 @@ if(config('account_create_character_create')) {
|
||||
}
|
||||
|
||||
$account_type = 'number';
|
||||
if(USE_ACCOUNT_NAME) {
|
||||
$account_type = 'name';
|
||||
if (config('account_login_by_email')) {
|
||||
$account_type = 'Email Address';
|
||||
}
|
||||
else {
|
||||
if(USE_ACCOUNT_NAME) {
|
||||
$account_type = 'name';
|
||||
}
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
@@ -72,14 +77,6 @@ if($save)
|
||||
$errors['country'] = 'Country is invalid.';
|
||||
}
|
||||
|
||||
if(config('recaptcha_enabled'))
|
||||
{
|
||||
require_once LIBS . 'GoogleReCAPTCHA.php';
|
||||
if (!GoogleReCAPTCHA::verify('register')) {
|
||||
$errors['verification'] = GoogleReCAPTCHA::getErrorMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// password
|
||||
if(empty($password)) {
|
||||
$errors['password'] = 'Please enter the password for your new account.';
|
||||
@@ -149,7 +146,9 @@ if($save)
|
||||
}
|
||||
}
|
||||
|
||||
$hooks->trigger(HOOK_ACCOUNT_CREATE_AFTER_SUBMIT, $params);
|
||||
if (!$hooks->trigger(HOOK_ACCOUNT_CREATE_POST, $params)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(config('account_create_character_create')) {
|
||||
$character_name = isset($_POST['name']) ? stripslashes(ucwords(strtolower($_POST['name']))) : null;
|
||||
@@ -162,9 +161,12 @@ if($save)
|
||||
|
||||
if(empty($errors))
|
||||
{
|
||||
$hasBeenCreatedByEMail = false;
|
||||
|
||||
$new_account = new OTS_Account();
|
||||
if (config('account_login_by_email')) {
|
||||
$new_account->createWithEmail($email);
|
||||
$hasBeenCreatedByEMail = true;
|
||||
}
|
||||
else {
|
||||
if(USE_ACCOUNT_NAME)
|
||||
@@ -181,7 +183,6 @@ if($save)
|
||||
|
||||
$new_account->setPassword(encrypt($password));
|
||||
$new_account->setEMail($email);
|
||||
$new_account->unblock();
|
||||
$new_account->save();
|
||||
|
||||
if(USE_ACCOUNT_SALT)
|
||||
@@ -253,14 +254,21 @@ if($save)
|
||||
$character_created = $createCharacter->doCreate($character_name, $character_sex, $character_vocation, $character_town, $new_account, $errors);
|
||||
if (!$character_created) {
|
||||
error('There was an error creating your character. Please create your character later in account management page.');
|
||||
error(implode(' ', $errors));
|
||||
}
|
||||
}
|
||||
|
||||
if($config['account_create_auto_login']) {
|
||||
$_POST['account_login'] = USE_ACCOUNT_NAME ? $account_name : $account_id;
|
||||
if(config('account_create_auto_login')) {
|
||||
if ($hasBeenCreatedByEMail) {
|
||||
$_POST['account_login'] = $email;
|
||||
}
|
||||
else {
|
||||
$_POST['account_login'] = USE_ACCOUNT_NAME ? $account_name : $account_id;
|
||||
}
|
||||
|
||||
$_POST['password_login'] = $password2;
|
||||
|
||||
require SYSTEM . 'login.php';
|
||||
require PAGES . 'account/login.php';
|
||||
header('Location: ' . getLink('account/manage'));
|
||||
}
|
||||
|
||||
|
124
system/pages/account/login.php
Normal file
124
system/pages/account/login.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* Login
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Gesior <jerzyskalski@wp.pl>
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2023 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
$title = 'Login';
|
||||
|
||||
// new login with data from form
|
||||
if(!$logged && isset($_POST['account_login'], $_POST['password_login']))
|
||||
{
|
||||
$login_account = $_POST['account_login'];
|
||||
$login_password = $_POST['password_login'];
|
||||
$remember_me = isset($_POST['remember_me']);
|
||||
if(!empty($login_account) && !empty($login_password))
|
||||
{
|
||||
if($cache->enabled())
|
||||
{
|
||||
$tmp = '';
|
||||
if($cache->fetch('failed_logins', $tmp))
|
||||
{
|
||||
$tmp = unserialize($tmp);
|
||||
$to_remove = array();
|
||||
foreach($tmp as $ip => $t)
|
||||
{
|
||||
if(time() - $t['last'] >= 5 * 60)
|
||||
$to_remove[] = $ip;
|
||||
}
|
||||
|
||||
foreach($to_remove as $ip)
|
||||
unset($tmp[$ip]);
|
||||
}
|
||||
else
|
||||
$tmp = array();
|
||||
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$t = $tmp[$ip] ?? null;
|
||||
}
|
||||
|
||||
$account_logged = new OTS_Account();
|
||||
if (config('account_login_by_email')) {
|
||||
$account_logged->findByEMail($login_account);
|
||||
}
|
||||
|
||||
if (!config('account_login_by_email') || config('account_login_by_email_fallback')) {
|
||||
if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER) {
|
||||
$account_logged->find($login_account);
|
||||
} else {
|
||||
$account_logged->load($login_account, true);
|
||||
}
|
||||
}
|
||||
|
||||
if($account_logged->isLoaded() && encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword()
|
||||
&& (!isset($t) || $t['attempts'] < 5)
|
||||
)
|
||||
{
|
||||
setSession('account', $account_logged->getId());
|
||||
setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password));
|
||||
if($remember_me) {
|
||||
setSession('remember_me', true);
|
||||
}
|
||||
|
||||
$logged = true;
|
||||
$logged_flags = $account_logged->getWebFlags();
|
||||
|
||||
if(isset($_POST['admin']) && !admin()) {
|
||||
$errors[] = 'This account has no admin privileges.';
|
||||
unsetSession('account');
|
||||
unsetSession('password');
|
||||
unsetSession('remember_me');
|
||||
$logged = false;
|
||||
}
|
||||
else {
|
||||
$account_logged->setCustomField('web_lastlogin', time());
|
||||
}
|
||||
|
||||
$hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me));
|
||||
}
|
||||
else
|
||||
{
|
||||
$hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me));
|
||||
|
||||
$errorMessage = getAccountLoginByLabel() . ' or password is not correct.';
|
||||
|
||||
// temporary solution for blocking failed login attempts
|
||||
if($cache->enabled())
|
||||
{
|
||||
if(isset($t))
|
||||
{
|
||||
$t['attempts']++;
|
||||
$t['last'] = time();
|
||||
|
||||
if($t['attempts'] >= 5)
|
||||
$errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.';
|
||||
else
|
||||
$errors[] = $errorMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
$t = array('attempts' => 1, 'last' => time());
|
||||
$errors[] = $errorMessage;
|
||||
}
|
||||
|
||||
$tmp[$ip] = $t;
|
||||
$cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour
|
||||
}
|
||||
else {
|
||||
$errors[] = $errorMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$errors[] = 'Please enter your ' . getAccountLoginByLabel() . ' and password.';
|
||||
|
||||
$hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me));
|
||||
}
|
||||
|
||||
$hooks->trigger(HOOK_ACCOUNT_LOGIN_POST);
|
||||
}
|
@@ -40,7 +40,7 @@ elseif($action == 'step1' && $action_type == 'email')
|
||||
{
|
||||
if($account->getCustomField('email_next') < time())
|
||||
echo 'Please enter e-mail to account with this character.<BR>
|
||||
<form action="?subtopic=lostaccount&action=sendcode" method=post>
|
||||
<form action="' . getLink('account/lost') . '?action=sendcode" method=post>
|
||||
<input type=hidden name="character">
|
||||
<table cellspacing=1 cellpadding=4 border=0 width=100%>
|
||||
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Please enter e-mail to account</B></TD></TR>
|
||||
@@ -68,7 +68,7 @@ elseif($action == 'step1' && $action_type == 'email')
|
||||
else
|
||||
echo 'Invalid player name format. If you have other characters on account try with other name.';
|
||||
echo '<BR /><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center">
|
||||
<a href="?subtopic=lostaccount" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div>
|
||||
<a href="' . getLink('account/lost') . '" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div>
|
||||
</TD></TR></FORM></TABLE></TABLE>';
|
||||
}
|
||||
elseif($action == 'sendcode')
|
||||
@@ -95,8 +95,8 @@ elseif($action == 'sendcode')
|
||||
<p>Account name: '.$account->getName().'</p>
|
||||
<br />
|
||||
To do so, please click this link:
|
||||
<p><a href="' . BASE_URL . '?subtopic=lostaccount&action=checkcode&code='.$newcode.'&character='.urlencode($nick).'">'.BASE_URL.'/?subtopic=lostaccount&action=checkcode&code='.$newcode.'&character='.urlencode($nick).'</a></p>
|
||||
<p>or open page: <i>' . BASE_URL . '?subtopic=lostaccount&action=checkcode</i> and in field "code" write <b>'.$newcode.'</b></p>
|
||||
<p><a href="' . getLink('account/lost') . '?action=checkcode&code='.$newcode.'&character='.urlencode($nick).'">'.BASE_URL.'/?subtopic=lostaccount&action=checkcode&code='.$newcode.'&character='.urlencode($nick).'</a></p>
|
||||
<p>or open page: <i>' . getLink('account/lost') . '?action=checkcode</i> and in field "code" write <b>'.$newcode.'</b></p>
|
||||
<br/>
|
||||
<p>If you did not request a password change, you may ignore this message and your password will remain unchanged.';
|
||||
|
||||
@@ -131,7 +131,7 @@ elseif($action == 'sendcode')
|
||||
else
|
||||
echo 'Invalid player name format. If you have other characters on account try with other name.';
|
||||
echo '<BR /><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center">
|
||||
<a href="?subtopic=lostaccount&action=step1&action_type=email&nick='.urlencode($nick).'" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div>
|
||||
<a href="' . getLink('account/lost') . '?action=step1&action_type=email&nick='.urlencode($nick).'" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div>
|
||||
</TD></TR></FORM></TABLE></TABLE>';
|
||||
}
|
||||
elseif($action == 'step1' && $action_type == 'reckey')
|
||||
@@ -150,7 +150,7 @@ elseif($action == 'step1' && $action_type == 'reckey')
|
||||
if(!empty($account_key))
|
||||
{
|
||||
echo 'If you enter right recovery key you will see form to set new e-mail and password to account. To this e-mail will be send your new password and account name.<BR>
|
||||
<FORM ACTION="?subtopic=lostaccount&action=step2" METHOD=post>
|
||||
<FORM ACTION="' . getLink('account/lost') . '?action=step2" METHOD=post>
|
||||
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
|
||||
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Please enter your recovery key</B></TD></TR>
|
||||
<TR><TD BGCOLOR="'.$config['darkborder'].'">
|
||||
|
@@ -11,6 +11,7 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$title = 'Account Management';
|
||||
require __DIR__ . '/login.php';
|
||||
require __DIR__ . '/base.php';
|
||||
|
||||
if(!$logged) {
|
||||
@@ -85,7 +86,7 @@ $twig->display('account.management.html.twig', array(
|
||||
'email_request' => $email_request,
|
||||
'email_new_time' => $email_new_time,
|
||||
'email_new' => isset($email_new) ? $email_new : '',
|
||||
'account' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId(),
|
||||
'account' => (USE_ACCOUNT_NAME ? $account_logged->getName() : (USE_ACCOUNT_NUMBER ? $account_logged->getNumber() : $account_logged->getId())),
|
||||
'account_email' => $account_email,
|
||||
'account_created' => $account_created,
|
||||
'account_status' => $account_status,
|
||||
|
@@ -10,7 +10,7 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
$title = 'Changelog';
|
||||
|
||||
$_page = (int)$_GET['page'] ?? 0;
|
||||
$_page = isset($_GET['page']) ? (int)$_GET['page'] : 0;
|
||||
$limit = 30;
|
||||
$offset = $_page * $limit;
|
||||
$next_page = false;
|
||||
|
@@ -201,8 +201,7 @@ if($player->isLoaded() && !$player->isDeleted())
|
||||
unset($storage);
|
||||
}
|
||||
|
||||
if($config['characters']['equipment']) {
|
||||
global $db;
|
||||
if($config['characters']['equipment'] && $db->hasTable('player_items') && $db->hasColumn('player_items', 'pid') && $db->hasColumn('player_items', 'sid') && $db->hasColumn('player_items', 'itemtype')) {
|
||||
$eq_sql = $db->query('SELECT `pid`, `itemtype` FROM player_items WHERE player_id = '.$player->getId().' AND (`pid` >= 1 and `pid` <= 10)');
|
||||
$equipment = array();
|
||||
foreach($eq_sql as $eq)
|
||||
@@ -285,7 +284,7 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil
|
||||
$deaths[] = array('time' => $death['date'], 'description' => $description . '.');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if ($db->hasColumn('player_deaths', 'time') && $db->hasColumn('player_deaths', 'level') && $db->hasColumn('player_deaths', 'killed_by') && $db->hasColumn('player_deaths', 'is_player')) {
|
||||
$mostdamage = '';
|
||||
if($db->hasColumn('player_deaths', 'mostdamage_by'))
|
||||
$mostdamage = ', `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`';
|
||||
|
@@ -101,14 +101,15 @@ if(isset($_GET['image']))
|
||||
return;
|
||||
}
|
||||
|
||||
$images =
|
||||
$db->query('SELECT `id`, `comment`, `image`, `author`, `thumb`' .
|
||||
$images = Cache::remember('gallery_' . ($canEdit ? '1' : '0'), 60, function () use ($db, $canEdit) {
|
||||
return $db->query('SELECT `id`, `comment`, `image`, `author`, `thumb`' .
|
||||
($canEdit ? ', `hidden`, `ordering`' : '') .
|
||||
' FROM `' . TABLE_PREFIX . 'gallery`' .
|
||||
(!$canEdit ? ' WHERE `hidden` != 1' : '') .
|
||||
' ORDER BY `ordering`;');
|
||||
' ORDER BY `ordering`;')->fetchAll(PDO::FETCH_ASSOC);
|
||||
});
|
||||
|
||||
$last = $images->rowCount();
|
||||
$last = count($images);
|
||||
if(!$last)
|
||||
{
|
||||
?>
|
||||
|
@@ -19,23 +19,23 @@ $guilds_list->orderBy("name");
|
||||
$guilds = array();
|
||||
if(count($guilds_list) > 0)
|
||||
{
|
||||
foreach ($guilds_list as $guild) {
|
||||
$guild_logo = $guild->getCustomField('logo_name');
|
||||
if (empty($guild_logo) || !file_exists(GUILD_IMAGES_DIR . $guild_logo))
|
||||
$guild_logo = "default.gif";
|
||||
foreach ($guilds_list as $guild) {
|
||||
$guild_logo = $guild->getCustomField('logo_name');
|
||||
if (empty($guild_logo) || !file_exists(GUILD_IMAGES_DIR . $guild_logo))
|
||||
$guild_logo = "default.gif";
|
||||
|
||||
$description = $guild->getCustomField('description');
|
||||
$description_with_lines = str_replace(array("\r\n", "\n", "\r"), '<br />', $description, $count);
|
||||
if ($count < $config['guild_description_lines_limit'])
|
||||
$description = wordwrap(nl2br($description), 60, "<br />", true);
|
||||
$description = $guild->getCustomField('description');
|
||||
$description_with_lines = str_replace(array("\r\n", "\n", "\r"), '<br />', $description, $count);
|
||||
if ($count < $config['guild_description_lines_limit'])
|
||||
$description = wordwrap(nl2br($description), 60, "<br />", true);
|
||||
|
||||
$guildName = $guild->getName();
|
||||
$guilds[] = array('name' => $guildName, 'logo' => $guild_logo, 'link' => getGuildLink($guildName, false), 'description' => $description);
|
||||
}
|
||||
$guildName = $guild->getName();
|
||||
$guilds[] = array('name' => $guildName, 'logo' => $guild_logo, 'link' => getGuildLink($guildName, false), 'description' => $description);
|
||||
}
|
||||
};
|
||||
|
||||
$twig->display('guilds.list.html.twig', array(
|
||||
'guilds' => $guilds,
|
||||
'logged' => isset($logged) ? $logged : false,
|
||||
'isAdmin' => admin(),
|
||||
'guilds' => $guilds,
|
||||
'logged' => isset($logged) ? $logged : false,
|
||||
'isAdmin' => admin(),
|
||||
));
|
||||
|
@@ -49,78 +49,78 @@ $players_from_account_in_guild = array();
|
||||
$players_from_account_ids = array();
|
||||
if($logged)
|
||||
{
|
||||
$account_players = $account_logged->getPlayers();
|
||||
foreach($account_players as $player)
|
||||
{
|
||||
$players_from_account_ids[] = $player->getId();
|
||||
$player_rank = $player->getRank();
|
||||
if($player_rank->isLoaded())
|
||||
{
|
||||
foreach($rank_list as $rank_in_guild)
|
||||
{
|
||||
if($guild_owner->isLoaded() && $rank_in_guild->isLoaded() && $player_rank->isLoaded() &&
|
||||
$rank_in_guild->getId() == $player_rank->getId())
|
||||
{
|
||||
$players_from_account_in_guild[] = $player->getName();
|
||||
if($guild_owner->getId() == $player->getId())
|
||||
{
|
||||
$guild_vice = true;
|
||||
$guild_leader = true;
|
||||
}
|
||||
else if($player_rank->getLevel() > 1)
|
||||
{
|
||||
$guild_vice = true;
|
||||
$level_in_guild = $player_rank->getLevel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$account_players = $account_logged->getPlayers();
|
||||
foreach($account_players as $player)
|
||||
{
|
||||
$players_from_account_ids[] = $player->getId();
|
||||
$player_rank = $player->getRank();
|
||||
if($player_rank->isLoaded())
|
||||
{
|
||||
foreach($rank_list as $rank_in_guild)
|
||||
{
|
||||
if($guild_owner->isLoaded() && $rank_in_guild->isLoaded() && $player_rank->isLoaded() &&
|
||||
$rank_in_guild->getId() == $player_rank->getId())
|
||||
{
|
||||
$players_from_account_in_guild[] = $player->getName();
|
||||
if($guild_owner->getId() == $player->getId())
|
||||
{
|
||||
$guild_vice = true;
|
||||
$guild_leader = true;
|
||||
}
|
||||
else if($player_rank->getLevel() > 1)
|
||||
{
|
||||
$guild_vice = true;
|
||||
$level_in_guild = $player_rank->getLevel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//show guild page
|
||||
$guild_logo = $guild->getCustomField('logo_name');
|
||||
if(empty($guild_logo) || !file_exists(GUILD_IMAGES_DIR . $guild_logo))
|
||||
$guild_logo = "default.gif";
|
||||
$guild_logo = "default.gif";
|
||||
|
||||
$description = $guild->getCustomField('description');
|
||||
$description_with_lines = str_replace(array("\r\n", "\n", "\r"), '<br />', $description, $count);
|
||||
if($count < $config['guild_description_lines_limit'])
|
||||
$description = wordwrap(nl2br($description), 60, "<br />", true);
|
||||
$description = wordwrap(nl2br($description), 60, "<br />", true);
|
||||
//$description = $description_with_lines;
|
||||
|
||||
$guild_owner = $guild->getOwner();
|
||||
if($guild_owner->isLoaded())
|
||||
$guild_owner_name = $guild_owner->getName();
|
||||
$guild_owner_name = $guild_owner->getName();
|
||||
|
||||
$guild_members = array();
|
||||
foreach($rank_list as $rank)
|
||||
{
|
||||
if($db->hasTable(GUILD_MEMBERS_TABLE))
|
||||
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `' . GUILD_MEMBERS_TABLE . '`.`rank_id` as `rank_id` FROM `players`, `' . GUILD_MEMBERS_TABLE . '` WHERE `' . GUILD_MEMBERS_TABLE . '`.`rank_id` = ' . $rank->getId() . ' AND `players`.`id` = `' . GUILD_MEMBERS_TABLE . '`.`player_id` ORDER BY `name`;');
|
||||
else if($db->hasColumn('players', 'rank_id'))
|
||||
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank->getId() . ' AND `deleted` = 0;');
|
||||
if($db->hasTable(GUILD_MEMBERS_TABLE))
|
||||
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `' . GUILD_MEMBERS_TABLE . '`.`rank_id` as `rank_id` FROM `players`, `' . GUILD_MEMBERS_TABLE . '` WHERE `' . GUILD_MEMBERS_TABLE . '`.`rank_id` = ' . $rank->getId() . ' AND `players`.`id` = `' . GUILD_MEMBERS_TABLE . '`.`player_id` ORDER BY `name`;');
|
||||
else if($db->hasColumn('players', 'rank_id'))
|
||||
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank->getId() . ' AND `deleted` = 0;');
|
||||
|
||||
$players_with_rank_number = $players_with_rank->rowCount();
|
||||
if($players_with_rank_number > 0)
|
||||
{
|
||||
$members = array();
|
||||
foreach($players_with_rank as $result)
|
||||
{
|
||||
$player = new OTS_Player();
|
||||
$player->load($result['id']);
|
||||
if(!$player->isLoaded())
|
||||
continue;
|
||||
$players_with_rank_number = $players_with_rank->rowCount();
|
||||
if($players_with_rank_number > 0)
|
||||
{
|
||||
$members = array();
|
||||
foreach($players_with_rank as $result)
|
||||
{
|
||||
$player = new OTS_Player();
|
||||
$player->load($result['id']);
|
||||
if(!$player->isLoaded())
|
||||
continue;
|
||||
|
||||
$members[] = $player;
|
||||
}
|
||||
$members[] = $player;
|
||||
}
|
||||
|
||||
$guild_members[] = array(
|
||||
'rank_name' => $rank->getName(),
|
||||
'rank_level' => $rank->getLevel(),
|
||||
'members' => $members
|
||||
);
|
||||
}
|
||||
$guild_members[] = array(
|
||||
'rank_name' => $rank->getName(),
|
||||
'rank_level' => $rank->getLevel(),
|
||||
'members' => $members
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
include(SYSTEM . 'libs/pot/InvitesDriver.php');
|
||||
@@ -129,37 +129,39 @@ $invited_list = $guild->listInvites();
|
||||
$show_accept_invite = 0;
|
||||
if($logged && count($invited_list) > 0)
|
||||
{
|
||||
foreach($invited_list as $invited_player)
|
||||
{
|
||||
if(count($account_players) > 0)
|
||||
{
|
||||
foreach($account_players as $player_from_acc)
|
||||
{
|
||||
if($player_from_acc->isLoaded() && $invited_player->isLoaded() && $player_from_acc->getName() == $invited_player->getName())
|
||||
$show_accept_invite++;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($invited_list as $invited_player)
|
||||
{
|
||||
if(count($account_players) > 0)
|
||||
{
|
||||
foreach($account_players as $player_from_acc)
|
||||
{
|
||||
if($player_from_acc->isLoaded() && $invited_player->isLoaded() && $player_from_acc->getName() == $invited_player->getName())
|
||||
$show_accept_invite++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$useGuildNick = false;
|
||||
if($db->hasColumn('players', 'guildnick'))
|
||||
$useGuildNick = true;
|
||||
$useGuildNick = true;
|
||||
|
||||
$twig->display('guilds.view.html.twig', array(
|
||||
'logo' => $guild_logo,
|
||||
'guild_name' => $guild_name,
|
||||
'description' => $description,
|
||||
'guild_owner' => $guild_owner->isLoaded() ? $guild_owner : null,
|
||||
'guild_creation_date' => $guild->getCreationData(),
|
||||
'guild_members' => $guild_members,
|
||||
'players_from_account_ids' => $players_from_account_ids,
|
||||
'players_from_account_in_guild' => $players_from_account_in_guild,
|
||||
'level_in_guild' => $level_in_guild,
|
||||
'isLeader' => $guild_leader,
|
||||
'isVice' => $guild_vice,
|
||||
'logged' => $logged,
|
||||
'invited_list' => $invited_list,
|
||||
'show_accept_invite' => $show_accept_invite,
|
||||
'useGuildNick' => $useGuildNick
|
||||
'logo' => $guild_logo,
|
||||
'guild' => $guild,
|
||||
'guild_id' => $guild->getId(),
|
||||
'guild_name' => $guild_name,
|
||||
'description' => $description,
|
||||
'guild_owner' => $guild_owner->isLoaded() ? $guild_owner : null,
|
||||
'guild_creation_date' => $guild->getCreationData(),
|
||||
'guild_members' => $guild_members,
|
||||
'players_from_account_ids' => $players_from_account_ids,
|
||||
'players_from_account_in_guild' => $players_from_account_in_guild,
|
||||
'level_in_guild' => $level_in_guild,
|
||||
'isLeader' => $guild_leader,
|
||||
'isVice' => $guild_vice,
|
||||
'logged' => $logged,
|
||||
'invited_list' => $invited_list,
|
||||
'show_accept_invite' => $show_accept_invite,
|
||||
'useGuildNick' => $useGuildNick
|
||||
));
|
||||
|
@@ -14,17 +14,17 @@ $title = 'Houses';
|
||||
|
||||
$errors = array();
|
||||
if(!$db->hasColumn('houses', 'name')) {
|
||||
$errors[] = 'Houses list is not available on this server.';
|
||||
$errors[] = 'Houses list is not available on this server.';
|
||||
|
||||
$twig->display('houses.html.twig', array(
|
||||
'errors' => $errors
|
||||
));
|
||||
$twig->display('houses.html.twig', array(
|
||||
'errors' => $errors
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
$rentType = trim(strtolower($config['lua']['houseRentPeriod']));
|
||||
if($rentType != 'yearly' && $rentType != 'monthly' && $rentType != 'weekly' && $rentType != 'daily')
|
||||
$rentType = 'never';
|
||||
$rentType = 'never';
|
||||
|
||||
$state = '';
|
||||
$order = '';
|
||||
@@ -32,116 +32,116 @@ $type = '';
|
||||
|
||||
if(isset($_GET['page']) && $_GET['page'] == 'view' && isset($_REQUEST['house']))
|
||||
{
|
||||
$beds = array("", "one", "two", "three", "fourth", "fifth");
|
||||
$houseName = $_REQUEST['house'];
|
||||
$houseId = (Validator::number($_REQUEST['house']) ? $_REQUEST['house'] : -1);
|
||||
$selectHouse = $db->query('SELECT * FROM ' . $db->tableName('houses') . ' WHERE ' . $db->fieldName('name') . ' LIKE ' . $db->quote($houseName) . ' OR `id` = ' . $db->quote($houseId));
|
||||
$beds = array("", "one", "two", "three", "fourth", "fifth");
|
||||
$houseName = $_REQUEST['house'];
|
||||
$houseId = (Validator::number($_REQUEST['house']) ? $_REQUEST['house'] : -1);
|
||||
$selectHouse = $db->query('SELECT * FROM ' . $db->tableName('houses') . ' WHERE ' . $db->fieldName('name') . ' LIKE ' . $db->quote($houseName) . ' OR `id` = ' . $db->quote($houseId));
|
||||
|
||||
$house = array();
|
||||
if($selectHouse->rowCount() > 0)
|
||||
{
|
||||
$house = $selectHouse->fetch();
|
||||
$houseId = $house['id'];
|
||||
$house = array();
|
||||
if($selectHouse->rowCount() > 0)
|
||||
{
|
||||
$house = $selectHouse->fetch();
|
||||
$houseId = $house['id'];
|
||||
|
||||
$title = $house['name'] . ' - ' . $title;
|
||||
$title = $house['name'] . ' - ' . $title;
|
||||
|
||||
$imgPath = 'images/houses/' . $houseId . '.gif';
|
||||
if(!file_exists($imgPath)) {
|
||||
$imgPath = 'images/houses/default.jpg';
|
||||
}
|
||||
$imgPath = 'images/houses/' . $houseId . '.gif';
|
||||
if(!file_exists($imgPath)) {
|
||||
$imgPath = 'images/houses/default.jpg';
|
||||
}
|
||||
|
||||
$bedsMessage = null;
|
||||
$houseBeds = $house['beds'];
|
||||
if($houseBeds > 0)
|
||||
$bedsMessage = 'House have ' . (isset($beds[$houseBeds]) ? $beds[$houseBeds] : $houseBeds) . ' bed' . ($houseBeds > 1 ? 's' : '');
|
||||
else
|
||||
$bedsMessage = 'This house dont have any beds';
|
||||
$bedsMessage = null;
|
||||
$houseBeds = $house['beds'];
|
||||
if($houseBeds > 0)
|
||||
$bedsMessage = 'House have ' . (isset($beds[$houseBeds]) ? $beds[$houseBeds] : $houseBeds) . ' bed' . ($houseBeds > 1 ? 's' : '');
|
||||
else
|
||||
$bedsMessage = 'This house dont have any beds';
|
||||
|
||||
$houseOwner = $house['owner'];
|
||||
if($houseOwner > 0)
|
||||
{
|
||||
$guild = NULL;
|
||||
$owner = null;
|
||||
if(isset($house['guild']) && $house['guild'] == 1)
|
||||
{
|
||||
$guild = new OTS_Guild();
|
||||
$guild->load($houseOwner);
|
||||
$owner = getGuildLink($guild->getName());
|
||||
}
|
||||
else
|
||||
$owner = getCreatureName($houseOwner);
|
||||
$houseOwner = $house['owner'];
|
||||
if($houseOwner > 0)
|
||||
{
|
||||
$guild = NULL;
|
||||
$owner = null;
|
||||
if(isset($house['guild']) && $house['guild'] == 1)
|
||||
{
|
||||
$guild = new OTS_Guild();
|
||||
$guild->load($houseOwner);
|
||||
$owner = getGuildLink($guild->getName());
|
||||
}
|
||||
else
|
||||
$owner = getCreatureName($houseOwner);
|
||||
|
||||
if($rentType != 'never' && $house['paid'] > 0)
|
||||
{
|
||||
$who = '';
|
||||
if($guild)
|
||||
$who = $guild->getName();
|
||||
else
|
||||
{
|
||||
$player = new OTS_Player();
|
||||
$player->load($houseOwner);
|
||||
if($player->isLoaded())
|
||||
{
|
||||
$sexs = array('She', 'He');
|
||||
$who = $sexs[$player->getSex()];
|
||||
}
|
||||
}
|
||||
$owner .= ' ' . $who . ' has paid the rent until ' . date("M d Y, H:i:s", $house['paid']) . ' CEST.';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
$errors[] = 'House with name ' . $houseName . ' does not exists.';
|
||||
if($rentType != 'never' && $house['paid'] > 0)
|
||||
{
|
||||
$who = '';
|
||||
if($guild)
|
||||
$who = $guild->getName();
|
||||
else
|
||||
{
|
||||
$player = new OTS_Player();
|
||||
$player->load($houseOwner);
|
||||
if($player->isLoaded())
|
||||
{
|
||||
$sexs = array('She', 'He');
|
||||
$who = $sexs[$player->getSex()];
|
||||
}
|
||||
}
|
||||
$owner .= ' ' . $who . ' has paid the rent until ' . date("M d Y, H:i:s", $house['paid']) . ' CEST.';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
$errors[] = 'House with name ' . $houseName . ' does not exists.';
|
||||
|
||||
$twig->display('houses.view.html.twig', array(
|
||||
'errors' => $errors,
|
||||
'imgPath' => isset($imgPath) ? $imgPath : null,
|
||||
'houseName' => isset($house['name']) ? $house['name'] : null,
|
||||
'bedsMessage' => isset($bedsMessage) ? $bedsMessage : null,
|
||||
'houseSize' => isset($house['size']) ? $house['size'] : null,
|
||||
'houseRent' => isset($house['rent']) ? $house['rent'] : null,
|
||||
'owner' => isset($owner) ? $owner : null,
|
||||
'rentType' => isset($rentType) ? $rentType : null
|
||||
));
|
||||
$twig->display('houses.view.html.twig', array(
|
||||
'errors' => $errors,
|
||||
'imgPath' => isset($imgPath) ? $imgPath : null,
|
||||
'houseName' => isset($house['name']) ? $house['name'] : null,
|
||||
'bedsMessage' => isset($bedsMessage) ? $bedsMessage : null,
|
||||
'houseSize' => isset($house['size']) ? $house['size'] : null,
|
||||
'houseRent' => isset($house['rent']) ? $house['rent'] : null,
|
||||
'owner' => isset($owner) ? $owner : null,
|
||||
'rentType' => isset($rentType) ? $rentType : null
|
||||
));
|
||||
|
||||
if (count($errors) > 0) {
|
||||
return;
|
||||
}
|
||||
if (count($errors) > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$cleanOldHouse = null;
|
||||
if(isset($config['lua']['houseCleanOld'])) {
|
||||
$cleanOldHouse = (int)(eval('return ' . $config['lua']['houseCleanOld'] . ';') / (24 * 60 * 60));
|
||||
$cleanOldHouse = (int)(eval('return ' . $config['lua']['houseCleanOld'] . ';') / (24 * 60 * 60));
|
||||
}
|
||||
|
||||
$housesSearch = false;
|
||||
if(isset($_POST['town']) && isset($_POST['state']) && isset($_POST['order']) && (isset($_POST['type']) || !$db->hasColumn('houses', 'guild')))
|
||||
{
|
||||
$townName = $config['towns'][$_POST['town']];
|
||||
$order = $_POST['order'];
|
||||
$orderby = '`name`';
|
||||
if(!empty($order))
|
||||
{
|
||||
if($order == 'size')
|
||||
$orderby = '`size`';
|
||||
else if($order == 'rent')
|
||||
$orderby = '`rent`';
|
||||
}
|
||||
$townName = $config['towns'][$_POST['town']];
|
||||
$order = $_POST['order'];
|
||||
$orderby = '`name`';
|
||||
if(!empty($order))
|
||||
{
|
||||
if($order == 'size')
|
||||
$orderby = '`size`';
|
||||
else if($order == 'rent')
|
||||
$orderby = '`rent`';
|
||||
}
|
||||
|
||||
$town = 'town';
|
||||
if($db->hasColumn('houses', 'town_id'))
|
||||
$town = 'town_id';
|
||||
else if($db->hasColumn('houses', 'townid'))
|
||||
$town = 'townid';
|
||||
$town = 'town';
|
||||
if($db->hasColumn('houses', 'town_id'))
|
||||
$town = 'town_id';
|
||||
else if($db->hasColumn('houses', 'townid'))
|
||||
$town = 'townid';
|
||||
|
||||
$whereby = '`' . $town . '` = ' .(int)$_POST['town'];
|
||||
$state = $_POST['state'];
|
||||
if(!empty($state))
|
||||
$whereby .= ' AND `owner` ' . ($state == 'free' ? '' : '!'). '= 0';
|
||||
$whereby = '`' . $town . '` = ' .(int)$_POST['town'];
|
||||
$state = $_POST['state'];
|
||||
if(!empty($state))
|
||||
$whereby .= ' AND `owner` ' . ($state == 'free' ? '' : '!'). '= 0';
|
||||
|
||||
$type = isset($_POST['type']) ? $_POST['type'] : NULL;
|
||||
if($type == 'guildhalls' && !$db->hasColumn('houses', 'guild'))
|
||||
$type = 'all';
|
||||
$type = isset($_POST['type']) ? $_POST['type'] : NULL;
|
||||
if($type == 'guildhalls' && !$db->hasColumn('houses', 'guild'))
|
||||
$type = 'all';
|
||||
|
||||
if (!empty($type) && $type != 'all')
|
||||
{
|
||||
@@ -158,49 +158,51 @@ if(isset($_POST['town']) && isset($_POST['state']) && isset($_POST['order']) &&
|
||||
}
|
||||
}
|
||||
|
||||
$houses_info = $db->query('SELECT * FROM `houses` WHERE ' . $whereby. ' ORDER BY ' . $orderby);
|
||||
$houses_info = $db->query('SELECT * FROM `houses` WHERE ' . $whereby. ' ORDER BY ' . $orderby);
|
||||
|
||||
$players_info = $db->query("SELECT `houses`.`id` AS `houseid` , `players`.`name` AS `ownername` FROM `houses` , `players` , `accounts` WHERE `players`.`id` = `houses`.`owner` AND `accounts`.`id` = `players`.`account_id`");
|
||||
$players = array();
|
||||
foreach($players_info->fetchAll() as $player)
|
||||
$players[$player['houseid']] = array('name' => $player['ownername']);
|
||||
$players_info = $db->query("SELECT `houses`.`id` AS `houseid` , `players`.`name` AS `ownername` FROM `houses` , `players` , `accounts` WHERE `players`.`id` = `houses`.`owner` AND `accounts`.`id` = `players`.`account_id`");
|
||||
$players = array();
|
||||
foreach($players_info->fetchAll() as $player)
|
||||
$players[$player['houseid']] = array('name' => $player['ownername']);
|
||||
|
||||
$houses = array();
|
||||
foreach($houses_info->fetchAll() as $house)
|
||||
{
|
||||
$owner = isset($players[$house['id']]) ? $players[$house['id']] : array();
|
||||
$hasTilesColumn = $db->hasColumn('houses', 'tiles');
|
||||
|
||||
$houseRent = null;
|
||||
if($db->hasColumn('houses', 'guild') && $house['guild'] == 1 && $house['owner'] != 0)
|
||||
{
|
||||
$guild = new OTS_Guild();
|
||||
$guild->load($house['owner']);
|
||||
$houseRent = 'Rented by ' . getGuildLink($guild->getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!empty($owner['name']))
|
||||
$houseRent = 'Rented by ' . getPlayerLink($owner['name']);
|
||||
else
|
||||
$houseRent = 'Free';
|
||||
}
|
||||
$houses = array();
|
||||
foreach($houses_info->fetchAll() as $house)
|
||||
{
|
||||
$owner = isset($players[$house['id']]) ? $players[$house['id']] : array();
|
||||
|
||||
$houses[] = array('owner' => $owner, 'name' => $house['name'], 'size' => $house['size'], 'rent' => $house['rent'], 'rentedBy' => $houseRent);
|
||||
}
|
||||
$houseRent = null;
|
||||
if($db->hasColumn('houses', 'guild') && $house['guild'] == 1 && $house['owner'] != 0)
|
||||
{
|
||||
$guild = new OTS_Guild();
|
||||
$guild->load($house['owner']);
|
||||
$houseRent = 'Rented by ' . getGuildLink($guild->getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!empty($owner['name']))
|
||||
$houseRent = 'Rented by ' . getPlayerLink($owner['name']);
|
||||
else
|
||||
$houseRent = 'Free';
|
||||
}
|
||||
|
||||
$housesSearch = true;
|
||||
$houses[] = array('owner' => $owner, 'name' => $house['name'], 'size' => ($hasTilesColumn ? $house['tiles'] : $house['size']), 'rent' => $house['rent'], 'rentedBy' => $houseRent);
|
||||
}
|
||||
|
||||
$housesSearch = true;
|
||||
}
|
||||
|
||||
$guild = $db->hasColumn('houses', 'guild') ? ' or guildhall' : '';
|
||||
$twig->display('houses.html.twig', array(
|
||||
'state' => $state,
|
||||
'order' => $order,
|
||||
'type' => $type,
|
||||
'houseType' => $type == 'guildhalls' ? 'Guildhalls' : 'Houses and Flats',
|
||||
'townName' => isset($townName) ? $townName : null,
|
||||
'townId' => isset($_POST['town']) ? $_POST['town'] : null,
|
||||
'guild' => $guild,
|
||||
'cleanOldHouse' => isset($cleanOld) ? $cleanOld : null,
|
||||
'housesSearch' => $housesSearch,
|
||||
'houses' => isset($houses) ? $houses : null
|
||||
));
|
||||
'state' => $state,
|
||||
'order' => $order,
|
||||
'type' => $type,
|
||||
'houseType' => $type == 'guildhalls' ? 'Guildhalls' : 'Houses and Flats',
|
||||
'townName' => isset($townName) ? $townName : null,
|
||||
'townId' => isset($_POST['town']) ? $_POST['town'] : null,
|
||||
'guild' => $guild,
|
||||
'cleanOldHouse' => isset($cleanOld) ? $cleanOld : null,
|
||||
'housesSearch' => $housesSearch,
|
||||
'houses' => isset($houses) ? $houses : null
|
||||
));
|
||||
|
@@ -182,13 +182,13 @@ if(!$news_cached)
|
||||
$admin_options = '';
|
||||
if($canEdit)
|
||||
{
|
||||
$admin_options = '<br/><br/><a target="_blank" rel="noopener noreferrer" href="/admin/?p=news&action=edit&id=' . $news['id'] . '" title="Edit">
|
||||
$admin_options = '<br/><br/><a target="_blank" rel="noopener noreferrer" href="' . ADMIN_URL . '?p=news&action=edit&id=' . $news['id'] . '" title="Edit">
|
||||
<img src="images/edit.png"/>Edit
|
||||
</a>
|
||||
<a id="delete" target="_blank" rel="noopener noreferrer" href="/admin/?p=news&action=delete&id=' . $news['id'] . '" onclick="return confirm(\'Are you sure?\');" title="Delete">
|
||||
<a id="delete" target="_blank" rel="noopener noreferrer" href="' . ADMIN_URL . '?p=news&action=delete&id=' . $news['id'] . '" onclick="return confirm(\'Are you sure?\');" title="Delete">
|
||||
<img src="images/del.png"/>Delete
|
||||
</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="/admin/?p=news&action=hide&id=' . $news['id'] . '" title="' . ($news['hidden'] != 1 ? 'Hide' : 'Show') . '">
|
||||
<a target="_blank" rel="noopener noreferrer" href="' . ADMIN_URL . '?p=news&action=hide&id=' . $news['id'] . '" title="' . ($news['hidden'] != 1 ? 'Hide' : 'Show') . '">
|
||||
<img src="images/' . ($news['hidden'] != 1 ? 'success' : 'error') . '.png"/>
|
||||
' . ($news['hidden'] != 1 ? 'Hide' : 'Show') . '
|
||||
</a>';
|
||||
|
@@ -4,9 +4,10 @@
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2021 MyAAC
|
||||
* @copyright 2023 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
if(!isset($content[0]))
|
||||
$content = '';
|
||||
@@ -50,15 +51,18 @@ if (false !== $pos = strpos($uri, '?')) {
|
||||
$uri = rawurldecode($uri);
|
||||
if (BASE_DIR !== '') {
|
||||
$tmp = str_replace_first('/', '', BASE_DIR);
|
||||
$uri = str_replace_first($tmp . '/', '', $uri);
|
||||
$uri = str_replace_first($tmp, '', $uri);
|
||||
}
|
||||
|
||||
if(0 === strpos($uri, '/')) {
|
||||
$uri = str_replace_first('/', '', $uri);
|
||||
}
|
||||
|
||||
define('URI', $uri);
|
||||
|
||||
/** @var boolean $load_it */
|
||||
if(!$load_it) {
|
||||
// ignore warnings in some functions/plugins
|
||||
// page is not loaded anyways
|
||||
// page is not loaded anyway
|
||||
define('PAGE', '');
|
||||
|
||||
return;
|
||||
@@ -115,10 +119,22 @@ $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r)
|
||||
if ($route[0] === '*') {
|
||||
$route[0] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'];
|
||||
}
|
||||
else {
|
||||
if (is_string($route[0])) {
|
||||
$route[0] = explode(',', $route[0]);
|
||||
}
|
||||
|
||||
$toUpperCase = function(string $value): string {
|
||||
return trim(strtoupper($value));
|
||||
};
|
||||
|
||||
// convert to upper case, fast-route accepts only upper case
|
||||
$route[0] = array_map($toUpperCase, $route[0]);
|
||||
}
|
||||
|
||||
$aliases = [
|
||||
[':int', ':string', ':alphanum'],
|
||||
[':\d+', ':[A-Za-z0-9-_%+\']+}', ':[A-Za-z0-9]+'],
|
||||
[':\d+', ':[A-Za-z0-9-_%+\' ]+', ':[A-Za-z0-9]+'],
|
||||
];
|
||||
|
||||
// apply aliases
|
||||
@@ -147,6 +163,10 @@ $found = true;
|
||||
// old support for pages like /?subtopic=accountmanagement
|
||||
$page = $_REQUEST['p'] ?? ($_REQUEST['subtopic'] ?? '');
|
||||
if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) {
|
||||
if (isset($_REQUEST['p'])) { // some plugins may require this
|
||||
$_REQUEST['subtopic'] = $_REQUEST['p'];
|
||||
}
|
||||
|
||||
if (config('backward_support')) {
|
||||
require SYSTEM . 'compat/pages.php';
|
||||
}
|
||||
@@ -161,7 +181,6 @@ else {
|
||||
switch ($routeInfo[0]) {
|
||||
case FastRoute\Dispatcher::NOT_FOUND:
|
||||
// ... 404 Not Found
|
||||
//var_dump('not found');
|
||||
/**
|
||||
* Fallback to load page from templates/ or system/pages/ directory
|
||||
*/
|
||||
@@ -266,9 +285,10 @@ if(config('backward_support')) {
|
||||
|
||||
unset($page);
|
||||
|
||||
function getDatabasePages() {
|
||||
global $db;
|
||||
$pages = $db->query('SELECT `name` FROM ' . TABLE_PREFIX . 'pages');
|
||||
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 = [];
|
||||
|
||||
if ($pages->rowCount() < 1) {
|
||||
@@ -282,7 +302,8 @@ function getDatabasePages() {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function loadPageFromFileSystem($page, &$found) {
|
||||
function loadPageFromFileSystem($page, &$found): string
|
||||
{
|
||||
$file = SYSTEM . 'pages/' . $page . '.php';
|
||||
if (!is_file($file)) {
|
||||
// feature: convert camelCase to snake_case
|
||||
|
@@ -7,9 +7,10 @@
|
||||
* @copyright 2021 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
return [
|
||||
['GET', '', '__redirect__/news'], // redirect empty URL to news
|
||||
['GET', '', 'news.php'], // empty URL = show news
|
||||
['GET', 'news/archive/{id:int}[/]', 'news/archive.php'],
|
||||
|
||||
// block access to some files
|
||||
@@ -26,12 +27,12 @@ return [
|
||||
[['GET', 'POST'], 'account/character/sex[/]', 'account/change_sex.php'],
|
||||
[['GET', 'POST'], 'account/character/delete[/]', 'account/delete_character.php'],
|
||||
[['GET', 'POST'], 'account/character/comment[/{name:[A-Za-z0-9-_%+\']+}]', 'account/change_comment.php'],
|
||||
['GET', 'account/confirm_email/{hash:[A-Za-z0-9-_]+}[/]', 'account/confirm_email.php'],
|
||||
['GET', 'account/confirm_email/{hash:alphanum}[/]', 'account/confirm_email.php'],
|
||||
|
||||
['GET', 'bans/{page:\d+}[/]', 'bans.php'],
|
||||
[['GET', 'POST'], 'characters[/{name:string]', 'characters.php'],
|
||||
['GET', 'bans/{page:int}[/]', 'bans.php'],
|
||||
[['GET', 'POST'], 'characters[/{name:string}]', 'characters.php'],
|
||||
['GET', 'changelog[/{page:int}]', 'changelog.php'],
|
||||
['GET', 'creatures[/{name:string}]', 'creatures.php'],
|
||||
[['GET', 'POST'], 'creatures[/{name:string}]', 'creatures.php'],
|
||||
|
||||
['GET', 'faq[/{action:string}]', 'faq.php'],
|
||||
|
||||
|
6
system/templates/account.back_button.html.twig
Normal file
6
system/templates/account.back_button.html.twig
Normal file
@@ -0,0 +1,6 @@
|
||||
{% if new_line is defined and new_line %}
|
||||
<br/>
|
||||
{% endif %}
|
||||
<form action="{% if action is not defined %}{{ getLink('account/manage') }}{% else %}{{ action }}{% endif %}" method="post">
|
||||
{{ include('buttons.back.html.twig') }}
|
||||
</form>
|
@@ -96,6 +96,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td></td><td><span id="password_error" class="FormFieldError">{% if errors.password is defined %}{{ errors.password }}{% endif %}</span></td></tr>
|
||||
|
||||
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_PASSWORD') }}
|
||||
|
||||
<tr>
|
||||
<td class="LabelV" style="width: 150px">
|
||||
<span{% if errors.password is defined %} class="red"{% endif %}>Repeat password:</span>
|
||||
@@ -108,28 +111,6 @@
|
||||
<tr><td></td><td><span id="password2_error" class="FormFieldError">{% if errors.password is defined %}{{ errors.password }}{% endif %}</span></td></tr>
|
||||
|
||||
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_PASSWORDS') }}
|
||||
|
||||
{% if config.recaptcha_enabled %}
|
||||
{% if config.recaptcha_type == 'v3' %}
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
|
||||
{% elseif config.recaptcha_type == 'v2-invisible' %}
|
||||
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-bind="login-submit"></div>
|
||||
{% elseif config.recaptcha_type == 'v2-checkbox' %}
|
||||
<tr>
|
||||
<td class="LabelV" style="width: 150px">
|
||||
<span{% if errors.verification[0] is not null %} class="red"{% endif %}>Verification:</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-theme="{{ config.recaptcha_v2_theme }}"></div>
|
||||
</td>
|
||||
</tr>
|
||||
{% if errors.verification is defined %}
|
||||
<tr><td></td><td><span class="FormFieldError">{{ errors.verification }}</span></td></tr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_RECAPTCHA') }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -344,11 +325,7 @@
|
||||
</table>
|
||||
</form>
|
||||
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_FORM') }}
|
||||
<script type="text/javascript" src="tools/check_name.js"></script>
|
||||
{% if config.recaptcha_enabled and config.recaptcha_type == 'v3' %}
|
||||
{% set action = 'register' %}
|
||||
{{ include('google_recaptcha_v3.html.twig') }}
|
||||
{% endif %}
|
||||
<script type="text/javascript" src="{{ constant('BASE_URL') }}tools/check_name.js"></script>
|
||||
<style>
|
||||
#SuggestAccountNumber {
|
||||
font-size: 7pt;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
{{ hook('HOOK_ACCOUNT_LOGIN_BEFORE_PAGE') }}
|
||||
Please enter your account {{ account|lower }} and your password.<br/><a href="{{ getLink('account/create') }}">Create an account</a> if you do not have one yet.<br/><br/>
|
||||
<form action="{{ getLink('account/manage') }}" method="post" >
|
||||
{% if redirect is not null %}
|
||||
@@ -22,42 +23,27 @@ Please enter your account {{ account|lower }} and your password.<br/><a href="{{
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;" >
|
||||
{{ hook('HOOK_ACCOUNT_LOGIN_BEFORE_PASSWORD') }}
|
||||
<tr>
|
||||
<td class="LabelV" >
|
||||
<span{% if error is not null %} class="red"{% endif %}>{{ account_login_by }}:</span>
|
||||
</td>
|
||||
<td style="width:100%;" ><input type="text" name="account_login" size="30" maxlength="30" autofocus/></td>
|
||||
</tr>
|
||||
{{ hook('HOOK_ACCOUNT_LOGIN_AFTER_ACCOUNT') }}
|
||||
<tr>
|
||||
<td class="LabelV" >
|
||||
<span{% if error is not null %} class="red"{% endif %}>Password:</span>
|
||||
</td>
|
||||
<td><input type="password" name="password_login" size="30" maxlength="29" ></td>
|
||||
</tr>
|
||||
{{ hook('HOOK_ACCOUNT_LOGIN_AFTER_PASSWORD') }}
|
||||
<tr>
|
||||
<td class="LabelV" ></td>
|
||||
<td><input type="checkbox" id="remember_me" name="remember_me" value="true" />
|
||||
<label for="remember_me"> Remember me</label></td>
|
||||
</tr>
|
||||
{% if config.recaptcha_enabled %}
|
||||
{% if config.recaptcha_type == 'v3' %}
|
||||
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
|
||||
{% elseif config.recaptcha_type == 'v2-invisible' %}
|
||||
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-bind="login-submit"></div>
|
||||
{% elseif config.recaptcha_type == 'v2-checkbox' %}
|
||||
<tr>
|
||||
<td class="LabelV" style="width: 150px">
|
||||
<span{% if error is not null %} class="red"{% endif %}>Verification:</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-theme="{{ config.recaptcha_v2_theme }}"></div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if error is not null %}
|
||||
<tr><td></td><td><span class="FormFieldError">{{ error }}</span></td></tr>
|
||||
{% endif %}
|
||||
{{ hook('HOOK_ACCOUNT_LOGIN_AFTER_REMEMBER_ME') }}
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
@@ -90,7 +76,3 @@ Please enter your account {{ account|lower }} and your password.<br/><a href="{{
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% if config.recaptcha_enabled and config.recaptcha_type == 'v3' %}
|
||||
{% set action = 'login' %}
|
||||
{{ include('google_recaptcha_v3.html.twig') }}
|
||||
{% endif %}
|
||||
|
@@ -89,10 +89,12 @@
|
||||
<a name="General+Information"></a>
|
||||
<h2>General Information</h2>
|
||||
<table width="100%">
|
||||
{% if not config.account_login_by_email or config.account_login_by_email_fallback %}
|
||||
<tr style="background-color: {{ config.lightborder }};" >
|
||||
<td style="width: 90px;">Account {% if constant('USE_ACCOUNT_NAME') %}Name{% else %}Number{% endif %}:</td>
|
||||
<td>{{ account }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr style="background-color: {{ config.darkborder }};" >
|
||||
<td style="width: 90px;">Email Address:</td>
|
||||
<td>{{ account_email ~ email_change }}
|
||||
@@ -206,4 +208,4 @@
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -25,7 +25,7 @@
|
||||
</div>
|
||||
<input type="text" class="form-control" id="account-name-input" name="account_login" placeholder="{{ account_login_by }}" required autofocus>
|
||||
</div>
|
||||
|
||||
{{ hook('HOOK_ADMIN_LOGIN_AFTER_ACCOUNT') }}
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-key"></i></span>
|
||||
@@ -33,6 +33,7 @@
|
||||
<input type="password" class="form-control" placeholder="Password" name="password_login"
|
||||
placeholder="Password" required>
|
||||
</div>
|
||||
{{ hook('HOOK_ADMIN_LOGIN_AFTER_PASSWORD') }}
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="icheck-primary">
|
||||
@@ -45,6 +46,7 @@
|
||||
<button type="submit" class="btn btn-info btn-block">Sign In</button>
|
||||
</div>
|
||||
</div>
|
||||
{{ hook('HOOK_ADMIN_LOGIN_AFTER_SIGN_IN') }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,14 +1,14 @@
|
||||
<div style="text-align: right;">
|
||||
<a href="admin/?p=pages&action=edit&id={{ page.id }}" title="Edit in Admin Panel" target="_blank">
|
||||
<a href="?p=pages&action=edit&id={{ page.id }}" title="Edit in Admin Panel" target="_blank">
|
||||
<img src="images/edit.png"/>Edit
|
||||
</a>
|
||||
<a id="delete" href="admin/?p=pages&action=delete&id={{ page.id }}" onclick="return confirm('Are you sure?');"
|
||||
<a id="delete" href="?p=pages&action=delete&id={{ page.id }}" onclick="return confirm('Are you sure?');"
|
||||
title="Delete in Admin Panel" target="_blank">
|
||||
<img src="images/del.png"/>Delete
|
||||
</a>
|
||||
<a href="admin/?p=pages&action=hide&id={{ page.id }}"
|
||||
<a href="?p=pages&action=hide&id={{ page.id }}"
|
||||
title="{% if page.hidden != 1 %}Hide{% else %}Show{% endif %} in Admin Panel" target="_blank">
|
||||
<img src="images/{% if page.hidden != 1 %}success{% else %}error{% endif %}.png"/>{% if page.hidden != 1 %}Hide{% else %}Show{% endif %}
|
||||
</a>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -6,6 +6,7 @@
|
||||
<table class="table table-striped table-bordered table-responsive d-md-table" id="tb_plugins">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Enabled</th>
|
||||
<th>Name</th>
|
||||
<th>Version</th>
|
||||
<th>Author</th>
|
||||
@@ -16,6 +17,17 @@
|
||||
<tbody>
|
||||
{% for plugin in plugins %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if plugin.enabled %}
|
||||
<a href="?p=plugins&disable={{ plugin.file }}" class="btn btn-success" onclick="return confirm('Are you sure you want to disable plugin {{ plugin.name }}?');" title="Disable">
|
||||
<i class="fas fa-check"></i> Enabled
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="?p=plugins&enable={{ plugin.file }}" class="btn btn-danger" onclick="return confirm('Are you sure you want to enable plugin {{ plugin.name }}?');" title="Enable">
|
||||
<i class="fas fa-ban"></i> Disabled
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td><b>{{ plugin.name }}</b><br>
|
||||
<small>{{ plugin.description|raw }}</small>
|
||||
</td>
|
||||
@@ -26,10 +38,11 @@
|
||||
<td>{{ plugin.file }}.json</td>
|
||||
<td>
|
||||
{% if plugin.uninstall %}
|
||||
<a href="?p=plugins&uninstall={{ plugin.file }}" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?');" title="Uninstall">
|
||||
<a href="?p=plugins&uninstall={{ plugin.file }}" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to uninstall {{ plugin.name }}?');" title="Uninstall">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
{% endif %}</td>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -39,6 +52,6 @@
|
||||
|
||||
<script>
|
||||
$(function () {
|
||||
$('#tb_plugins').DataTable()
|
||||
$('#tb_plugins').DataTable();
|
||||
})
|
||||
</script>
|
||||
|
@@ -9,6 +9,7 @@
|
||||
<th>IP</th>
|
||||
<th>Last visit</th>
|
||||
<th>Page</th>
|
||||
<th>Browser</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -17,6 +18,7 @@
|
||||
<td>{{ visitor.ip }}</td>
|
||||
<td>{{ visitor.lastvisit|date("H:i:s") }}</td>
|
||||
<td><a href="{{ visitor.page }}">{{ visitor.page|slice(0, 50) }}</a></td>
|
||||
<td>{{ visitor.browser|raw }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@@ -11,7 +11,7 @@
|
||||
<td>
|
||||
{{ hook(constant('HOOK_CHARACTERS_BEFORE_INFORMATIONS')) }}
|
||||
{% if canEdit %}
|
||||
<a href="admin/?p=players&id={{ player.getId() }}" title="Edit in Admin Panel" target="_blank">
|
||||
<a href="{{ constant('ADMIN_URL') }}?p=players&id={{ player.getId() }}" title="Edit in Admin Panel" target="_blank">
|
||||
<img src="images/edit.png"/>Edit
|
||||
</a>
|
||||
{% endif %}
|
||||
@@ -404,7 +404,8 @@
|
||||
<tr>
|
||||
<td>
|
||||
<input type="hidden" name="name" value="{{ player.getName() }}"/>
|
||||
<input type="image" name="View {{ player.getName() }}" alt="View {{ player.getName() }}" src="{{ template_path }}/images/global/buttons/sbutton_view.gif" border="0" width="120" height="18"/>
|
||||
{% set button_name = "View" %}
|
||||
{{ include('buttons.base.html.twig') }}
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
@@ -418,7 +419,7 @@
|
||||
{% endif %}
|
||||
{{ hook(constant('HOOK_CHARACTERS_AFTER_CHARACTERS')) }}
|
||||
{% if canEdit %}
|
||||
<a href="admin/?p=players&id={{ player.getId() }}" title="Edit in Admin Panel" target="_blank">
|
||||
<a href="{{ constant('ADMIN_URL') }}?p=players&id={{ player.getId() }}" title="Edit in Admin Panel" target="_blank">
|
||||
<img src="images/edit.png"/>Edit
|
||||
</a>
|
||||
{% endif %}
|
||||
|
@@ -8,9 +8,8 @@
|
||||
<meta name="description" content="myaac">
|
||||
<meta name="generator" content="MyAAC">
|
||||
|
||||
<link rel="stylesheet" href="tools/css/messages.css">
|
||||
<link rel="shortcut icon" href="images/error.ico">
|
||||
<base href="{{ BASE_URL }}" />
|
||||
<link rel="stylesheet" href="{{ BASE_URL }}tools/css/messages.css">
|
||||
<link rel="shortcut icon" href="{{ BASE_URL }}images/error.ico">
|
||||
|
||||
<style>
|
||||
body{
|
||||
@@ -57,7 +56,7 @@
|
||||
}
|
||||
</style>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="tools/js/html5shiv.min.js"></script>
|
||||
<script src="{{ BASE_URL }}tools/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
|
@@ -1,11 +0,0 @@
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
grecaptcha.ready(function() {
|
||||
grecaptcha.execute('{{ config.recaptcha_site_key }}', {action: '{{ action }}'}).then(function(token) {
|
||||
if (token) {
|
||||
document.getElementById('g-recaptcha-response').value = token;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
@@ -1,11 +0,0 @@
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
grecaptcha.ready(function() {
|
||||
grecaptcha.execute('{{ config.recaptcha_site_key }}', {action: '{{ action }}'}).then(function(token) {
|
||||
if (token) {
|
||||
document.getElementById('g-recaptcha-response').value = token;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
@@ -1,162 +1,162 @@
|
||||
<div class="TableContainer">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text">Active Guilds on {{ config.lua.serverName }}</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text">Active Guilds on {{ config.lua.serverName }}</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="Table3">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="TableShadowContainerRightTop">
|
||||
<div class="TableShadowRightTop" style="background-image:url({{ template_path }}/images/content/table-shadow-rt.gif);"></div>
|
||||
</div>
|
||||
<div class="TableContentAndRightShadow" style="background-image:url({{ template_path }}/images/content/table-shadow-rm.gif);">
|
||||
<div class="TableContentContainer">
|
||||
<table class="TableContent" width="100%">
|
||||
<tbody>
|
||||
{% if guilds|length > 0 %}
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td width="64"><b>Logo</b></td>
|
||||
<td><b>Description</b></td>
|
||||
<td width="12%"><b> </b></td>
|
||||
</tr>
|
||||
<table class="Table3">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="TableShadowContainerRightTop">
|
||||
<div class="TableShadowRightTop" style="background-image:url({{ template_path }}/images/content/table-shadow-rt.gif);"></div>
|
||||
</div>
|
||||
<div class="TableContentAndRightShadow" style="background-image:url({{ template_path }}/images/content/table-shadow-rm.gif);">
|
||||
<div class="TableContentContainer">
|
||||
<table class="TableContent" width="100%">
|
||||
<tbody>
|
||||
{% if guilds|length > 0 %}
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td width="64"><b>Logo</b></td>
|
||||
<td><b>Description</b></td>
|
||||
<td width="12%"><b> </b></td>
|
||||
</tr>
|
||||
|
||||
{% set i = 0 %}
|
||||
{% for guild in guilds %}
|
||||
{% set i = i + 1 %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
<td>
|
||||
<img src="{{ constant('GUILD_IMAGES_DIR') }}{{ guild.logo }}" width="64" height="64">
|
||||
</td>
|
||||
{% set i = 0 %}
|
||||
{% for guild in guilds %}
|
||||
{% set i = i + 1 %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
<td>
|
||||
<img src="{{ constant('GUILD_IMAGES_DIR') }}{{ guild.logo }}" width="64" height="64">
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<span{% if guild.description is not empty %} valign="top"{% endif %}>
|
||||
<b>{{ guild.name }}</b>{% if isAdmin %}<a href="?subtopic=guilds&action=delete_by_admin&guild={{ guild.name }}"> - Delete this guild (for ADMIN only!)</a>{% endif %}
|
||||
</span>
|
||||
<td>
|
||||
<span{% if guild.description is not empty %} valign="top"{% endif %}>
|
||||
<b>{{ guild.name }}</b>{% if isAdmin %}<a href="?subtopic=guilds&action=delete_by_admin&guild={{ guild.name }}"> - Delete this guild (for ADMIN only!)</a>{% endif %}
|
||||
</span>
|
||||
|
||||
{% if guild.description is not empty %}
|
||||
<br>
|
||||
<span>{{ guild.description }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if guild.description is not empty %}
|
||||
<br>
|
||||
<span>{{ guild.description }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="border:0;">
|
||||
<form action="{{ guild.link }}" method="post">
|
||||
{{ include('buttons.view.html.twig') }}
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td valign="top">
|
||||
<b>Create Guild</b>
|
||||
<br/>
|
||||
Actually there is no guild on server.{% if logged %} Create first! Press button "Create Guild"{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="border:0;">
|
||||
<form action="{{ guild.link }}" method="post">
|
||||
{{ include('buttons.view.html.twig') }}
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td valign="top">
|
||||
<b>Create Guild</b>
|
||||
<br/>
|
||||
Actually there is no guild on server.{% if logged %} Create first! Press button "Create Guild"{% endif %}
|
||||
</td>
|
||||
|
||||
{% if logged %}
|
||||
<td>
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||
<form action="?subtopic=guilds&action=create" method="post">
|
||||
<form action="?subtopic=guilds&action=create" method="post">
|
||||
{% set button_name = 'Found Guild' %}
|
||||
{% set button_image = '_sbutton_foundguild' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</form>
|
||||
</form>
|
||||
</table>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="TableShadowContainer">
|
||||
<div class="TableBottomShadow" style="background-image:url(https://static.tibia.com/images/global/content/table-shadow-bm.gif);">
|
||||
<div class="TableBottomLeftShadow" style="background-image:url({{ template_path }}/images/content/table-shadow-bl.gif);"></div>
|
||||
<div class="TableBottomRightShadow" style="background-image:url({{ template_path }}/images/content/table-shadow-br.gif);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% if logged %}
|
||||
<td>
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||
<form action="?subtopic=guilds&action=create" method="post">
|
||||
<form action="?subtopic=guilds&action=create" method="post">
|
||||
{% set button_name = 'Found Guild' %}
|
||||
{% set button_image = '_sbutton_foundguild' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</form>
|
||||
</form>
|
||||
</table>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="TableShadowContainer">
|
||||
<div class="TableBottomShadow" style="background-image:url(https://static.tibia.com/images/global/content/table-shadow-bm.gif);">
|
||||
<div class="TableBottomLeftShadow" style="background-image:url({{ template_path }}/images/content/table-shadow-bl.gif);"></div>
|
||||
<div class="TableBottomRightShadow" style="background-image:url({{ template_path }}/images/content/table-shadow-br.gif);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<table border="0" cellspacing="1" cellpadding="4" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="{{ template_path }}images/general/blank.gif" width="80" height="1" border="0">
|
||||
</td>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="{{ template_path }}images/general/blank.gif" width="80" height="1" border="0">
|
||||
</td>
|
||||
|
||||
<td align="center">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
{% if logged %}
|
||||
No guild found that suits your needs?
|
||||
<form action="?subtopic=guilds&action=create" method="post">
|
||||
{% set button_name = 'Found Guild' %}
|
||||
{% set button_image = '_sbutton_foundguild' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</form>
|
||||
{% else %}
|
||||
<b>Before you can create a guild you must login.</b>
|
||||
<br/>
|
||||
<form action="?subtopic=accountmanagement&redirect={{ getLink('guilds') }}" method="post">
|
||||
{% include('buttons.login.html.twig') %}
|
||||
</form>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
<td align="center">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
{% if logged %}
|
||||
No guild found that suits your needs?
|
||||
<form action="?subtopic=guilds&action=create" method="post">
|
||||
{% set button_name = 'Found Guild' %}
|
||||
{% set button_image = '_sbutton_foundguild' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</form>
|
||||
{% else %}
|
||||
<b>Before you can create a guild you must login.</b>
|
||||
<br/>
|
||||
<form action="?subtopic=accountmanagement&redirect={{ getLink('guilds') }}" method="post">
|
||||
{% include('buttons.login.html.twig') %}
|
||||
</form>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% if logged %}
|
||||
<br/>
|
||||
If you have any problem with guilds try:
|
||||
<br/>
|
||||
<a href="?subtopic=guilds&action=cleanup_players">Cleanup players</a> - can't join guild/be invited? Can't create guild? Try cleanup players.
|
||||
<br/>
|
||||
<a href="?subtopic=guilds&action=cleanup_guilds">Cleanup guilds</a> - made guild, you are a leader, but you are not on players list? Cleanup guilds!
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if logged %}
|
||||
<br/>
|
||||
If you have any problem with guilds try:
|
||||
<br/>
|
||||
<a href="?subtopic=guilds&action=cleanup_players">Cleanup players</a> - can't join guild/be invited? Can't create guild? Try cleanup players.
|
||||
<br/>
|
||||
<a href="?subtopic=guilds&action=cleanup_guilds">Cleanup guilds</a> - made guild, you are a leader, but you are not on players list? Cleanup guilds!
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td align="center">
|
||||
<img src="{{ template_path }}/images/general/blank.gif" width="80" height="1" border="0">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<td align="center">
|
||||
<img src="{{ template_path }}/images/general/blank.gif" width="80" height="1" border="0">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
@@ -1,347 +1,349 @@
|
||||
<div class="Border_2">
|
||||
<div class="Border_3">
|
||||
<div class="BoxContent">
|
||||
<table border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="64">
|
||||
<img src="{{ constant('GUILD_IMAGES_DIR') }}{{ logo }}" width="64" height="64">
|
||||
</td>
|
||||
<div class="Border_3">
|
||||
<div class="BoxContent">
|
||||
<table border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="64">
|
||||
<img src="{{ constant('GUILD_IMAGES_DIR') }}{{ logo }}" width="64" height="64">
|
||||
</td>
|
||||
|
||||
<td align="center" width="100%"><h1>{{ guild_name }}</h1></td>
|
||||
<td align="center" width="100%"><h1>{{ guild_name }}</h1></td>
|
||||
|
||||
<td width="64">
|
||||
<img src="{{ constant('GUILD_IMAGES_DIR') }}{{ logo }}" width="64" height="64">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<td width="64">
|
||||
<img src="{{ constant('GUILD_IMAGES_DIR') }}{{ logo }}" width="64" height="64">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<table width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align:top;">
|
||||
<div class="TableContainer">
|
||||
<div class="TableContainer">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text">Guild Information</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align:top;">
|
||||
<div class="TableContainer">
|
||||
<div class="TableContainer">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text">Guild Information</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="Table1" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="GuildInformationContainer">
|
||||
{% if descriptions is not empty %}
|
||||
{{ description }}
|
||||
<br>
|
||||
<br>
|
||||
{% endif %}
|
||||
<table class="Table1" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="GuildInformationContainer">
|
||||
{% if descriptions is not empty %}
|
||||
{{ description }}
|
||||
<br>
|
||||
<br>
|
||||
{% endif %}
|
||||
|
||||
{% if guild_owner is not empty %}
|
||||
{% set guildOwnerName = guild_owner.getName() %}
|
||||
{% if guild_owner is not empty %}
|
||||
{% set guildOwnerName = guild_owner.getName() %}
|
||||
|
||||
<a href="{{ getPlayerLink(guildOwnerName, false) }}"><b>{{ guildOwnerName }}</b></a> is guild leader of <b>{{ guild_name }}</b>.
|
||||
<br>
|
||||
{% endif %}
|
||||
<a href="{{ getPlayerLink(guildOwnerName, false) }}"><b>{{ guildOwnerName }}</b></a> is guild leader of <b>{{ guild_name }}</b>.
|
||||
<br>
|
||||
{% endif %}
|
||||
|
||||
The guild was founded on {{ config.lua.serverName }} on {{ guild_creation_date|date("j F Y") }}.
|
||||
{% if isLeader %}
|
||||
<a href="?subtopic=guilds&action=manager&guild={{ guild_name }}" style="float: right;">
|
||||
<img src="{{ template_path }}/images/global/buttons/sbutton_manageguild.png" style="width: 120px; height: 20px;" alt="Manage Guild">
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
The guild was founded on {{ config.lua.serverName }} on {{ guild_creation_date|date("j F Y") }}.
|
||||
{% if isLeader %}
|
||||
<a href="?subtopic=guilds&action=manager&guild={{ guild_name }}" style="float: right;">
|
||||
<img src="{{ template_path }}/images/global/buttons/sbutton_manageguild.png" style="width: 120px; height: 20px;" alt="Manage Guild">
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
<div class="TableContainer">
|
||||
<div class="TableContainer">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text">Guild Members</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="TableContainer">
|
||||
<div class="TableContainer">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text">Guild Members</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="Table3" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="TableContentAndRightShadow">
|
||||
<div class="TableContentContainer">
|
||||
<table class="TableContent" width="100%">
|
||||
<tbody>
|
||||
<tr class="LabelH">
|
||||
<td>Rank</td>
|
||||
<td>Name{% if useGuildNick %} and Title{% endif %}</td>
|
||||
<td>Vocation</td>
|
||||
<td>Level</td>
|
||||
<td>Status</td>
|
||||
</tr>
|
||||
<table class="Table3" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="TableContentAndRightShadow">
|
||||
<div class="TableContentContainer">
|
||||
<table class="TableContent" width="100%">
|
||||
<tbody>
|
||||
<tr class="LabelH">
|
||||
<td>Rank</td>
|
||||
<td>Name{% if useGuildNick %} and Title{% endif %}</td>
|
||||
<td>Vocation</td>
|
||||
<td>Level</td>
|
||||
<td>Status</td>
|
||||
</tr>
|
||||
|
||||
{% set showedRank, i = false, 0 %}
|
||||
{% for rank in guild_members if rank.members|length > 0 %}
|
||||
{% set rankStyle, i = getStyle(i), i + 1 %}
|
||||
{% set showedRank, i = false, 0 %}
|
||||
{% for rank in guild_members if rank.members|length > 0 %}
|
||||
{% set rankStyle, i = getStyle(i), i + 1 %}
|
||||
|
||||
{% for player in rank.members %}
|
||||
<tr bgcolor="{{ rankStyle }}">
|
||||
<td>
|
||||
{% if not showedRank %}{{ rank.rank_name }}{% endif %}
|
||||
{% set showedRank = true %}
|
||||
</td>
|
||||
{% for player in rank.members %}
|
||||
<tr bgcolor="{{ rankStyle }}">
|
||||
<td>
|
||||
{% if not showedRank %}{{ rank.rank_name }}{% endif %}
|
||||
{% set showedRank = true %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% set playerName = player.getName() %}
|
||||
<form action="?subtopic=guilds&action=change_nick&name={{ playerName }}&guild={{ guild_name }}" method="post">
|
||||
{{ getPlayerLink(playerName, true)|raw }}
|
||||
<td>
|
||||
{% set playerName = player.getName() %}
|
||||
<form action="?subtopic=guilds&action=change_nick&name={{ playerName }}&guild={{ guild_name }}" method="post">
|
||||
{{ getPlayerLink(playerName, true)|raw }}
|
||||
|
||||
{% set showGuildNick = false %}
|
||||
{% if player.getGuildNick() is not empty %}
|
||||
{% set showGuildNick = true %}
|
||||
{% set guildNickRaw = player.getGuildNick()|raw %}
|
||||
{% endif %}
|
||||
{% set showGuildNick = false %}
|
||||
{% if player.getGuildNick() is not empty %}
|
||||
{% set showGuildNick = true %}
|
||||
{% set guildNickRaw = player.getGuildNick()|raw %}
|
||||
{% endif %}
|
||||
|
||||
{% if logged %}
|
||||
{% if player.getId() in players_from_account_ids %}
|
||||
(<input type="text" name="nick" value="{{ guildNickRaw }}"><input type="submit" value="Change">)
|
||||
{% else %}
|
||||
{% if showGuildNick %} ({{ guildNickRaw }}){% endif %}
|
||||
{% endif %}
|
||||
{% if logged %}
|
||||
{% if player.getId() in players_from_account_ids %}
|
||||
(<input type="text" name="nick" value="{{ guildNickRaw }}"><input type="submit" value="Change">)
|
||||
{% else %}
|
||||
{% if showGuildNick %} ({{ guildNickRaw }}){% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if level_in_guild > rank.rank_level or isLeader %}
|
||||
{% if guildOwnerName != playerName %}
|
||||
<span style="font-size: 10px; float: right">
|
||||
{<a href="?subtopic=guilds&action=kick_player&guild={{ guild_name|url_encode }}&name={{ playerName|url_encode }}">KICK</a>}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if showGuildNick %} ({{ guildNickRaw }}){% endif %}
|
||||
{% endif %}
|
||||
</form>
|
||||
</td>
|
||||
{% if level_in_guild > rank.rank_level or isLeader %}
|
||||
{% if guildOwnerName != playerName %}
|
||||
<span style="font-size: 10px; float: right">
|
||||
{<a href="?subtopic=guilds&action=kick_player&guild={{ guild_name|url_encode }}&name={{ playerName|url_encode }}">KICK</a>}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if showGuildNick %} ({{ guildNickRaw }}){% endif %}
|
||||
{% endif %}
|
||||
</form>
|
||||
</td>
|
||||
|
||||
<td>{{ player.getVocationName() }}</td>
|
||||
<td>{{ player.getLevel() }}</td>
|
||||
<td>
|
||||
<span style="color: {% if player.isOnline() %} green;"><b>Online{% else %} red;"><b>Offline{% endif %}</b></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<td>{{ player.getVocationName() }}</td>
|
||||
<td>{{ player.getLevel() }}</td>
|
||||
<td>
|
||||
<span style="color: {% if player.isOnline() %} green;"><b>Online{% else %} red;"><b>Offline{% endif %}</b></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% set showedRank = false %}
|
||||
{% else %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
<td colspan="5">No guild members found.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br>
|
||||
{% set showedRank = false %}
|
||||
{% else %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
<td colspan="5">No guild members found.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div class="TableContainer">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text">Invited Characters</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="TableContainer">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text">Invited Characters</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="Table3" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="TableContentContainer">
|
||||
<table class="TableContent" width="100%">
|
||||
<tbody>
|
||||
<tr class="LabelH">
|
||||
<td><b>Name</b></td>
|
||||
</tr>
|
||||
<table class="Table3" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="TableContentContainer">
|
||||
<table class="TableContent" width="100%">
|
||||
<tbody>
|
||||
<tr class="LabelH">
|
||||
<td><b>Name</b></td>
|
||||
</tr>
|
||||
|
||||
{% set i = 0 %}
|
||||
{% for invited_player in invited_list if invited_list|length > 0 %}
|
||||
{% if invited_player.isLoaded() %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
{% set i = i + 1 %}
|
||||
{% set i = 0 %}
|
||||
{% for invited_player in invited_list if invited_list|length > 0 %}
|
||||
{% if invited_player.isLoaded() %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
{% set i = i + 1 %}
|
||||
|
||||
<td>
|
||||
{{ getPlayerLink(invited_player.getName(), true)|raw }}
|
||||
<td>
|
||||
{{ getPlayerLink(invited_player.getName(), true)|raw }}
|
||||
|
||||
{% if isVice %}
|
||||
<div style="float: right">
|
||||
{<a href="?subtopic=guilds&action=delete_invite&guild={{ guild_name|url_encode }}&name={{ invited_player.getName()|url_encode }}">Cancel Invitation</a>}
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
<td>
|
||||
No invited characters found.
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br>
|
||||
{% if isVice %}
|
||||
<div style="float: right">
|
||||
{<a href="?subtopic=guilds&action=delete_invite&guild={{ guild_name|url_encode }}&name={{ invited_player.getName()|url_encode }}">Cancel Invitation</a>}
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
<td>
|
||||
No invited characters found.
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div class="TableContainer">
|
||||
<table class="Table3" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="TableContentContainer">
|
||||
<table class="TableContent" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
{% if not logged %}
|
||||
<form action="?subtopic=accountmanagement&redirect={{ getGuildLink(guild_name|url_encode, false) }}" method="post">
|
||||
<td>
|
||||
{{ include('buttons.login.html.twig') }}
|
||||
</td>
|
||||
</form>
|
||||
{% else %}
|
||||
{% if show_accept_invite > 0 %}
|
||||
<form action="?subtopic=guilds&action=accept_invite&guild={{ guild_name|url_encode }}" method="post">
|
||||
<td>
|
||||
<input type="image" name="Accept Invite" alt="Accept Invite" src="{{ template_path }}/images/global/buttons/sbutton_acceptinvite.png" style="width: 120px; height: 20px;">
|
||||
</td>
|
||||
</form>
|
||||
{% endif %}
|
||||
{{ hook(constant('HOOK_GUILDS_AFTER_INVITED_CHARACTERS'), { 'guild': guild, 'isLeader': isLeader }) }}
|
||||
|
||||
{% if isVice %}
|
||||
<form action="?subtopic=guilds&action=invite&guild={{ guild_name|url_encode }}" method="post">
|
||||
<td>
|
||||
{% set button_name = 'Invite Character' %}
|
||||
{% set button_image = '_sbutton_invitecharacter' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</td>
|
||||
</form>
|
||||
<div class="TableContainer">
|
||||
<table class="Table3" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="TableContentContainer">
|
||||
<table class="TableContent" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
{% if not logged %}
|
||||
<form action="?subtopic=accountmanagement&redirect={{ getGuildLink(guild_name|url_encode, false) }}" method="post">
|
||||
<td>
|
||||
{{ include('buttons.login.html.twig') }}
|
||||
</td>
|
||||
</form>
|
||||
{% else %}
|
||||
{% if show_accept_invite > 0 %}
|
||||
<form action="?subtopic=guilds&action=accept_invite&guild={{ guild_name|url_encode }}" method="post">
|
||||
<td>
|
||||
<input type="image" name="Accept Invite" alt="Accept Invite" src="{{ template_path }}/images/global/buttons/sbutton_acceptinvite.png" style="width: 120px; height: 20px;">
|
||||
</td>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<form action="?subtopic=guilds&action=change_rank&guild={{ guild_name|url_encode }}" method="post">
|
||||
<td>
|
||||
{% set button_name = 'Edit Ranks' %}
|
||||
{% set button_image = '_sbutton_editranks' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</td>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if isVice %}
|
||||
<form action="?subtopic=guilds&action=invite&guild={{ guild_name|url_encode }}" method="post">
|
||||
<td>
|
||||
{% set button_name = 'Invite Character' %}
|
||||
{% set button_image = '_sbutton_invitecharacter' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</td>
|
||||
</form>
|
||||
|
||||
{% if players_from_account_in_guild|length > 0 %}
|
||||
<form action="?subtopic=guilds&action=leave_guild&guild={{ guild_name|url_encode }}" method="post">
|
||||
<td>
|
||||
{% set button_name = 'Leave Guild' %}
|
||||
{% set button_image = '_sbutton_leaveguild' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</td>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<form action="?subtopic=guilds&action=change_rank&guild={{ guild_name|url_encode }}" method="post">
|
||||
<td>
|
||||
{% set button_name = 'Edit Ranks' %}
|
||||
{% set button_image = '_sbutton_editranks' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</td>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<form action="{{ getLink('guilds') }}" method="post">
|
||||
<td style="float: right">
|
||||
{{ include('buttons.back.html.twig') }}
|
||||
</td>
|
||||
</form>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if players_from_account_in_guild|length > 0 %}
|
||||
<form action="?subtopic=guilds&action=leave_guild&guild={{ guild_name|url_encode }}" method="post">
|
||||
<td>
|
||||
{% set button_name = 'Leave Guild' %}
|
||||
{% set button_image = '_sbutton_leaveguild' %}
|
||||
{% include('buttons.base.html.twig') %}
|
||||
</td>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<form action="{{ getLink('guilds') }}" method="post">
|
||||
<td style="float: right">
|
||||
{{ include('buttons.back.html.twig') }}
|
||||
</td>
|
||||
</form>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,171 +1,171 @@
|
||||
<div class="TableContainer">
|
||||
{% if errors is not empty %}
|
||||
{% for error in errors %}
|
||||
<p class="error">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<table class="Table1" cellpadding="0" cellspacing="0" style="background-color: {{ config.lightborder }}">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text" >House Search</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
{% if errors is not empty %}
|
||||
{% for error in errors %}
|
||||
<p class="error">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<table class="Table1" cellpadding="0" cellspacing="0" style="background-color: {{ config.lightborder }}">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text" >House Search</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
Here you can see the list of all available houses, flats{{ guildString }}.
|
||||
Click on any view button to get more information about a house or adjust
|
||||
the search criteria and start a new search.
|
||||
<br><br>
|
||||
{% if cleanOldHouse is not empty or rentType != 'never' %}
|
||||
Every morning during global server save there is automatic house cleaning. Server delete house owners who have not logged in last {{ cleanOldHouse }} days{% if rentType != 'never' %} or have not paid {{ rentType }} house rent. Remember to leave money for a rent in {% if config.lua.bankSystem is not empty %}your house bank or {% else %}depo in same city where you have house!{% endif %}{% else %}.{% endif %}
|
||||
<br><br>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
Here you can see the list of all available houses, flats{{ guildString }}.
|
||||
Click on any view button to get more information about a house or adjust
|
||||
the search criteria and start a new search.
|
||||
<br><br>
|
||||
{% if cleanOldHouse is not empty or rentType != 'never' %}
|
||||
Every morning during global server save there is automatic house cleaning. Server delete house owners who have not logged in last {{ cleanOldHouse }} days{% if rentType != 'never' %} or have not paid {{ rentType }} house rent. Remember to leave money for a rent in {% if config.lua.bankSystem is not empty %}your house bank or {% else %}depo in same city where you have house!{% endif %}{% else %}.{% endif %}
|
||||
<br><br>
|
||||
{% endif %}
|
||||
|
||||
{% if houses is not empty or housesSearch %}
|
||||
<table border="0" cellspacing="1" cellpadding="4" width="100%">
|
||||
<tbody>
|
||||
<tr bgcolor="{{ config.vdarkborder }}">
|
||||
<td colspan="6" class="white"><b>Available {{ houseType }}{% if townName is not empty %} in {{ townName }}{% endif %} on <b>{{ config.lua.serverName }}</b></b></td>
|
||||
</tr>
|
||||
{% if houses is not empty or housesSearch %}
|
||||
<table border="0" cellspacing="1" cellpadding="4" width="100%">
|
||||
<tbody>
|
||||
<tr bgcolor="{{ config.vdarkborder }}">
|
||||
<td colspan="6" class="white"><b>Available {{ houseType }}{% if townName is not empty %} in {{ townName }}{% endif %} on <b>{{ config.lua.serverName }}</b></b></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
{% if houses is not empty %}
|
||||
<td width="40%"><b>Name</b></td>
|
||||
<td width="10%"><b>Size</b></td>
|
||||
<td width="10%"><b>Rent</b></td>
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
{% if houses is not empty %}
|
||||
<td width="40%"><b>Name</b></td>
|
||||
<td width="10%"><b>Size</b></td>
|
||||
<td width="10%"><b>Rent</b></td>
|
||||
|
||||
<td width="40%"><b>Status</b></td>
|
||||
<td> </td>
|
||||
{% elseif housesSearch %}
|
||||
<td>No {{ houseType }} with specified criterias.</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
<td width="40%"><b>Status</b></td>
|
||||
<td> </td>
|
||||
{% elseif housesSearch %}
|
||||
<td>No {{ houseType }} with specified criterias.</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
|
||||
{% if houses is not empty %}
|
||||
{% set i = 0 %}
|
||||
{% for house in houses %}
|
||||
{% set i = i + 1 %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
<td width="40%">
|
||||
{{ house.name }}
|
||||
</td>
|
||||
{% if houses is not empty %}
|
||||
{% set i = 0 %}
|
||||
{% for house in houses %}
|
||||
{% set i = i + 1 %}
|
||||
<tr bgcolor="{{ getStyle(i) }}">
|
||||
<td width="40%">
|
||||
{{ house.name }}
|
||||
</td>
|
||||
|
||||
<td width="10%">
|
||||
{{ house.size }}
|
||||
</td>
|
||||
<td width="10%">
|
||||
{{ house.size }}
|
||||
</td>
|
||||
|
||||
<td width="10%">
|
||||
{{ house.rent }} golds
|
||||
</td>
|
||||
<td width="10%">
|
||||
{{ house.rent }} golds
|
||||
</td>
|
||||
|
||||
<td width="40%">
|
||||
{{ house.rentedBy|raw }}
|
||||
</td>
|
||||
<td width="40%">
|
||||
{{ house.rentedBy|raw }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<form action="{{ getLink('houses/view') }}" method="post">
|
||||
<input type="hidden" name="house" value="{{ house.name }}">
|
||||
{{ include('buttons.view.html.twig') }}
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
{% endif %}
|
||||
<td>
|
||||
<form action="{{ getLink('houses/view') }}" method="post">
|
||||
<input type="hidden" name="house" value="{{ house.name }}">
|
||||
{{ include('buttons.view.html.twig') }}
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
{% endif %}
|
||||
|
||||
<form action="{{ getLink('houses') }}" method="post">
|
||||
<table border="0" cellspacing="1" cellpadding="4" width="100%">
|
||||
<tbody>
|
||||
<tr bgcolor="{{ config.vdarkborder }}">
|
||||
<td colspan="4" class="white"><b>House Search</b></td>
|
||||
</tr>
|
||||
<form action="{{ getLink('houses') }}" method="post">
|
||||
<table border="0" cellspacing="1" cellpadding="4" width="100%">
|
||||
<tbody>
|
||||
<tr bgcolor="{{ config.vdarkborder }}">
|
||||
<td colspan="4" class="white"><b>House Search</b></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td width="25%"><b>Town</b></td>
|
||||
<td width="25%"><b>Status</b></td>
|
||||
<td width="25%"><b>Order</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td width="25%"><b>Town</b></td>
|
||||
<td width="25%"><b>Status</b></td>
|
||||
<td width="25%"><b>Order</b></td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td valign="top" rowspan="2">
|
||||
{% set checked = false %}
|
||||
{% for id, name in config.towns if id > 0 %}
|
||||
{% if ((townId is empty and name is not empty) or id == townId) and not checked %}
|
||||
{% set variable = "checked" %}
|
||||
{% set checked = true %}
|
||||
{% else %}
|
||||
{% set variable = "" %}
|
||||
{% endif %}
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td valign="top" rowspan="2">
|
||||
{% set checked = false %}
|
||||
{% for id, name in config.towns if id > 0 %}
|
||||
{% if ((townId is empty and name is not empty) or id == townId) and not checked %}
|
||||
{% set variable = "checked" %}
|
||||
{% set checked = true %}
|
||||
{% else %}
|
||||
{% set variable = "" %}
|
||||
{% endif %}
|
||||
|
||||
<input type="radio" name="town" id="town_{{ id }}" value="{{ id }}"{% if variable is defined %} {{ variable }}{% endif %}>
|
||||
<label for="town_{{ id }}"> {{ name }}</label>
|
||||
<br>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<input type="radio" name="town" id="town_{{ id }}" value="{{ id }}"{% if variable is defined %} {{ variable }}{% endif %}>
|
||||
<label for="town_{{ id }}"> {{ name }}</label>
|
||||
<br>
|
||||
{% endfor %}
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<input type="radio" name="state" id="state_all" value=""{% if state is empty %} checked{% endif %}>
|
||||
<label for="state_all">all states</label><br>
|
||||
<td valign="top">
|
||||
<input type="radio" name="state" id="state_all" value=""{% if state is empty %} checked{% endif %}>
|
||||
<label for="state_all">all states</label><br>
|
||||
|
||||
<input type="radio" name="state" id="state_free" value="free"{% if state == 'free' %} checked{% endif %}>
|
||||
<label for="state_free">free</label><br>
|
||||
<input type="radio" name="state" id="state_free" value="free"{% if state == 'free' %} checked{% endif %}>
|
||||
<label for="state_free">free</label><br>
|
||||
|
||||
<input type="radio" name="state" id="state_rented" value="rented"{% if state == 'rented' %} checked{% endif %}>
|
||||
<label for="state_rented">rented</label><br>
|
||||
</td>
|
||||
<input type="radio" name="state" id="state_rented" value="rented"{% if state == 'rented' %} checked{% endif %}>
|
||||
<label for="state_rented">rented</label><br>
|
||||
</td>
|
||||
|
||||
<td valign="top" rowspan="2">
|
||||
<input type="radio" name="order" id="order_name" value=""{% if order is empty %} checked{% endif %}>
|
||||
<label for="order_name"> by name</label><br>
|
||||
<td valign="top" rowspan="2">
|
||||
<input type="radio" name="order" id="order_name" value=""{% if order is empty %} checked{% endif %}>
|
||||
<label for="order_name"> by name</label><br>
|
||||
|
||||
<input type="radio" name="order" id="order_size" value="size"{% if order == 'size' %} checked{% endif %}>
|
||||
<label for="order_size"> by size</label><br>
|
||||
<input type="radio" name="order" id="order_size" value="size"{% if order == 'size' %} checked{% endif %}>
|
||||
<label for="order_size"> by size</label><br>
|
||||
|
||||
<input type="radio" name="order" id="order_rent" value="rent"{% if order == 'rent' %} checked{% endif %}>
|
||||
<label for="order_rent"> by rent</label><br>
|
||||
</td>
|
||||
</tr>
|
||||
<input type="radio" name="order" id="order_rent" value="rent"{% if order == 'rent' %} checked{% endif %}>
|
||||
<label for="order_rent"> by rent</label><br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td valign="top">
|
||||
<input type="radio" name="type" id="type_all" value=""{% if type is empty %} checked{% endif %}>
|
||||
<label for="type"> all</label><br>
|
||||
<input type="radio" name="type" id="type_houses" value="houses"{% if type == 'houses' %} checked{% endif %}>
|
||||
<label for="type_houses"> houses and flats</label><br>
|
||||
<input type="radio" name="type" id="type_guildhalls" value="guildhalls"{% if type == 'guildhalls' %} checked{% endif %}>
|
||||
<label for="type_guildhalls"> guildhalls</label><br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<tr bgcolor="{{ config.darkborder }}">
|
||||
<td valign="top">
|
||||
<input type="radio" name="type" id="type_all" value=""{% if type is empty %} checked{% endif %}>
|
||||
<label for="type"> all</label><br>
|
||||
<input type="radio" name="type" id="type_houses" value="houses"{% if type == 'houses' %} checked{% endif %}>
|
||||
<label for="type_houses"> houses and flats</label><br>
|
||||
<input type="radio" name="type" id="type_guildhalls" value="guildhalls"{% if type == 'guildhalls' %} checked{% endif %}>
|
||||
<label for="type_guildhalls"> guildhalls</label><br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||
<tbody>
|
||||
<tr align="center">
|
||||
<td>
|
||||
{{ include('buttons.submit.html.twig') }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||
<tbody>
|
||||
<tr align="center">
|
||||
<td>
|
||||
{{ include('buttons.submit.html.twig') }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@@ -1,51 +1,51 @@
|
||||
<div class="TableContainer">
|
||||
{% if errors is not empty %}
|
||||
{% for error in errors %}
|
||||
<p class="error">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<table class="Table1" cellpadding="0" cellspacing="0" style="background-color: {{ config.lightborder }}">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text" >{{ houseName }}</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
{% if errors is not empty %}
|
||||
{% for error in errors %}
|
||||
<p class="error">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<table class="Table1" cellpadding="0" cellspacing="0" style="background-color: {{ config.lightborder }}">
|
||||
<div class="CaptionContainer">
|
||||
<div class="CaptionInnerContainer">
|
||||
<span class="CaptionEdgeLeftTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightTop" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionBorderTop" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionVerticalLeft" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<div class="Text" >{{ houseName }}</div>
|
||||
<span class="CaptionVerticalRight" style="background-image:url({{ template_path }}/images/content/box-frame-vertical.gif);"></span>
|
||||
<span class="CaptionBorderBottom" style="background-image:url({{ template_path }}/images/content/table-headline-border.gif);"></span>
|
||||
<span class="CaptionEdgeLeftBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table border="0" cellpadding="4" cellspacing="1" width="100%">
|
||||
<tr style="display: inline-flex;">
|
||||
<td><img src="{{ imgPath }}"></td>
|
||||
<td>
|
||||
{{ bedsMessage }} and has a size of <b>{{ houseSize }} square meters</b>.
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
<table border="0" cellpadding="4" cellspacing="1" width="100%">
|
||||
<tr style="display: inline-flex;">
|
||||
<td><img src="{{ imgPath }}"></td>
|
||||
<td>
|
||||
{{ bedsMessage }} and has a size of <b>{{ houseSize }} square meters</b>.
|
||||
|
||||
{% if rentType != 'never' %}
|
||||
The {{ rentType }} is <b>{{ houseRent }} gold</b> and will be debited to the bank account on <b>{{ config.lua.serverName }}</b>.
|
||||
{% endif %}
|
||||
<br>
|
||||
{% if rentType != 'never' %}
|
||||
The {{ rentType }} is <b>{{ houseRent }} gold</b> and will be debited to the bank account on <b>{{ config.lua.serverName }}</b>.
|
||||
{% endif %}
|
||||
<br>
|
||||
|
||||
{% if owner is not empty %}
|
||||
The house has been rented by <b>{{ owner|raw }}</b>.
|
||||
{% else %}
|
||||
No one has bought this house yet.
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if owner is not empty %}
|
||||
The house has been rented by <b>{{ owner|raw }}</b>.
|
||||
{% else %}
|
||||
No one has bought this house yet.
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<br><br>
|
||||
<br><br>
|
||||
|
@@ -12,7 +12,7 @@
|
||||
{% for value in ['server_path', 'mail_admin'] %}
|
||||
<div class="form-group mb-2">
|
||||
<label for="vars_{{ value }}">{{ locale['step_config_' ~ value] }}</label>
|
||||
<input class="form-control" type="text" name="vars[{{ value }}]" id="vars_{{ value }}"{% if session['var_' ~ value] is not null %} value="{{ session['var_' ~ value] }}"{% endif %}/>
|
||||
<input class="form-control" type="{% if value == 'mail_admin' %}email{% else %}text{% endif %}" name="vars[{{ value }}]" id="vars_{{ value }}"{% if session['var_' ~ value] is not null %} value="{{ session['var_' ~ value] }}"{% endif %}/>
|
||||
<small class="form-text text-muted">{{ locale['step_config_' ~ value ~ '_desc'] }}</small>
|
||||
</div>
|
||||
{% endfor %}
|
||||
@@ -43,9 +43,9 @@
|
||||
<input type="checkbox" name="vars[usage]" id="vars_usage" value="1"{% if session['var_usage'] is null or session['var_usage'] == 1 %} checked{% endif %}/>
|
||||
<small class="form-text text-muted d-block">{{ locale.step_config_usage_desc }}</small>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-center m-3">
|
||||
{{ buttons|raw }}
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</form>
|
||||
|
@@ -4,10 +4,11 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<input width="120" height="18" border="0" type="image" src="{{ template_path }}/images/global/buttons/sbutton_back.gif" alt="Back" name="Back" />
|
||||
{% set button_name = 'Back' %}
|
||||
{{ include('buttons.base.html.twig') }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</form>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -12,7 +12,7 @@
|
||||
<span class="CaptionEdgeRightBottom" style="background-image:url({{ template_path }}/images/content/box-frame-edge.gif);"></span>
|
||||
</div>
|
||||
</div>
|
||||
<table class="Table1" cellpadding="0" cellspacing="0" style="background-color: {{ config.lightborder }}">
|
||||
<table class="Table5" cellpadding="0" cellspacing="0" style="background-color: {{ config.lightborder }}">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="InnerTableContainer">
|
||||
|
@@ -16,6 +16,3 @@
|
||||
Please turn it on, or be aware that some features on this website will not work correctly.
|
||||
</div>
|
||||
</noscript>
|
||||
{% if config.recaptcha_enabled %}
|
||||
<script src="https://www.google.com/recaptcha/api.js{% if config('recaptcha_type') == 'v3' %}?render={{ config.recaptcha_site_key }}{% endif %}"></script>
|
||||
{% endif %}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user