Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6e221fe469 | ||
![]() |
679e08ec11 | ||
![]() |
603495ca97 | ||
![]() |
4c6af13574 | ||
![]() |
3fcbd42445 | ||
![]() |
e6d2e363d5 | ||
![]() |
0a067577a3 | ||
![]() |
a5b599088a | ||
![]() |
51ba514d2a |
@ -1,19 +0,0 @@
|
|||||||
# EditorConfig is awesome: https://EditorConfig.org
|
|
||||||
|
|
||||||
# top-most EditorConfig file
|
|
||||||
root = true
|
|
||||||
|
|
||||||
# with a newline ending every file
|
|
||||||
[*]
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = 4
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
||||||
[{composer.json,package.json}]
|
|
||||||
indent_style = space
|
|
||||||
|
|
||||||
[{package.json, *.yml}]
|
|
||||||
indent_size = 2
|
|
13
.gitattributes
vendored
@ -1,13 +0,0 @@
|
|||||||
* text=auto
|
|
||||||
.gitattributes export-ignore
|
|
||||||
.gitignore export-ignore
|
|
||||||
.github export-ignore
|
|
||||||
.editorconfig export-ignore
|
|
||||||
_config.yml export-ignore
|
|
||||||
release.sh export-ignore
|
|
||||||
|
|
||||||
# cypress
|
|
||||||
cypress export-ignore
|
|
||||||
cypress.config.js export-ignore
|
|
||||||
|
|
||||||
*.sh text eol=lf
|
|
12
.github/FUNDING.yml
vendored
@ -1,12 +0,0 @@
|
|||||||
# These are supported funding model platforms
|
|
||||||
|
|
||||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
|
||||||
patreon: # Replace with a single Patreon username
|
|
||||||
open_collective: # Replace with a single Open Collective username
|
|
||||||
ko_fi: # Replace with a single Ko-fi username
|
|
||||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
||||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
||||||
liberapay: # Replace with a single Liberapay username
|
|
||||||
issuehunt: # Replace with a single IssueHunt username
|
|
||||||
otechie: # Replace with a single Otechie username
|
|
||||||
custom: paypal.me/slawkens # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
|
29
.github/ISSUE_TEMPLATE.md
vendored
@ -1,29 +0,0 @@
|
|||||||
<!--
|
|
||||||
Please use this issue tracker only for reporting MyAAC bugs.
|
|
||||||
|
|
||||||
If you need support, please use the discord server:
|
|
||||||
|
|
||||||
- https://discord.gg/2J39Wus (we have an own channel named #my-aac there)
|
|
||||||
|
|
||||||
or use otland support boards:
|
|
||||||
|
|
||||||
- https://otland.net/forums/support.16/
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Server configuration
|
|
||||||
- Operating System:
|
|
||||||
- Web Server (+ version):
|
|
||||||
- PHP Version:
|
|
||||||
- Server name and version (for example: TFS 0.3):
|
|
||||||
- MyAAC Version:
|
|
||||||
|
|
||||||
### Client configuration (Your Computer)
|
|
||||||
|
|
||||||
- Browser:
|
|
||||||
- Operating System:
|
|
||||||
|
|
||||||
### Description:
|
|
||||||
|
|
||||||
|
|
||||||
### Steps To Reproduce:
|
|
162
.github/workflows/cypress.yml
vendored
@ -1,162 +0,0 @@
|
|||||||
name: Cypress
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
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: [ '8.1', '8.2', '8.3' ]
|
|
||||||
ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration)
|
|
||||||
name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }})
|
|
||||||
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@v4
|
|
||||||
with:
|
|
||||||
ref: main
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
- run: npm ci
|
|
||||||
|
|
||||||
- name: Checkout TFS
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
if: matrix.ots == 'tfs-1.4'
|
|
||||||
with:
|
|
||||||
repository: otland/forgottenserver
|
|
||||||
ref: 1.4
|
|
||||||
path: ots
|
|
||||||
|
|
||||||
- name: Checkout TFS
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
if: matrix.ots == 'tfs-master'
|
|
||||||
with:
|
|
||||||
repository: otland/forgottenserver
|
|
||||||
ref: master
|
|
||||||
path: ots
|
|
||||||
|
|
||||||
- name: Checkout Canary
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
if: matrix.ots == 'canary-3.1.2'
|
|
||||||
with:
|
|
||||||
repository: opentibiabr/canary
|
|
||||||
ref: v3.1.2
|
|
||||||
path: ots
|
|
||||||
|
|
||||||
- name: Import OTS Schema
|
|
||||||
run: |
|
|
||||||
mysql -uroot -proot myaac < ots/schema.sql
|
|
||||||
|
|
||||||
- name: Rename config.lua
|
|
||||||
run: mv ots/config.lua.dist ots/config.lua
|
|
||||||
|
|
||||||
- name: Replace mysqlUser (TFS 1.4)
|
|
||||||
uses: jacobtomlinson/gha-find-replace@v3
|
|
||||||
if: matrix.ots == 'tfs-1.4'
|
|
||||||
with:
|
|
||||||
find: 'mysqlUser = "forgottenserver"'
|
|
||||||
replace: 'mysqlUser = "root"'
|
|
||||||
regex: false
|
|
||||||
include: 'ots/config.lua'
|
|
||||||
|
|
||||||
- name: Replace mysqlPass (TFS 1.4)
|
|
||||||
uses: jacobtomlinson/gha-find-replace@v3
|
|
||||||
if: matrix.ots == 'tfs-1.4'
|
|
||||||
with:
|
|
||||||
find: 'mysqlPass = ""'
|
|
||||||
replace: 'mysqlPass = "root"'
|
|
||||||
regex: false
|
|
||||||
include: 'ots/config.lua'
|
|
||||||
|
|
||||||
- name: Replace mysqlDatabase (TFS 1.4)
|
|
||||||
uses: jacobtomlinson/gha-find-replace@v3
|
|
||||||
if: matrix.ots == 'tfs-1.4'
|
|
||||||
with:
|
|
||||||
find: 'mysqlDatabase = "forgottenserver"'
|
|
||||||
replace: 'mysqlDatabase = "myaac"'
|
|
||||||
regex: false
|
|
||||||
include: 'ots/config.lua'
|
|
||||||
|
|
||||||
- name: Replace mysqlDatabase (Canary)
|
|
||||||
uses: jacobtomlinson/gha-find-replace@v3
|
|
||||||
if: matrix.ots == 'canary-3.1.2'
|
|
||||||
with:
|
|
||||||
find: 'mysqlDatabase = "otservbr-global"'
|
|
||||||
replace: 'mysqlDatabase = "myaac"'
|
|
||||||
regex: false
|
|
||||||
include: 'ots/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@v4
|
|
||||||
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-${{ hashFiles('**/composer.json') }}
|
|
||||||
|
|
||||||
- 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@v6
|
|
||||||
env:
|
|
||||||
CYPRESS_URL: http://localhost:8080
|
|
||||||
CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/ots
|
|
||||||
|
|
||||||
- name: Save screenshots
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: cypress-screenshots-${{ matrix.php-versions }}-${{ matrix.ots }}
|
|
||||||
path: cypress/screenshots
|
|
||||||
|
|
||||||
- name: Upload Cypress Videos
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: cypress-videos-${{ matrix.php-versions }}-${{ matrix.ots }}
|
|
||||||
path: cypress/videos
|
|
||||||
|
|
||||||
- name: Upload PHP Logs
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: php-log-${{ matrix.php-versions }}-${{ matrix.ots }}
|
|
||||||
path: php.log
|
|
16
.github/workflows/phplint.yml
vendored
@ -1,16 +0,0 @@
|
|||||||
name: PHP Linting
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
phplint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: overtrue/phplint@8.2
|
|
||||||
with:
|
|
||||||
path: .
|
|
||||||
options: --exclude=*.log
|
|
46
.github/workflows/phpstan.yml
vendored
@ -1,46 +0,0 @@
|
|||||||
name: "PHPStan"
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tests:
|
|
||||||
name: PhpStan on PHP ${{ matrix.php-versions }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
php-versions: [ '8.1', '8.2', '8.3' ]
|
|
||||||
steps:
|
|
||||||
- name: "Checkout"
|
|
||||||
uses: "actions/checkout@v4"
|
|
||||||
|
|
||||||
- name: "Install PHP"
|
|
||||||
uses: "shivammathur/setup-php@v2"
|
|
||||||
with:
|
|
||||||
coverage: "none"
|
|
||||||
extensions: "intl, zip"
|
|
||||||
ini-values: "memory_limit=-1"
|
|
||||||
php-version: "${{ matrix.php-version }}"
|
|
||||||
|
|
||||||
- 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@v4
|
|
||||||
with:
|
|
||||||
path: ${{ steps.composer-cache.outputs.dir }}
|
|
||||||
# Use composer.json for key, if composer.lock is not committed.
|
|
||||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
|
||||||
restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
|
||||||
|
|
||||||
- name: "Install composer dependencies"
|
|
||||||
run: "composer install"
|
|
||||||
|
|
||||||
- name: "Run PHPStan"
|
|
||||||
run: "/usr/bin/php vendor/bin/phpstan analyse"
|
|
78
.gitignore
vendored
@ -1,78 +0,0 @@
|
|||||||
Thumbs.db
|
|
||||||
.DS_Store
|
|
||||||
.idea
|
|
||||||
|
|
||||||
#
|
|
||||||
/.htaccess
|
|
||||||
lua
|
|
||||||
|
|
||||||
# composer
|
|
||||||
composer.phar
|
|
||||||
vendor
|
|
||||||
|
|
||||||
# npm
|
|
||||||
node_modules
|
|
||||||
tools/ext
|
|
||||||
|
|
||||||
# cypress
|
|
||||||
cypress.env.json
|
|
||||||
cypress/e2e/2-advanced-examples
|
|
||||||
cypress/screenshots
|
|
||||||
|
|
||||||
# created by release.sh
|
|
||||||
releases
|
|
||||||
tmp
|
|
||||||
|
|
||||||
config.local.php
|
|
||||||
|
|
||||||
# all custom templates
|
|
||||||
templates/*
|
|
||||||
!templates/tibiacom
|
|
||||||
!templates/kathrine
|
|
||||||
|
|
||||||
# guild images
|
|
||||||
images/guilds/*
|
|
||||||
!images/guilds/default.gif
|
|
||||||
|
|
||||||
# editor images
|
|
||||||
images/editor/*
|
|
||||||
!images/editor/index.html
|
|
||||||
|
|
||||||
# gallery images
|
|
||||||
images/gallery/*
|
|
||||||
!images/gallery/index.html
|
|
||||||
!images/gallery/demon.jpg
|
|
||||||
!images/gallery/demon_thumb.gif
|
|
||||||
|
|
||||||
# cache
|
|
||||||
system/cache/*
|
|
||||||
!system/cache/index.html
|
|
||||||
!system/cache/twig/index.html
|
|
||||||
!system/cache/signatures/index.html
|
|
||||||
!system/cache/plugins/index.html
|
|
||||||
!system/cache/persistent/index.html
|
|
||||||
|
|
||||||
# logs
|
|
||||||
system/logs/*
|
|
||||||
!system/logs/index.html
|
|
||||||
|
|
||||||
# data
|
|
||||||
system/data/*
|
|
||||||
!system/data/index.html
|
|
||||||
|
|
||||||
# php sessions
|
|
||||||
system/php_sessions/*
|
|
||||||
!system/php_sessions/index.html
|
|
||||||
|
|
||||||
# plugins
|
|
||||||
plugins/*
|
|
||||||
!plugins/.htaccess
|
|
||||||
!plugins/example.json
|
|
||||||
!plugins/account-create-hint.json
|
|
||||||
!plugins/account-create-hint
|
|
||||||
!plugins/email-confirmed-reward.json
|
|
||||||
!plugins/email-confirmed-reward
|
|
||||||
landing
|
|
||||||
|
|
||||||
# system
|
|
||||||
system/functions_custom.php
|
|
@ -1,21 +1,7 @@
|
|||||||
<IfModule mod_autoindex.c>
|
Options -Indexes -MultiViews
|
||||||
Options -Indexes
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
<IfModule mod_negotiation.c>
|
RewriteEngine On
|
||||||
Options -MultiViews
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
<FilesMatch "^(.*\.md|.*\.json|.*\.dist|.*\.sql|CHANGELOG|README|composer\.lock)$">
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
Require all denied
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
</FilesMatch>
|
RewriteRule ^.*$ index.php [L]
|
||||||
|
|
||||||
<IfModule mod_rewrite.c>
|
|
||||||
RewriteEngine On
|
|
||||||
|
|
||||||
#RewriteBase /myaac/
|
|
||||||
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
|
||||||
RewriteRule ^.*$ index.php [L]
|
|
||||||
</IfModule>
|
|
390
CHANGELOG
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
[0.7.5 - 04.01.2017]
|
||||||
|
* fixed bug on othire with config.account_premium_days
|
||||||
|
* fixed bug on TFS 1.x when online_afk is enabled
|
||||||
|
* warning about leaving news page with changes
|
||||||
|
* added player status to tibiacom top 5 highscores box
|
||||||
|
* save detected country on create account in session
|
||||||
|
* fixed getPremDays and isPremium functions (newest 11.x engines are bugged when it comes to PACC, its not fault of MyAAC)
|
||||||
|
* fix when there are no changelogs or highscores yet
|
||||||
|
* small fix regarding getTopPlayers function which was ignoring $limit variable
|
||||||
|
* fixed news adding when type != ARTICLE
|
||||||
|
* fixed template path finding
|
||||||
|
* fixed displaying article_text when it was empty saved
|
||||||
|
|
||||||
|
[0.7.4 - 24.12.2017]
|
||||||
|
* fixed mysql fatal error on tibiacom template - top 5 box
|
||||||
|
* fixed displaying of level percent bar on tibian signature
|
||||||
|
* inform user about Twig cache failure on installation, instead of http 500 error
|
||||||
|
* when dir system/cache is not writable by the webserver, then show some nice notice to the user about it instead of http 500 error
|
||||||
|
* remember client version select and usage stats checkbox in session on install
|
||||||
|
* automatically update highscores_ids_hidden for users who installed myaac before (migration)
|
||||||
|
|
||||||
|
[0.7.3 - 18.12.2017]
|
||||||
|
* auto generate myaac cache & session prefix on install to be unique across installations
|
||||||
|
* fixed hiding shop system menu on tibiacom template when disabled in config
|
||||||
|
* prevent adding duplicated newses with installation
|
||||||
|
* some changes to sample characters: chanced town_id to 1, posx: 1000, posy: 1000, posz: 1000 and default group_id to 1 so you can change in-game outfits and they will be used
|
||||||
|
* added version 772 constant to install client choose (OTHire)
|
||||||
|
* better solution for hidding samples (configurable) - highscores_ids_hidden
|
||||||
|
* fixed account.login redirect not working on tibiacom template
|
||||||
|
* installation: warn about wrong admin account name/id and password
|
||||||
|
* fixed last menu closing in tibiacom template
|
||||||
|
* updated polish locale (translation) on install
|
||||||
|
* (internal) removed some duplicated code on install finish
|
||||||
|
* (internal) renamed installation step files to be in correct order
|
||||||
|
* added TODO file
|
||||||
|
|
||||||
|
[0.7.1 - 13.12.2017]
|
||||||
|
* added changelog menu item to kathrine template
|
||||||
|
* fixed some php short tag in changelogs page
|
||||||
|
* fixed guild change description back button
|
||||||
|
* removed duplicated "Support List" menu item from tibiacom template
|
||||||
|
* changed some notice when version check is failed
|
||||||
|
* (internal) moved changelog to twig
|
||||||
|
|
||||||
|
[0.7.0 - 20.11.2017]
|
||||||
|
* moved template menus to database, they're now dynamically loaded
|
||||||
|
* added anonymous usage statistics reporting (only if user agrees, first usage report will be send after 7 days)
|
||||||
|
* you can edit them in Admin Panel under 'Menus' option
|
||||||
|
* you can also add custom links, like http://google.pl
|
||||||
|
* added networks (facebook and twitter) and highscores (top 5) boxes to tibiacom template, configurable in templates/tibiacom/config.php
|
||||||
|
* added news ticker for kathrine template
|
||||||
|
* added featured article to tibiacom template (you can add them with add news button)
|
||||||
|
* added tinymce editor to 'Pages' in admin panel
|
||||||
|
* added links to edit/delete/hide custom page directly from page
|
||||||
|
* update forum post after editing news (when forum post has been created)
|
||||||
|
* enabled code plugin for tinymce which enabled raw html code editing
|
||||||
|
* removed videos pages, as it can be easily added using custom Menus and Pages with insert Media
|
||||||
|
* removed bug_report configurable, its now enabled by default
|
||||||
|
* log some error info when mail cannot be send on account create
|
||||||
|
* twig getLink function will now return with full url (BASE_URL included)
|
||||||
|
* verify install post values directly on config page and display error
|
||||||
|
* updated tinymce to version 4.7.2 (from 4.7.0)
|
||||||
|
* updated phpmailer to version 5.2.26 (from 5.2.23)
|
||||||
|
* (#30) (fix) recovering account on servers that doesn't support salts
|
||||||
|
* (fix) account email confirm function
|
||||||
|
* (fix) showing changelog with urls in Admin Panel
|
||||||
|
* (fix) uninstalling plugin
|
||||||
|
* (fix) polls box in tibiacom template
|
||||||
|
* (fix) remove hooks from db on plugin deinstall
|
||||||
|
* (fix) some weird include possibilities with forum and account actions (verify action name)
|
||||||
|
* (fix) loading hooks from plugin installed from command line
|
||||||
|
* (fix) some changelog PHP Notice warning
|
||||||
|
* (internal) moved uninstall logic to Plugins class
|
||||||
|
* (internal) moved tibiacom boxes to separate directory
|
||||||
|
* (internal) moved news tickers to twig template
|
||||||
|
* (internal) moved Forum class to separate file
|
||||||
|
* (internal) moved deprecated functions to compat.php
|
||||||
|
* (internal) added some compat functions that are used by shop system
|
||||||
|
* (internal) renamed constant TICKET -> TICKER
|
||||||
|
* (internal) shortened message functions
|
||||||
|
|
||||||
|
[0.6.6 - 22.10.2017]
|
||||||
|
* fixed some php fatal error on spells page
|
||||||
|
* changed spells.vocations field in db size to 300
|
||||||
|
* please reload your spells after this update!
|
||||||
|
|
||||||
|
[0.6.5 - 21.10.2017]
|
||||||
|
* fixed displaying custom pages
|
||||||
|
* fixed adding new group forum board
|
||||||
|
|
||||||
|
[0.6.4 - 20.10.2017]
|
||||||
|
* reverted OTS_Account::getLastLogin() cause its used by tibia11-login plugin
|
||||||
|
|
||||||
|
[0.6.3 - 20.10.2017]
|
||||||
|
* fixed creating account
|
||||||
|
* fixed viewing thread without being logged
|
||||||
|
* fixed showing premium account status
|
||||||
|
|
||||||
|
[0.6.2 - 20.10.2017]
|
||||||
|
* added forums for guilds and groups
|
||||||
|
* added nice looking menu for my account page in default template
|
||||||
|
* new command line tool: install_plugin.php - can be used to install plugins from command line. Usage: "php install_plugin.php path_to_file"
|
||||||
|
* added new tooltip to view characters equipment item name and monster loot
|
||||||
|
* added items.xml loader class and weapons.xml loader class
|
||||||
|
* minimum PHP version to install AAC is now 5.3.0 cause of Anonymous functions used by Twig
|
||||||
|
* Added 'Are you sure?' popup when uninstalling plugin
|
||||||
|
* added some warnings when plugin json file is incomplete
|
||||||
|
* fixed showing in characters ban expires when is unlimited
|
||||||
|
* fixed displaying monster loot when item.name in loot is used instead of item.id
|
||||||
|
* load also runes into spells table
|
||||||
|
* display plugin uninstall option only if its possible
|
||||||
|
* after changing template you will be redirected to latest viewed page
|
||||||
|
* display gallery add image form only on main gallery page
|
||||||
|
* (internal) moved most of guilds html-in-php code to twig
|
||||||
|
* (internal) moved spells page to twig template
|
||||||
|
* (internal) removed useless spells.spell column that was duplicate of spells.words
|
||||||
|
* (internal) save monster loot in database in json format instead loading it every time from xml file
|
||||||
|
* (internal) store monster voices and immunities in json format
|
||||||
|
* (internal) moved buttons to separate template
|
||||||
|
* (internal) moved online search form to twig
|
||||||
|
* (internal) added new function getItemNameById($id)
|
||||||
|
* (internal) Moved plugin install logic to a new class: Plugins
|
||||||
|
* (internal) changed spells.vocations database field to store json data instead of comma separated
|
||||||
|
* (internal) removed $hook_types array, using defined() and constant() functions now
|
||||||
|
* (internal) removed useless monsters.gfx_name field from database
|
||||||
|
* (internal) renamed database field monsters.hide_creature to hidden
|
||||||
|
* (internal) renamed existing Items class to Items_Images
|
||||||
|
* (internal) optimized Spells class
|
||||||
|
* (internal) new function: OTS_Guild::hasMember(OTS_Player $player)
|
||||||
|
* (internal) new function: Forum::hasAccess($board_id)
|
||||||
|
|
||||||
|
[0.6.1 - 17.10.2017]
|
||||||
|
* fixed signatures loading
|
||||||
|
* new configurable: session_prefix, to allow more websites on one machine (must be unique for every website on your dedicated server!)
|
||||||
|
* better error handling for monsters and spells loader (save errors to system/logs/error.log)
|
||||||
|
* check if file exist before loading (monsters and spells)
|
||||||
|
* (internal) Account::getAccess() = Account::getGroupId()
|
||||||
|
* (internal) moved account actions (pages) to account/ directory
|
||||||
|
* (internal) moved forum actions (pages) to forum/ directory
|
||||||
|
* (internal) moved forum.edit_post to twig templates
|
||||||
|
|
||||||
|
[0.6.0 - 16.10.2017]
|
||||||
|
* added faq management - add/edit/move/hide/delete from website
|
||||||
|
* new account.login view for tibiacom template
|
||||||
|
* monsters and spells are now being loaded at the installation of the AAC
|
||||||
|
* fix for php versions under 5.5 where empty() function supported only variables
|
||||||
|
* added missing change email and change info buttons to account.management default template
|
||||||
|
* added new indicator icons for create account, create character and change character name
|
||||||
|
* fixed config loader when some inline comments are present
|
||||||
|
* fixed editing page in admin panel that contains some html code
|
||||||
|
* fixed forum new post on mac os and some specific mysql versions
|
||||||
|
* attempt to fix incorrect views counter behavior (its resetting to 0 in some cases)
|
||||||
|
* enabled cache http headers for signatures
|
||||||
|
* check if monster file exist before loading it
|
||||||
|
* fixed if plugin zip file name contains dot (.)
|
||||||
|
* renamed screenshots to gallery and movies to videos
|
||||||
|
* moved install pages to twig
|
||||||
|
* fixed Account::getGuildAccess function
|
||||||
|
* removed never used library from sources - dwoo
|
||||||
|
* moved check_* functions to class Validator
|
||||||
|
* from now all validators ajax requests will fire onblur instead of onkeyup
|
||||||
|
* ajax requests returns now json instead of xml
|
||||||
|
* added 404 response when file is not found
|
||||||
|
|
||||||
|
[0.5.1 - 11.10.2017]
|
||||||
|
* fixed forum add/edit board
|
||||||
|
* new configurable: highscores_length, how much highscores to display
|
||||||
|
* fixed highscores links (ALL, previous and next page)
|
||||||
|
* update templates cache when installing/uninstalling plugin
|
||||||
|
* moved character deaths and frags table generation to twig
|
||||||
|
* fixed some bug when you uninstall plugin and then try to install again on the same page
|
||||||
|
* check if plugin exist before uninstalling
|
||||||
|
* fixed some warning in OTS_Base_DB
|
||||||
|
|
||||||
|
[0.5.0 - 10.10.2017]
|
||||||
|
* moved .htaccess rules to plain php (index.php)
|
||||||
|
* updated tinymce to the latest (4.7.0) version, you can now embed code, for example youtube videos
|
||||||
|
* added option to uninstall plugin
|
||||||
|
* added option to require specified myaac, php or database version for plugins, without that plugin won't be installed
|
||||||
|
* change accountmanagement links to use friendly_urls
|
||||||
|
* fixed creating new forum thread
|
||||||
|
* sample characters are now assigned to admin account and have group_id 4 to not be shown on highscores
|
||||||
|
* added links loaded from database to admin panel - for future plugins
|
||||||
|
* print some info to error.log when can't find config.lua
|
||||||
|
* some fixes in account changecomment action
|
||||||
|
* show info when account name/number or password is empty on login
|
||||||
|
* fixed showing account login errors
|
||||||
|
* added few characters hooks
|
||||||
|
* fixed some kathrine template js bug when shop is disabled
|
||||||
|
* you can now use slash '/' in custom pages loaded from database
|
||||||
|
* added new twig function getLink that convert link taking into account config.friendly_urls
|
||||||
|
* internalLayoutLink -> getLink
|
||||||
|
|
||||||
|
[0.4.3 - 05.10.2017]
|
||||||
|
* better config loader taken from latest gesior, you can now include files in your config by doing dofile('config.local.lua')
|
||||||
|
* fixed country detection in create account
|
||||||
|
* fixed showing of character deaths and frags
|
||||||
|
* fixed https://otland.net/threads/myaac-v0-0-1.251454/page-13#post-2466303
|
||||||
|
* fixed https://otland.net/threads/myaac-v0-0-1.251454/page-13#post-2466313
|
||||||
|
* fixed rook sample, which will now have level 1, 150 health, 0 mana, and 400 cap.
|
||||||
|
* fixed samples being deleted by tfs 1.0+ cause of 'deletion' field set to 1
|
||||||
|
* pages loaded from database have higher priority than normal .php pages, so they will be loaded first if they exist
|
||||||
|
* moved many pages to twig templates
|
||||||
|
* change download client links from clients.halfaway.net to tibia-clients.com
|
||||||
|
* added bugtracker to kathrine template
|
||||||
|
* added CREDITS file
|
||||||
|
|
||||||
|
[0.4.2 - 14.09.2017]
|
||||||
|
* updated version number
|
||||||
|
|
||||||
|
[0.4.1 - 13.09.2017]
|
||||||
|
* fixed log in to admin panel
|
||||||
|
* fixed File is not .zip plugin upload error
|
||||||
|
|
||||||
|
[0.4.0 - 13.09.2017
|
||||||
|
* added option to add/edit/delete/hide/move forum boards
|
||||||
|
* moved some of HTML-in-PHP code to Twig templates
|
||||||
|
* added bug_report configurable which can enable/disable bug tracker
|
||||||
|
* log errors instead of showing them to users with system directories
|
||||||
|
* fix when $_SERVER['HTTP_ACCEPT_ENCODING'] is not set
|
||||||
|
* when it fails to load config.lua it will output error also to error.log
|
||||||
|
* automatically detect json file in .zip instead of basing on filename (admin panel - plugins)
|
||||||
|
* hopefully fixed the error with "The file you are trying to upload is not a .zip file. Please try again."
|
||||||
|
* fixed wrong name of table in bugtracker
|
||||||
|
* fixed some bugs in bugtracker
|
||||||
|
* added report bug link in templates
|
||||||
|
* fixed some rare error when user is logged in for longer than 15 minutes and tries to login again
|
||||||
|
* fixed some grammar errors
|
||||||
|
* some small improvements
|
||||||
|
* fixed some separators in kathrine template
|
||||||
|
|
||||||
|
[0.3.0 - 28.08.2017]
|
||||||
|
* added administration panel for screenshots management with auto thumbnail generator and image auto-resizing
|
||||||
|
* added Twig template engine and moved some html-in-php code to it
|
||||||
|
* automatically detect player country based on user location (IP) on create account
|
||||||
|
* player sex (gender) is now configurable at $config['genders']
|
||||||
|
* fixed recovering account and changing password when salt is enabled
|
||||||
|
* fixed installing samples when for example Rook Sample already exist and other samples not
|
||||||
|
* fixed some mysql error when character you trying to create already exist
|
||||||
|
* fixed some warning when you select nonexistent country
|
||||||
|
* password change minimal/maximal length notice is now more precise
|
||||||
|
* added 'enabled' field in myaac_hooks table, which can enable or disable specified hook
|
||||||
|
* removed DEFAULT '' for TEXT field. It didn't worked under some systems like MAC OS X.
|
||||||
|
* minimum PHP version to install the MyAAC is now 5.2.0 cause of pathinfo (extension) function
|
||||||
|
* removed unused admin stylish template
|
||||||
|
* removed some unused cities field from myaac_spells table
|
||||||
|
* moved news adding at installation from schema.sql to finish.php
|
||||||
|
* some optimizations
|
||||||
|
|
||||||
|
[0.2.4 - 09.06.2017]
|
||||||
|
* fixed invite to guild
|
||||||
|
* added id field on monsters, so you can delete them in phpmyadmin
|
||||||
|
* fixed adding some creatures with ' and "
|
||||||
|
* fixed when there are spaces at beginning of the file (creatures)
|
||||||
|
* fixed when file is unable to parse (creatures)
|
||||||
|
* fixed typo loss_items => loss_containers
|
||||||
|
* more elegant way of showing message on reload creatures and spells
|
||||||
|
|
||||||
|
[0.2.3 - 31.05.2017]
|
||||||
|
* fixed guild management on OTHire 0.0.3
|
||||||
|
* set default skills to 10 when creating new character
|
||||||
|
* fixed displaying of "Create forum thread" in newses
|
||||||
|
* fixed deleting guild on servers that use players.rank_id field
|
||||||
|
* fixed phpmailer class loading (https://otland.net/threads/myaac-v0-0-1.251454/page-8#post-2445222)
|
||||||
|
* fixed displaying vocation amount on online page
|
||||||
|
* better support for custom vocations, you just need to set in config vocations_amount to yours.
|
||||||
|
* fixed huge space in player name (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444328)
|
||||||
|
* fixed Undefined variable (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444034)
|
||||||
|
* fixed Undefined offset (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444035)
|
||||||
|
|
||||||
|
[0.2.2 - 22.05.2017]
|
||||||
|
* added missing cache/signature directory
|
||||||
|
* fixed https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2443868
|
||||||
|
|
||||||
|
[0.2.1 - 21.05.2017]
|
||||||
|
* added Swedish translation by Sizaro
|
||||||
|
* fixed some bugs with installlation & characters & houses
|
||||||
|
|
||||||
|
[0.2.0 - 21.05.2017]
|
||||||
|
* added option to change character sex for premium points
|
||||||
|
* moved site_closed to database, now you can close your site through admin panel
|
||||||
|
* added option to admin panel: clear cache
|
||||||
|
* added experiencetable_rows configurable
|
||||||
|
* optimized OTS_Account->getGroupId(), now its using like 20 queries less
|
||||||
|
* optimized OTS_Player->load($id) function, should be much faster now
|
||||||
|
* fixed displaying on highscores special outfits
|
||||||
|
* fixed skull images displaying
|
||||||
|
* fixed displaying unlimited premium account
|
||||||
|
* fixed bug where players.lookaddons doesn't exist (OTHire etc.) (https://otland.net/threads/myaac-v0-0-1.251454/page-6#post-2442407)
|
||||||
|
* fixed signature tibian for OTHire and other servers that doesnt use accounts.premdays field
|
||||||
|
* fixed when player name in signature containst space
|
||||||
|
* don't show "Create forum thread" when editing
|
||||||
|
* fixed red color table after create account
|
||||||
|
* updated download links, as clients.halfaway.net isn't working anymore
|
||||||
|
* fixed some bugs while installing when field `email_next` or `hidden` already exist
|
||||||
|
* fixed movies unexpected comment
|
||||||
|
* added template_place_holder('center_top') to kathrine template
|
||||||
|
|
||||||
|
[0.1.5 - 13.05.2017]
|
||||||
|
* fixed bug with "Integrity constraint violation: 1048 Column 'ip' cannot be null"
|
||||||
|
|
||||||
|
[0.1.4 - 13.05.2017]
|
||||||
|
* added outfit shower, in characters, online, and highscores
|
||||||
|
* updated database to version 2
|
||||||
|
* fixed item images (now using item-images.ots.me host by default)
|
||||||
|
* fixed news ticket and posting long newses (https://otland.net/threads/myaac-v0-0-1.251454/page-5#post-2442026)
|
||||||
|
* news body limit increased to 65535 (mysql text field)
|
||||||
|
* removed some unused code from my old server
|
||||||
|
* added spells & monsters to kathrine template
|
||||||
|
|
||||||
|
[0.1.3 - 11.05.2017]
|
||||||
|
* this is just release to update version number
|
||||||
|
|
||||||
|
[0.1.2 - 11.05.2017]
|
||||||
|
* forgot to update CHANGELOG and MYAAC_VERSION
|
||||||
|
|
||||||
|
[0.1.1 - 11.05.2017]
|
||||||
|
* fixed updating myaac_config with database_version to 1
|
||||||
|
* fixed database updater
|
||||||
|
|
||||||
|
[0.1.0 - 11.05.2017]
|
||||||
|
* added new feature: change character name for premium points (disabled by default, you can enable it in config under account_change_character_name in config.php)
|
||||||
|
* added automatic database updater (data migrations)
|
||||||
|
* renamed events to hooks
|
||||||
|
* moved hooks to database
|
||||||
|
* now you can use hooks in plugins
|
||||||
|
* set account.type field to 5 on install, if TFS 1.0+
|
||||||
|
* added example plugin
|
||||||
|
* new, latest google analytics code
|
||||||
|
* fixed bug with loading account.name that has numbers in it
|
||||||
|
* fixed many bugs in player editor in admin panel
|
||||||
|
* added error handling to plugin manager and some more verification in
|
||||||
|
* file has been correctly unpacked/uploaded
|
||||||
|
* fixed Statistics page in admin panel when using account.number
|
||||||
|
* fixed bug when creating/recovering account on servers with
|
||||||
|
* account.salt field (TFS 0.3 for example)
|
||||||
|
* fixed forum showing thread with html tags (added from news manager)
|
||||||
|
* new, latest code for youtube videos in movies page
|
||||||
|
* fixed showing vocation images when using $config['online_vocations_images']
|
||||||
|
* many fixes in polls (also importing proper schema)
|
||||||
|
* fixed hovering on buttons in kathrine template (on accountmanagement page)
|
||||||
|
* fixed signatures (many fixes)
|
||||||
|
* added missing gesior signature system
|
||||||
|
|
||||||
|
[0.0.6 - 06.05.2017]
|
||||||
|
* fixed bug while installing (https://otland.net/threads/myaac-v0-0-1.251454/page-3#post-2440543)
|
||||||
|
* fixed bug when creating character (not showing errors) (one more time)
|
||||||
|
* fixed support for TFS 0.2 series
|
||||||
|
* added FAQ link
|
||||||
|
|
||||||
|
[0.0.5 - 05.05.2017]
|
||||||
|
* fixed bug when creating character (not showing errors)
|
||||||
|
* Fixed characters loading with names that has been created with other AAC
|
||||||
|
* fixed links to shop in default template
|
||||||
|
* fixed some weird PHP 7.1 warnings/notices
|
||||||
|
* Fixed config loading with some weird comments
|
||||||
|
* fixed bug with status info utf8 encoding (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440259)
|
||||||
|
* fixed when ip in log_action is NULL (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440357)
|
||||||
|
* fixed bug when guild doesn't exist on characters page (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440320)
|
||||||
|
* disabled friendly_urls by default
|
||||||
|
* fixes when $config['database_*'] is set
|
||||||
|
* added CHANGELOG
|
||||||
|
|
||||||
|
[0.0.3 - 03.05.2017]
|
||||||
|
* Full support for OTHire 0.0.3
|
||||||
|
* added support for otservers that doesn't use account.name field, instead just account number will be used
|
||||||
|
* fixed encryption detection on TFS 0.3
|
||||||
|
* fixed bug when server_config table doesn't exist
|
||||||
|
* (install) moved admin account creation to new step
|
||||||
|
* fixed news comment link
|
||||||
|
* by default, the installer creates now the Admin player, for admin account
|
||||||
|
* fixed installation errors
|
||||||
|
* fixed config.lua loading with some weird comments
|
||||||
|
|
||||||
|
[0.0.2 - 02.05.2017]
|
||||||
|
* updated forum links to use friendly_urls
|
||||||
|
* some more info will be shown when cannot connect to database
|
||||||
|
* show more error infos when creating character
|
||||||
|
* fixed forum link on newses
|
||||||
|
* fixed spells loading when there's vocation name instead of id
|
||||||
|
* fixed bug when you have changed template but it doesn't exist anymore
|
||||||
|
* fixed vocations with promotion loading
|
||||||
|
* fixed support for gesior pages and templates
|
||||||
|
* added function OTS_Acount:getGroupId()
|
||||||
|
|
||||||
|
[0.0.1 - 01.05.2017]
|
||||||
|
This is first official release of MyAAC.
|
||||||
|
Features are listed here
|
||||||
|
|
||||||
|
For more information, see the release announcement on OTLand: https://otland.net/threads/myaac-v0-0-1.251454/
|
266
CHANGELOG-1.x.md
@ -1,266 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
## [1.4 - 22.04.2025]
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* feat: admin-pages (can add admin pages through plugins) (https://github.com/slawkens/myaac/commit/ceaa0639e66d31e8177ff90791463470367aa45d)
|
|
||||||
* just place the page in admin-pages folder in the plugin
|
|
||||||
* Also, possibility to overwrite default myaac admin pages
|
|
||||||
* Add db->hasTableAndColumns(table, columns), credits to @opentibiabr Team (https://github.com/slawkens/myaac/commit/82a533d88c8a342076891d132b4b409ed9a1fe72)
|
|
||||||
* Add noSubmit option to buttons.base (https://github.com/slawkens/myaac/commit/64f6d3abcada3bf9fd7599f50d2fac0a1367f383)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fix: display 404 error instead of 500 when page has been removed from filesystem (https://github.com/slawkens/myaac/commit/c2bf94fb2370d2009a2eb907f818955132cf8611)
|
|
||||||
* Fix headline.php: change image format to .png cause of black background (https://github.com/slawkens/myaac/commit/b618084d50918539d9a70abd97e764137b966067)
|
|
||||||
* Clear cache on plugin enable/disable, fixes some issues with plugin pages being cached (https://github.com/slawkens/myaac/commit/1d0c173e7d000aecbd432800941fc3e38a0e50f2)
|
|
||||||
* Do not autoload sub-folders if autoload pages is disabled (https://github.com/slawkens/myaac/commit/d47195a7878095336f9c9edc6f96244257f67eec)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* SQL Syntax Standardization (by @JoaozinhoBrasil, #298)
|
|
||||||
* Pages in theme/template folder will now have precedence over normal pages (https://github.com/slawkens/myaac/commit/6d8f4718a1d349fba8f0ebc39cfd3a1a84d104b0)
|
|
||||||
* Small changes in account.login.html.twig (https://github.com/slawkens/myaac/commit/f40b986b59d4c8fa89ab4745731bf366f8619976)
|
|
||||||
* Plugin name is required, version is optional (https://github.com/slawkens/myaac/commit/e6f05a2731c61d931be49e121c068e49c0ad5e01)
|
|
||||||
|
|
||||||
## [1.3.3 - 04.04.2025]
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fix uninstall plugin when plugin is disabled (https://github.com/slawkens/myaac/commit/6c568fd36a271270684fc412ccd556b230273a6d)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Display more useful info when error parsing config.lua (https://github.com/slawkens/myaac/commit/fa6b6aa153ffc131e0d1631a4dcd9012a5850c2e)
|
|
||||||
|
|
||||||
### Other
|
|
||||||
* Small adjustments (https://github.com/slawkens/myaac/commit/35e2483de86e295bdf089cceffa25842eeb2e34c, https://github.com/slawkens/myaac/commit/ae639d65b0bfa491e747e907e2ebc77f83f47981)
|
|
||||||
|
|
||||||
## [1.3.2 - 01.04.2025]
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fix debugBar/admin panel menu when using custom base_dir (https://github.com/slawkens/myaac/commit/65696f63e3aac02ff952ea81279e7cb2fa7570fb)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Settings: Show/hide IP Ban Protection options depending on the value (enabled/disabled) (https://github.com/slawkens/myaac/commit/dbf73d0b61b45601ae95e51b23c051c2704169c5)
|
|
||||||
* Do not require init.php in cache:clear command (https://github.com/slawkens/myaac/commit/d25c71857f767834239bbffacd00fdc671adb157)
|
|
||||||
|
|
||||||
## [1.3.1 - 19.03.2025]
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fixed migrate:run command (https://github.com/slawkens/myaac/commit/1a5771ad51e595fe13368a0721b059c4ecefb17d)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Small adjustments (https://github.com/slawkens/myaac/commit/6fac883659f581baac1361826d046410156f1e58, https://github.com/slawkens/myaac/commit/4a6896b4469968b9904292734cf6c14ba5eeef14)
|
|
||||||
|
|
||||||
## [1.3 - 10.03.2025]
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Use latest outfit-images host from @gesior (https://github.com/slawkens/myaac/commit/529bdcf016dd0f9dffbc34d81f99a046a9ddb70d)
|
|
||||||
* Change monster link to $_GET ?name= (https://github.com/slawkens/myaac/commit/4c5cc8b573b2b3e7ec00a22b7ede30a68083a924)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fixed house links (https://github.com/slawkens/myaac/commit/887b5068ad11c4cdab614afd34525caba785ce13)
|
|
||||||
* Fixed long title on headline.php (https://github.com/slawkens/myaac/commit/3e3f4bb5a514158ec8777684ca6c7f1c2a37bed5)
|
|
||||||
* Fixed menu colors once again, plus add !important tag (https://github.com/slawkens/myaac/commit/aa52df6e2ec92cafc25b655ae907bf2e1746d9cc)
|
|
||||||
* Fix: add possibility to remove all menu items in admin panel (https://github.com/slawkens/myaac/commit/00fe1adc15ea7646596d755f6e6e1f7854ffc1d5, https://github.com/slawkens/myaac/commit/9239a4f4198c3ad260802ac3b47e9c41b80b754e)
|
|
||||||
|
|
||||||
## [1.2 - 09.02.2025]
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Twig session(key) function + reworked session functions to accept multi-array like in Laravel (https://github.com/slawkens/myaac/commit/b46ddb43d03ef7e5fc34e555e92e856bdc905691)
|
|
||||||
* add template_name to twig variables (https://github.com/slawkens/myaac/commit/ae1161d77050bda181802b4496c9de920a7bb1bc)
|
|
||||||
* add HOOK_INIT, executed just after $hooks are loaded (https://github.com/slawkens/myaac/commit/19686725dc810f63a07f049f82c66cf336d90ca6)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* settings: password input hide/show, enable Save button only if changes has been made, save settings in transaction (https://github.com/slawkens/myaac/commit/4fda4f643b60a151179e5dd4f04912fb2618d98f, https://github.com/slawkens/myaac/commit/28fef952f857b79d64bc7495ffa5e1999e68e192, https://github.com/slawkens/myaac/commit/4b6024dc451accadb6c469fa282a9a764c1c0a81)
|
|
||||||
* rework menus: Different categories can have different colors + Option to reset menus (https://github.com/slawkens/myaac/commit/73de93a561f6b13111e019075724357d8a617249, https://github.com/slawkens/myaac/commit/3da3e62c5b12390d75de9b3320729bcca6e0b458)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* highscores: Fix online status + vocation for TFS 0.x (https://github.com/slawkens/myaac/commit/ea51ad27c38be88d86514cb979bb394fcfbef1f0)
|
|
||||||
* clear cache button in admin bar needed to be clicked twice until it worked (https://github.com/slawkens/myaac/commit/ea51ad27c38be88d86514cb979bb394fcfbef1f0)
|
|
||||||
* HOOK_STARTUP location (https://github.com/slawkens/myaac/commit/a73fb1003ee3f812cf182d1834d65f08e6f60d1f)
|
|
||||||
* if vocation name has more words (https://github.com/slawkens/myaac/commit/9d7fc98e1e0a96b59ecc1a7c39800a64445db364)
|
|
||||||
|
|
||||||
### Updated
|
|
||||||
* Bump twig/twig from 3.18.0 to 3.19.0 (#284)
|
|
||||||
|
|
||||||
## [1.1 - 27.01.2025]
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* adjust mailer settings descriptions to latest gmail (https://github.com/slawkens/myaac/commit/c5d5bb80671db135e6b503f53684771c7272e05d)
|
|
||||||
* optimize $player->isOnline() function, thanks @gesior (https://github.com/slawkens/myaac/commit/10dd818b139d5e1bb1ca9ec81edfb083ba9316b4)
|
|
||||||
* make players.comment and guilds.description VARCHAR (https://github.com/slawkens/myaac/commit/a45ceab83a74bee2b89cdb72baceda75e577e3cf)
|
|
||||||
* add lua/ folder to .gitignore (https://github.com/slawkens/myaac/commit/07012f786b1114cb6ab2f064f82c645b136a375a)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* general fixes in the tibiacom template menus, better support for custom menus
|
|
||||||
* make functions_custom.php optional (https://github.com/slawkens/myaac/commit/dc2b5afd9980984e2b259c9fc99f2ade46f70a5a)
|
|
||||||
* error in CLI, where BASE_URL is not defined (https://github.com/slawkens/myaac/commit/4d749b881582f64b5a46196dbbb5ee8097127f03)
|
|
||||||
* hook ACCOUNT_LOGIN_BEFORE_ACCOUNT location (https://github.com/slawkens/myaac/commit/669c447fca8643ce56d9ef8c1374ec647c780998)
|
|
||||||
|
|
||||||
## [1.0.1 - 14.01.2025]
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* tibiacom account & news menu links not auto expanding
|
|
||||||
|
|
||||||
### Updated (Thanks dependabot)
|
|
||||||
* twig from ^2.0 to ^3.11
|
|
||||||
* tinymce from ^6.8.3 to ^7.2.0
|
|
||||||
* cypress from ^12.12.0 to ^13.17.0
|
|
||||||
* nesbot/carbon from 2.72.5 to 2.72.6
|
|
||||||
|
|
||||||
## [1.0 - 12.01.2025]
|
|
||||||
|
|
||||||
First stable release in the v1.0 series.
|
|
||||||
|
|
||||||
Minimum PHP 8.1 is required.
|
|
||||||
|
|
||||||
Changes since RC.2:
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* feature: migrations up/down. Allows to downgrade/upgrade database to specified version (https://github.com/slawkens/myaac/commit/3f6ff3a3326b0475d28d11ffd7fff51f362d799f)
|
|
||||||
* new hooks for news management (https://github.com/slawkens/myaac/commit/011a85d8ae34283ded6999882833f9d4797028ec, https://github.com/slawkens/myaac/commit/36bd3eb846e829b45313e10f7568dc4e95841143)
|
|
||||||
* None Vocation to highscores (can be changed to RookStayer in Admin Panel) (https://github.com/slawkens/myaac/commit/a4a248099521bb5b8b2aa5bd592138debd2f19d5)
|
|
||||||
* support for button_color (green, red, blue) (https://github.com/slawkens/myaac/commit/d8b6b749ee62e88b6af4a05d3d7557f90b94d94e)
|
|
||||||
* add $whoopsHandler as variable, can be used by plugins (https://github.com/slawkens/myaac/commit/b0c8cf2ecda23045d725aaf43cfb3852ed766a4b)
|
|
||||||
* PlayerModel->outfit_url attribute (https://github.com/slawkens/myaac/commit/3b5be1a8db5dceecaa388e2925a5536d13b38881)
|
|
||||||
* support for selecting plugin themes in Admin menus.php (https://github.com/slawkens/myaac/commit/77a2c1cec343ffe4be5c2c2503ee81bc32a14ca1)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* schema: Change character set to utf8mb4 (support for Emojis in Menus/Pages/News/Forum etc.) (https://github.com/slawkens/myaac/commit/27c44f1bdfb6234cf0c9d5b4b491123bb205b08f)
|
|
||||||
* prefer get_browser_real_ip() over REMOTE_ADDR (https://github.com/slawkens/myaac/commit/941846605c00cee83168d2f916410b8ba8d4b7b9)
|
|
||||||
* automatically set selected current one on highscores filters (https://github.com/slawkens/myaac/commit/e96227fbe41ae281783b2d49edb169a603601813)
|
|
||||||
* rewrite towns loading code, removed OTBM loader (was too slow) (https://github.com/slawkens/myaac/commit/c980a0914632e7b27f718464f669a200707d217e)
|
|
||||||
* allow OTS_Player to be passed as object to getPlayerLink (https://github.com/slawkens/myaac/commit/84d37c5a8f2c4535a41c8aa8264752969d3f3a3d)
|
|
||||||
* do not clear menus by default on install (https://github.com/slawkens/myaac/commit/12d8faa3eda5e798f97b71e941c035187daad96e)
|
|
||||||
* display warning in admin panel - plugins - if zip extension is not installed (https://github.com/slawkens/myaac/commit/e3ffe5d9e11d78ab064a370d8541bac351c9bcd9)
|
|
||||||
* set default_socket_timeout for ipinfo.io checkup to 5 seconds (https://github.com/slawkens/myaac/commit/783d96fc6568a607d3198b832fed3a0dd06c4ebb)
|
|
||||||
* refactor getTopPlayers function (support for balance) (https://github.com/slawkens/myaac/commit/c769962e39fe8dfb72ecd5be1864e145696be794)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* XSS in forum (https://github.com/slawkens/myaac/commit/c2b7286d20d4b579171540f7a774e8a0995d5e8f, https://github.com/slawkens/myaac/commit/8fb643596f9586005976e7bdb484a541a9d8715e)
|
|
||||||
* price deducted when changing sex (https://github.com/slawkens/myaac/commit/16671ea40b72dcf74037c359ad572f9eb825edf9)
|
|
||||||
* move_thread by unauthorized user (https://github.com/slawkens/myaac/commit/d6c40c836a53cb1710f911f77f45f28b54ea1b54, thanks @anyeor)
|
|
||||||
* TFS 1.4.2 where conditions is NULL (https://github.com/slawkens/myaac/commit/b8396d4c8482e951da538b13f2296123732c4545)
|
|
||||||
* do not show forum new thread show button if not logged in (https://github.com/slawkens/myaac/commit/507402171ba3b6e7ee184bd7fa73e0d55e0cad7a, @anyeor)
|
|
||||||
* login if limiter is disabled (https://github.com/slawkens/myaac/commit/a0f1971583f0f790013e2145fb5ac573c59fbdef)
|
|
||||||
* fixes to installMenus function (https://github.com/slawkens/myaac/commit/a2fadc5945fe0a5e39f740827f6ffbda1bb501e2)
|
|
||||||
* many PHP exceptions in different places
|
|
||||||
* fixes to tibiacom menus ActiveSubmenuItem
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
* bugtracker SQL table code as the page has been removed/moved to plugins (https://github.com/slawkens/myaac/commit/5782772b901b05fb814bc718d062f6e2cd71df8c)
|
|
||||||
|
|
||||||
## [1.0-RC.2 - 25.10.2024]
|
|
||||||
|
|
||||||
Still waiting for your reports about bugs found in this release. We are very close to stable release.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* feat: rate limit settings for blocking accounts login attempts (@gpedro, #266)
|
|
||||||
* search by email in accounts editor (https://github.com/slawkens/myaac/commit/c2ec46824621468f2a1cb4046805c485ed13fea5)
|
|
||||||
* New hooks in account manage + create (https://github.com/slawkens/myaac/commit/93641fc68ac9a5f1479329e2bd41380c19534d5d)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* chore: drop raw queries + accounts - search by email + accounts - required min size for search by account number (@gpedro, #266)
|
|
||||||
* Use https for outfit & item images (https://github.com/slawkens/myaac/commit/71c00aa5e01fbdfd88802912e200dd1025976231)
|
|
||||||
* Do not require players & guilds tables on install (https://github.com/slawkens/myaac/commit/779aa152fa940261c9b161533946f44e288597a2)
|
|
||||||
* Do not create player if there is no players table in db (https://github.com/slawkens/myaac/commit/201f95caa8b70e88fa651eac8c3c3aa7cd765bd0)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Highscore frags fixed for TFS 0.3 (@Scrollog, #263)
|
|
||||||
* Missing groups variable #262. thanks, @Scrollog for reporting (https://github.com/slawkens/myaac/commit/8d8bdb6dac6df21672ac77288fff2f2f8d6eb665)
|
|
||||||
* Verified email for login.php (@gpedro, #265)
|
|
||||||
* Warning if core.account_country is disabled (https://github.com/slawkens/myaac/commit/ab73d60c61e14a1cacdb6cfbf7f89f4bf3be0833)
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0-RC.1 - 23.07.2024]
|
|
||||||
|
|
||||||
Changes since 1.0-beta:
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Feat: Hooks priority (https://github.com/slawkens/myaac/commit/dc17b701da053e04bfa64e21be9247a4f07505e1)
|
|
||||||
* Make autoload of pages, commands and themes configurable (https://github.com/slawkens/myaac/commit/c1d4b4f80cd6bb85507ee9471e47013955a26a91)
|
|
||||||
* Fraggers in characters page for TFS 1.x and canary (https://github.com/slawkens/myaac/commit/42f99c3edc8de39cccc5632cb42e88b24579c5a6)
|
|
||||||
* New hooks: HOOK_INSTALL_FINISH, HOOK_ACCOUNT_CREATE_CHARACTER_* (https://github.com/slawkens/myaac/commit/08ac8ebade106521a5c7396faa5ce7006e629f7c, https://github.com/slawkens/myaac/commit/45dda5e834ff2059faea6ef9be2efa76f1723cbd)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Allow account_create_character_create even if account_mail_verify is activated (https://github.com/slawkens/myaac/commit/203e411b626fe62401a4b74a48420769e512aa39)
|
|
||||||
* Create guild_rank entries, in case MySQL trigger not loaded (https://github.com/slawkens/myaac/commit/d9c1b2507c81f306970642b35e4bf5f7cc04a6f2, https://github.com/slawkens/myaac/commit/47a19e85dd84e9f3b39a1b29cfc2c04b004832b9)
|
|
||||||
* Set Admin Account verified by default (https://github.com/slawkens/myaac/commit/cd49dfc79942f3301ce9c0b8d899b9f39bda9a41)
|
|
||||||
* Refactor account routes into sub folders (https://github.com/slawkens/myaac/commit/bdc0c43d3fd3a51030c3e916bdb9f008468f5ecd)
|
|
||||||
* Order towns by id (https://github.com/slawkens/myaac/commit/9ea2a5067fc4b75de395f381577b18914132ad84)
|
|
||||||
* Do not create news about myaac, if any news already exist (on installation (https://github.com/slawkens/myaac/commit/504242fb846b73b56b87bc1e39d070687ad7f5b4)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Not working google recaptcha plugin (https://github.com/slawkens/myaac/commit/a1bcb217ecf4e21fd58da4ba491da1852029898a)
|
|
||||||
* Not working account create if account_country is disabled (https://github.com/slawkens/myaac/commit/933b681a9fcdbb6283e0469b3806d2ded492d232)
|
|
||||||
* Account verify - do not allow login without verified email (Thanks @anyeor, https://github.com/slawkens/myaac/commit/fcb13f3c0fb8ceafda0bd614a229a26a269432bd)
|
|
||||||
* Detect tools/ext exists on install to prevent broken installs (https://github.com/slawkens/myaac/commit/10a739773c4f2911876bc802a0ee0537c3e00a92)
|
|
||||||
* Cache reloading each time page refreshes (https://github.com/slawkens/myaac/commit/ec96985872057340112f65073efc0c4bf86dddb0)
|
|
||||||
* Highscores frags for TFS 1.x and canary (https://github.com/slawkens/myaac/commit/a04d186c22912915f0a7873dfe677ef3b5a23c79)
|
|
||||||
* Monsters page: monster not found exception (https://github.com/slawkens/myaac/commit/ef79b99b8acc179f14b8475547347d9daca27512)
|
|
||||||
* Fixed bug if \<flags\> are not present in monster.xml (https://github.com/slawkens/myaac/commit/57b47ab7983f625c7c0ef4f5303a4d07ef172786)
|
|
||||||
* fastRoute duplicate errors (https://github.com/slawkens/myaac/commit/4c0739d3e93812dff0c33849ea3f38e4e49113ac)
|
|
||||||
* useGuildNick displaying (https://github.com/slawkens/myaac/commit/0db0ec1aa47e044c26bc403ff5078a2115d086f8)
|
|
||||||
|
|
||||||
## [1.0-beta - 18.05.2024]
|
|
||||||
|
|
||||||
Minimum PHP version for this release is 8.1.
|
|
||||||
|
|
||||||
### 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
|
|
||||||
* Towns, NPCs & Items are stored in permanent cache
|
|
||||||
* new pages: mass account & teleport tools
|
|
||||||
* changelogs editor
|
|
||||||
* revised Accounts & Players editors
|
|
||||||
* option to add/modify admin 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 page
|
|
||||||
* auto-loading of themes, commands & pages from plugins/ folder. You need just to place them in correct folder and they will be loaded automatically - this allows better customization, without interfering with core AAC folders. This will allow in the future automatic updates for plugins as well the AAC as whole.
|
|
||||||
* config.php moved to Admin Panel -> Settings page
|
|
||||||
* new console script: aac - using symfony/console
|
|
||||||
* usage: `php aac` (will list all commands by default)
|
|
||||||
* example: `php aac cache:clear`
|
|
||||||
* example: `php aac plugin:install theme-example.zip`
|
|
||||||
* replace POT Query Builder to Eloquent ORM. Not 100% yet - in some places there is still old $db approach used (@gpedro) (https://github.com/slawkens/myaac/pull/230)
|
|
||||||
* brand new charming installation page (by @fernandomatos)
|
|
||||||
* using Bootstrap
|
|
||||||
* new pages router: nikic/fast-route, allowing for better customisation
|
|
||||||
* Plugin cronjobs: central control of the cronjobs
|
|
||||||
* 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)
|
|
||||||
* support for Account Number
|
|
||||||
* suggest account number option
|
|
||||||
* many new functions, hooks and configurables
|
|
||||||
* better Exception Handler (Whoops - https://github.com/filp/whoops)
|
|
||||||
* automated website tests (using Cypress)
|
|
||||||
* csrf protection (https://github.com/slawkens/myaac/pull/235)
|
|
||||||
* option to restrict Page view to specified group of users (Not-Logged in, logged-in players, tutors, gamemasters etc.)
|
|
||||||
* phpdebug bar (http://phpdebugbar.com/). Activated if env == 'dev', can be also activated in production by enabling "enable_debugbar" in local config
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Composer and NPM is now used for external libraries like: Twig, PHPMailer, fast-route, jQuery, Bootstrap 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
|
|
||||||
* Monsters
|
|
||||||
* moved pages to Twig:
|
|
||||||
* experience stages
|
|
||||||
* update player_deaths entries on name change
|
|
||||||
* change_password email to be more informal
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* hundreds of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here
|
|
@ -1,18 +0,0 @@
|
|||||||
# automatically exported using this script:
|
|
||||||
# git log --all --format='%cN <%cE>' | sort -u > contributors
|
|
||||||
# in no particular order
|
|
||||||
# cleaned for readability
|
|
||||||
|
|
||||||
Evil Puncker <EPuncker@users.noreply.github.com>
|
|
||||||
Fernando Matos <fernando@pixele.com.br>
|
|
||||||
Lee <42119604+Leesneaks@users.noreply.github.com>
|
|
||||||
caio <caio.zucoli@gmail.com>
|
|
||||||
slawkens <slawkens@gmail.com>
|
|
||||||
tobi132 <tobi132@gmx.net>
|
|
||||||
vankk <nwtr.otland@hotmail.com>
|
|
||||||
whiteblXK <krzys16001@gmail.com>
|
|
||||||
xitobuh <jonas.hockert92@gmail.com>
|
|
||||||
Danilo Pucci <dnlps@hotmail.com>
|
|
||||||
gpedro <gpedro831@gmail.com>
|
|
||||||
Matheus Collier <matheuscollier@gmail.com>
|
|
||||||
SRNT-GG <95472530+SRNT-GG@users.noreply.github.com>
|
|
3
CREDITS
@ -1,3 +1,2 @@
|
|||||||
* Gesior.pl (2007 - 2008)
|
* Gesior.pl (2007 - 2008)
|
||||||
* Slawkens (2009 - 2025)
|
* Slawkens (2009 - 2017)
|
||||||
* Contributors listed in CONTRIBUTORS.txt
|
|
||||||
|
85
README.md
@ -1,38 +1,18 @@
|
|||||||
# [MyAAC](https://my-aac.org)
|
# myaac
|
||||||
|
MyAAC is a free and open-source Automatic Account Creator (AAC) and Content Management System (CMS) written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases.
|
||||||
MyAAC is a free and open-source Automatic Account Creator (AAC) for Open Tibia Servers written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases.
|
|
||||||
|
|
||||||
Official website: https://my-aac.org
|
Official website: https://my-aac.org
|
||||||
|
|
||||||
[](https://github.com/slawkens/myaac/actions)
|
### REQUIREMENTS
|
||||||
[](https://opensource.org/licenses/gpl-license)
|
|
||||||
[](https://github.com/slawkens/myaac/releases)
|
|
||||||
[](https://discord.gg/2J39Wus)
|
|
||||||
[](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed)
|
|
||||||
|
|
||||||
| Version | Status | Branch | Requirements |
|
|
||||||
|:--------|:-----------------------|:--------|:---------------|
|
|
||||||
| 2.x | Experimental features | develop | PHP >= 8.1 |
|
|
||||||
| **1.x** | **Active development** | main | **PHP >= 8.1** |
|
|
||||||
| 0.9.x | Not developed anymore | 0.9 | PHP >= 7.2.5 |
|
|
||||||
| 0.8.x | Active support | 0.8 | PHP >= 7.2.5 |
|
|
||||||
| 0.7.x | End Of Life | 0.7 | PHP >= 5.3.3 |
|
|
||||||
|
|
||||||
The recommended version to install is 1.x, which can be found at releases page - [https://github.com/slawkens/myaac/releases](https://github.com/slawkens/myaac/releases).
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
* [docs.my-aac.org](https://docs.my-aac.org)
|
|
||||||
* [my-aac.org - FAQ](https://my-aac.org/faqs/)
|
|
||||||
|
|
||||||
### Requirements
|
|
||||||
|
|
||||||
|
- PHP 5.3.0 or later
|
||||||
- MySQL database
|
- MySQL database
|
||||||
- PHP Extensions: pdo, xml, json
|
- PDO PHP Extension
|
||||||
- (optional) apache2 mod_rewrite (to use friendly_urls)
|
- XML PHP Extension
|
||||||
- (optional) zip PHP Extension (to install plugins)
|
- ZIP PHP Extension
|
||||||
- (optional) gd PHP Extension (for generating signature images)
|
- (optional) mod_rewrite to use friendly_urls
|
||||||
|
|
||||||
### Installation
|
### INSTALLATION AND CONFIGURATION
|
||||||
|
|
||||||
Just decompress and untar the source (which you should have done by now,
|
Just decompress and untar the source (which you should have done by now,
|
||||||
if you're reading this), into your webserver's document root.
|
if you're reading this), into your webserver's document root.
|
||||||
@ -48,51 +28,18 @@ The recommended version to install is 1.x, which can be found at releases page -
|
|||||||
chmod 660 images/guilds
|
chmod 660 images/guilds
|
||||||
chmod 660 images/houses
|
chmod 660 images/houses
|
||||||
chmod 660 images/gallery
|
chmod 660 images/gallery
|
||||||
chmod -R 760 system/cache
|
|
||||||
|
|
||||||
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.
|
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.
|
||||||
|
|
||||||
### Configuration
|
### KNOWN PROBLEMS
|
||||||
|
|
||||||
Check *config.php* to get more information. (Notice: MyAAC 1.0+ doesn't use config.php anymore, it has been moved to Admin Panel - Settings page).
|
- none -
|
||||||
|
|
||||||
Use *config.local.php* for your local configuration changes.
|
### OTHER NOTES
|
||||||
|
|
||||||
### Branches
|
If you have a great idea or want contribute to the project - visit our website at http://www.my-aac.org
|
||||||
|
|
||||||
This repository follows the Git Flow Workflow.
|
### LICENSING
|
||||||
Cheatsheet: [Git-Flow-Cheatsheet](https://danielkummer.github.io/git-flow-cheatsheet)
|
|
||||||
|
|
||||||
That means, we use:
|
This program and all associated files are released under the GNU Public
|
||||||
* main branch, for current stable release
|
License, see LICENSE for details.
|
||||||
* develop branch, for development version (next release)
|
|
||||||
* feature branches, for features etc.
|
|
||||||
|
|
||||||
### Known Problems
|
|
||||||
|
|
||||||
- Some compatibility issues with some exotic distributions.
|
|
||||||
|
|
||||||
### Contributing
|
|
||||||
|
|
||||||
Contributions are more than welcome.
|
|
||||||
|
|
||||||
Pull requests should be made to the *develop* branch as that is the working branch, master is for release code.
|
|
||||||
|
|
||||||
Bug fixes to current release should be done to master branch.
|
|
||||||
|
|
||||||
Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our wiki.
|
|
||||||
|
|
||||||
### Other Notes
|
|
||||||
|
|
||||||
If you have a great idea or want to contribute to the project - visit our website at https://www.my-aac.org
|
|
||||||
|
|
||||||
## Project supported by JetBrains
|
|
||||||
|
|
||||||
Many thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects.
|
|
||||||
|
|
||||||
[](https://www.jetbrains.com/?from=https://github.com/slawkens)
|
|
||||||
|
|
||||||
### License
|
|
||||||
|
|
||||||
This program and all associated files are released under the GNU Public License.
|
|
||||||
See [LICENSE](https://github.com/slawkens/myaac/blob/master/LICENSE) for details.
|
|
||||||
|
37
TODO
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// MyAAC TODO
|
||||||
|
|
||||||
|
0.*
|
||||||
|
* support duplicated vocation names with different ids
|
||||||
|
* plugins: option to define custom requirements check in json file, to check if system meets the requirement
|
||||||
|
* add support for defining max myaac version in plugin.json file
|
||||||
|
* cache Menus in templates
|
||||||
|
* don't show error indicators on first time load - createaccount page
|
||||||
|
* update Twig to the latest version from 1.x branch
|
||||||
|
* semantic versioning support for plugins (github.com/composer/semver)
|
||||||
|
* add some notice to the user that installing step "Import Schema" will take some time
|
||||||
|
* check user IP on installing to prevent install by random user
|
||||||
|
|
||||||
|
1.0:
|
||||||
|
* i18n support (issue #1 on github)
|
||||||
|
* New Admin Panel layout and interface
|
||||||
|
* add changelog management interface
|
||||||
|
* remove tibiacom template, and include it as a plugin
|
||||||
|
|
||||||
|
2.0
|
||||||
|
* remove compat functions
|
||||||
|
* folder restructure:
|
||||||
|
* var/ (for logs, cache and data), config/, bin, public/ (for index and images and other public content), system/ (for php files and classess)
|
||||||
|
* rename templates to layouts as templates is meant to be used for twig templates
|
||||||
|
* change gifts_system to shop_system configurable
|
||||||
|
* move most used options in system/templates dir to separate directories (more transparent)
|
||||||
|
|
||||||
|
At any time between (version not specified):
|
||||||
|
* better news archive with search function (like on tibia.com)
|
||||||
|
* guild wars management (issue #13 on github)
|
||||||
|
* update account.management page to be more realistic (like on tibia.com)
|
||||||
|
* update guilds page to be more realistic (like on tibia.com)
|
||||||
|
* possibility to add extra cache engines with plugins
|
||||||
|
* preferably configurable (enable/disable) forum TinyMCE editor
|
||||||
|
* new cache engine - plain php, is good with pure php 7.0+ and opcache
|
||||||
|
* OTAdmin support in Admin Panel
|
||||||
|
* database towns table support for TFS 1.3
|
@ -1 +0,0 @@
|
|||||||
theme: jekyll-theme-slate
|
|
36
aac
@ -1,36 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once __DIR__ . '/common.php';
|
|
||||||
|
|
||||||
if(!IS_CLI) {
|
|
||||||
echo 'This script can be run only in command line mode.';
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once SYSTEM . 'functions.php';
|
|
||||||
|
|
||||||
define('SELF_NAME', basename(__FILE__));
|
|
||||||
|
|
||||||
use MyAAC\Plugins;
|
|
||||||
use Symfony\Component\Console\Application;
|
|
||||||
|
|
||||||
$application = new Application('MyAAC', MYAAC_VERSION);
|
|
||||||
|
|
||||||
$commandsGlob = glob(SYSTEM . 'src/Commands/*.php');
|
|
||||||
foreach ($commandsGlob as $item) {
|
|
||||||
$name = pathinfo($item, PATHINFO_FILENAME);
|
|
||||||
if ($name == 'Command') { // ignore base Command class
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$commandPre = '\\MyAAC\Commands\\';
|
|
||||||
$application->add(new ($commandPre . $name));
|
|
||||||
}
|
|
||||||
|
|
||||||
$pluginCommands = Plugins::getCommands();
|
|
||||||
foreach ($pluginCommands as $item) {
|
|
||||||
$application->add(require $item);
|
|
||||||
}
|
|
||||||
|
|
||||||
$application->run();
|
|
Before Width: | Height: | Size: 4.3 KiB |
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
$hooks->register('debugbar_admin_head_end', HOOK_ADMIN_HEAD_END, function ($params) {
|
|
||||||
global $debugBar;
|
|
||||||
|
|
||||||
if (!isset($debugBar)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$debugBarRenderer = $debugBar->getJavascriptRenderer(BASE_URL . 'vendor/maximebf/debugbar/src/DebugBar/Resources/');
|
|
||||||
echo $debugBarRenderer->renderHead();
|
|
||||||
});
|
|
||||||
$hooks->register('debugbar_admin_body_end', HOOK_ADMIN_BODY_END, function ($params) {
|
|
||||||
global $debugBar;
|
|
||||||
|
|
||||||
if (!isset($debugBar)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$debugBarRenderer = $debugBar->getJavascriptRenderer(BASE_URL . 'vendor/maximebf/debugbar/src/DebugBar/Resources/');
|
|
||||||
echo $debugBarRenderer->render();
|
|
||||||
});
|
|
@ -1,2 +1 @@
|
|||||||
<?php
|
<?php
// nothing yet here
?>
|
||||||
// nothing yet here
|
|
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use MyAAC\Plugins;
|
|
||||||
|
|
||||||
$order = 10;
|
|
||||||
|
|
||||||
$settingsMenu = [];
|
|
||||||
|
|
||||||
$settingsMenu[] = [
|
|
||||||
'name' => 'MyAAC',
|
|
||||||
'link' => 'settings&plugin=core',
|
|
||||||
'icon' => 'list',
|
|
||||||
'order' => $order,
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach (Plugins::getAllPluginsSettings() as $setting) {
|
|
||||||
$file = BASE . $setting['settingsFilename'];
|
|
||||||
if (!file_exists($file)) {
|
|
||||||
warning('Plugin setting: ' . $file . ' - cannot be loaded.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$order += 10;
|
|
||||||
|
|
||||||
$settings = require $file;
|
|
||||||
|
|
||||||
$settingsMenu[] = [
|
|
||||||
'name' => $settings['name'],
|
|
||||||
'link' => 'settings&plugin=' . $setting['pluginFilename'],
|
|
||||||
'icon' => 'list',
|
|
||||||
'order' => $order,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($settings, $file, $order);
|
|
||||||
|
|
||||||
return $settingsMenu;
|
|
@ -1,75 +1,54 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// few things we'll need
|
// few things we'll need
|
||||||
use MyAAC\Plugins;
|
require('../common.php');
|
||||||
|
require_once(BASE . 'config.local.php');
|
||||||
require '../common.php';
|
|
||||||
|
|
||||||
const ADMIN_PANEL = true;
|
|
||||||
const MYAAC_ADMIN = true;
|
|
||||||
|
|
||||||
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
|
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
|
||||||
{
|
{
|
||||||
header('Location: ' . BASE_URL . 'install/');
|
header('Location: ' . BASE_URL . 'install/');
|
||||||
throw new RuntimeException('Setup detected that <b>install/</b> directory exists. Please visit <a href="' . BASE_URL . 'install">this</a> url to start MyAAC Installation.<br/>Delete <b>install/</b> directory if you already installed MyAAC.<br/>Remember to REFRESH this page when you\'re done!');
|
die('Setup detected that <b>install/</b> directory exists. Please visit <a href="' . BASE_URL . 'install">this</a> url to start MyAAC Installation.<br/>Delete <b>install/</b> directory if you already installed MyAAC.<br/>Remember to REFRESH this page when you\'re done!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define('ADMIN_PANEL', true);
|
||||||
|
|
||||||
$content = '';
|
$content = '';
|
||||||
|
|
||||||
// validate page
|
// validate page
|
||||||
$page = $_GET['p'] ?? '';
|
$page = isset($_GET['p']) ? $_GET['p'] : '';
|
||||||
if(empty($page) || preg_match("/[^a-zA-Z0-9_\-\/.]/", $page))
|
if(empty($page) || preg_match("/[^a-zA-Z0-9_\-]/", $page))
|
||||||
$page = 'dashboard';
|
$page = 'dashboard';
|
||||||
|
|
||||||
$page = strtolower($page);
|
$page = strtolower($page);
|
||||||
define('PAGE', $page);
|
define('PAGE', $page);
|
||||||
|
|
||||||
require SYSTEM . 'functions.php';
|
require(SYSTEM . 'functions.php');
|
||||||
require SYSTEM . 'init.php';
|
require(SYSTEM . 'init.php');
|
||||||
|
require(SYSTEM . 'status.php');
|
||||||
require __DIR__ . '/includes/debugbar.php';
|
require(SYSTEM . 'login.php');
|
||||||
require SYSTEM . 'status.php';
|
require(ADMIN . 'includes/functions.php');
|
||||||
require SYSTEM . 'login.php';
|
|
||||||
require __DIR__ . '/includes/functions.php';
|
|
||||||
|
|
||||||
$twig->addGlobal('config', $config);
|
$twig->addGlobal('config', $config);
|
||||||
$twig->addGlobal('status', $status);
|
$twig->addGlobal('status', $status);
|
||||||
|
|
||||||
if (ACTION == 'logout') {
|
|
||||||
require SYSTEM . 'logout.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we're not logged in - show login box
|
// if we're not logged in - show login box
|
||||||
if(!$logged || !admin()) {
|
if(!$logged || !admin()) {
|
||||||
$page = 'login';
|
$page = 'login';
|
||||||
}
|
}
|
||||||
|
|
||||||
$pluginsAdminPages = Plugins::getAdminPages();
|
// include our page
|
||||||
if(isset($pluginsAdminPages[$page]) && file_exists(BASE . $pluginsAdminPages[$page])) {
|
$file = SYSTEM . 'pages/admin/' . $page . '.php';
|
||||||
$file = BASE . $pluginsAdminPages[$page];
|
if(!@file_exists($file)) {
|
||||||
}
|
$page = '404';
|
||||||
else {
|
$file = SYSTEM . 'pages/404.php';
|
||||||
// include our page
|
|
||||||
$file = __DIR__ . '/pages/' . $page . '.php';
|
|
||||||
if(!@file_exists($file)) {
|
|
||||||
if (str_contains($page, 'plugins/')) {
|
|
||||||
$file = BASE . $page;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$page = '404';
|
|
||||||
$file = SYSTEM . 'pages/404.php';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
if($hooks->trigger(HOOK_ADMIN_BEFORE_PAGE)) {
|
include($file);
|
||||||
require $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
$content .= ob_get_contents();
|
$content .= ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
|
|
||||||
// template
|
// template
|
||||||
$template_path = 'template/';
|
$template_path = 'template/';
|
||||||
require __DIR__ . '/' . $template_path . 'template.php';
|
require(ADMIN . $template_path . 'template.php');
|
||||||
|
?>
|
||||||
|
@ -1,659 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Account editor
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Lee
|
|
||||||
* @copyright 2020 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Models\Account as AccountModel;
|
|
||||||
use MyAAC\Models\Player;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$title = 'Account editor';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
$admin_base = ADMIN_URL . '?p=accounts';
|
|
||||||
$use_datatable = true;
|
|
||||||
|
|
||||||
if (setting('core.account_country'))
|
|
||||||
require SYSTEM . 'countries.conf.php';
|
|
||||||
|
|
||||||
$nameOrNumberColumn = getAccountIdentityColumn();
|
|
||||||
|
|
||||||
$hasSecretColumn = $db->hasColumn('accounts', 'secret');
|
|
||||||
$hasCoinsColumn = $db->hasColumn('accounts', 'coins');
|
|
||||||
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
|
|
||||||
$hasTypeColumn = $db->hasColumn('accounts', 'type');
|
|
||||||
$hasGroupColumn = $db->hasColumn('accounts', 'group_id');
|
|
||||||
|
|
||||||
if (setting('core.account_country')) {
|
|
||||||
$countries = array();
|
|
||||||
foreach (array('pl', 'se', 'br', 'us', 'gb') as $c)
|
|
||||||
$countries[$c] = $config['countries'][$c];
|
|
||||||
|
|
||||||
$countries['--'] = '----------';
|
|
||||||
foreach ($config['countries'] as $code => $c)
|
|
||||||
$countries[$code] = $c;
|
|
||||||
}
|
|
||||||
$web_acc = ACCOUNT_WEB_FLAGS;
|
|
||||||
$acc_type = setting('core.account_types');
|
|
||||||
?>
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ >
|
|
||||||
<script src="<?php echo BASE_URL; ?>tools/js/jquery.datetimepicker.js"></script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$id = 0;
|
|
||||||
$search_account = $search_account_email = '';
|
|
||||||
if (isset($_REQUEST['id']))
|
|
||||||
$id = (int)$_REQUEST['id'];
|
|
||||||
else if (isset($_REQUEST['search_email'])) {
|
|
||||||
$search_account_email = $_REQUEST['search_email'];
|
|
||||||
$accountModel = AccountModel::where('email', $search_account_email)->limit(11)->get(['email', 'id']);
|
|
||||||
if (count($accountModel) == 0) {
|
|
||||||
echo_error('No entries found.');
|
|
||||||
} else if (count($accountModel) == 1) {
|
|
||||||
$id = $accountModel->first()->getKey();
|
|
||||||
} else if (count($accountModel) > 10) {
|
|
||||||
echo_error('Specified e-mail resulted with too many accounts.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isset($_REQUEST['search'])) {
|
|
||||||
$search_account = $_REQUEST['search'];
|
|
||||||
$min_size = 3;
|
|
||||||
if (in_array($nameOrNumberColumn, ['id', 'number'])) {
|
|
||||||
$min_size = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen($search_account) < $min_size && !Validator::number($search_account)) {
|
|
||||||
echo_error('Account ' . $nameOrNumberColumn . ' is too short.');
|
|
||||||
} else {
|
|
||||||
$query = AccountModel::where($nameOrNumberColumn, '=', $search_account)->limit(11)->get(['id', $nameOrNumberColumn]);
|
|
||||||
if (count($query) == 0) {
|
|
||||||
echo_error('No entries found.');
|
|
||||||
} else if (count($query) == 1) {
|
|
||||||
$id = $query->first()->getKey();
|
|
||||||
} else if (count($query) > 10) {
|
|
||||||
echo_error('Specified name resulted with too many accounts.');
|
|
||||||
} else {
|
|
||||||
$str_construct = 'Do you mean?<ul class="mb-0">';
|
|
||||||
foreach ($query as $row) {
|
|
||||||
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row->getKey() . '">' . $row->attributes[$nameOrNumberColumn] . '</a></li>';
|
|
||||||
}
|
|
||||||
$str_construct .= '</ul>';
|
|
||||||
echo_error($str_construct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<div class="row">
|
|
||||||
<?php
|
|
||||||
$groups = new OTS_Groups_List();
|
|
||||||
if ($id > 0) {
|
|
||||||
$account = new OTS_Account();
|
|
||||||
$account->load($id);
|
|
||||||
|
|
||||||
if (isset($_POST['save']) && $account->isLoaded()) {
|
|
||||||
$error = false;
|
|
||||||
|
|
||||||
$_error = '';
|
|
||||||
$account_db = new OTS_Account();
|
|
||||||
if (USE_ACCOUNT_NAME) {
|
|
||||||
$name = $_POST['name'];
|
|
||||||
|
|
||||||
$account_db->find($name);
|
|
||||||
if ($account_db->isLoaded() && $account->getName() != $name)
|
|
||||||
echo_error('This name is already used. Please choose another name!');
|
|
||||||
}
|
|
||||||
|
|
||||||
$account_db->load($id);
|
|
||||||
if (!$account_db->isLoaded())
|
|
||||||
echo_error('Account with this id doesn\'t exist.');
|
|
||||||
|
|
||||||
//type/group
|
|
||||||
if ($hasTypeColumn || $hasGroupColumn) {
|
|
||||||
$group = $_POST['group'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$password = ((!empty($_POST["pass"]) ? $_POST['pass'] : null));
|
|
||||||
if (!Validator::password($password)) {
|
|
||||||
$errors['password'] = Validator::getLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
//secret
|
|
||||||
if ($hasSecretColumn) {
|
|
||||||
$secret = $_POST['secret'];
|
|
||||||
}
|
|
||||||
|
|
||||||
//key
|
|
||||||
$key = $_POST['key'];
|
|
||||||
$email = $_POST['email'];
|
|
||||||
if (!Validator::email($email))
|
|
||||||
$errors['email'] = Validator::getLastError();
|
|
||||||
|
|
||||||
//tibia coins
|
|
||||||
if ($hasCoinsColumn) {
|
|
||||||
$t_coins = $_POST['t_coins'];
|
|
||||||
verify_number($t_coins, 'Tibia coins', 12);
|
|
||||||
}
|
|
||||||
// prem days
|
|
||||||
$p_days = (int)$_POST['p_days'];
|
|
||||||
verify_number($p_days, 'Prem days', 11);
|
|
||||||
|
|
||||||
//prem points
|
|
||||||
$p_points = $_POST['p_points'];
|
|
||||||
verify_number($p_points, 'Prem Points', 11);
|
|
||||||
|
|
||||||
//rl name
|
|
||||||
$rl_name = $_POST['rl_name'];
|
|
||||||
|
|
||||||
//location
|
|
||||||
$rl_loca = $_POST['rl_loca'];
|
|
||||||
|
|
||||||
//country
|
|
||||||
if(setting('core.account_country')) {
|
|
||||||
$rl_country = $_POST['rl_country'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$web_flags = $_POST['web_flags'];
|
|
||||||
verify_number($web_flags, 'Web Flags', 1);
|
|
||||||
|
|
||||||
//created
|
|
||||||
$created = strtotime($_POST['created']);
|
|
||||||
verify_number($created, 'Created', 11);
|
|
||||||
|
|
||||||
//web last login
|
|
||||||
$web_lastlogin = strtotime($_POST['web_lastlogin']);
|
|
||||||
verify_number($web_lastlogin, 'Web Last login', 11);
|
|
||||||
|
|
||||||
if (!$error && $hooks->trigger(HOOK_ADMIN_ACCOUNTS_SAVE_POST, ['account_id' => $account->getId(), 'account_email' => $account->getEMail()])) {
|
|
||||||
if (USE_ACCOUNT_NAME) {
|
|
||||||
$account->setName($name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($hasTypeColumn) {
|
|
||||||
$account->setCustomField('type', $group);
|
|
||||||
} elseif ($hasGroupColumn) {
|
|
||||||
$account->setCustomField('group_id', $group);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($hasSecretColumn) {
|
|
||||||
$account->setCustomField('secret', $secret);
|
|
||||||
}
|
|
||||||
$account->setCustomField('key', $key);
|
|
||||||
$account->setEMail($email);
|
|
||||||
if ($hasCoinsColumn) {
|
|
||||||
$account->setCustomField('coins', $t_coins);
|
|
||||||
}
|
|
||||||
|
|
||||||
$lastDay = 0;
|
|
||||||
if($p_days != 0 && $p_days != OTS_Account::GRATIS_PREMIUM_DAYS) {
|
|
||||||
$lastDay = time();
|
|
||||||
} else if ($lastDay != 0) {
|
|
||||||
$lastDay = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$account->setPremDays($p_days);
|
|
||||||
$account->setLastLogin($lastDay);
|
|
||||||
if ($hasPointsColumn) {
|
|
||||||
$account->setCustomField('premium_points', $p_points);
|
|
||||||
}
|
|
||||||
$account->setRLName($rl_name);
|
|
||||||
$account->setLocation($rl_loca);
|
|
||||||
|
|
||||||
if(setting('core.account_country')) {
|
|
||||||
$account->setCountry($rl_country);
|
|
||||||
}
|
|
||||||
|
|
||||||
$account->setCustomField('created', $created);
|
|
||||||
$account->setWebFlags($web_flags);
|
|
||||||
$account->setCustomField('web_lastlogin', $web_lastlogin);
|
|
||||||
|
|
||||||
if (isset($password)) {
|
|
||||||
if (USE_ACCOUNT_SALT) {
|
|
||||||
$salt = generateRandomString(10, false, true, true);
|
|
||||||
$password = $salt . $password;
|
|
||||||
$account->setCustomField('salt', $salt);
|
|
||||||
}
|
|
||||||
|
|
||||||
$password = encrypt($password);
|
|
||||||
$account->setPassword($password);
|
|
||||||
|
|
||||||
if (USE_ACCOUNT_SALT)
|
|
||||||
$account->setCustomField('salt', $salt);
|
|
||||||
}
|
|
||||||
|
|
||||||
$account->save();
|
|
||||||
echo_success('Account saved at: ' . date('G:i'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ($id == 0) {
|
|
||||||
$accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ', email FROM `accounts` ORDER BY `id` ASC');
|
|
||||||
?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-10">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Accounts</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<table class="acc_datatable table table-striped table-bordered table-responsive d-md-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>ID</th>
|
|
||||||
<th><?= ($nameOrNumberColumn == 'name' ? 'Name' : 'Number'); ?></th>
|
|
||||||
<?php if($hasTypeColumn || $hasGroupColumn): ?>
|
|
||||||
<th>E-Mail</th>
|
|
||||||
<th>Position</th>
|
|
||||||
<?php endif; ?>
|
|
||||||
<th style="width: 40px">Edit</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($accounts_db as $account_lst): ?>
|
|
||||||
<tr>
|
|
||||||
<th><?php echo $account_lst['id']; ?></th>
|
|
||||||
<td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td>
|
|
||||||
<td><?php echo $account_lst['email']; ?></td>
|
|
||||||
<?php if($hasTypeColumn || $hasGroupColumn): ?>
|
|
||||||
<td>
|
|
||||||
<?php if ($hasTypeColumn) {
|
|
||||||
echo $acc_type[$account_lst['type']];
|
|
||||||
} elseif ($hasGroupColumn) {
|
|
||||||
$group = $groups->getGroups();
|
|
||||||
echo $group[$account_lst['group_id']];
|
|
||||||
} ?>
|
|
||||||
</td>
|
|
||||||
<?php endif; ?>
|
|
||||||
<td><a href="?p=accounts&id=<?php echo $account_lst['id']; ?>" class="btn btn-success btn-sm" title="Edit">
|
|
||||||
<i class="fas fa-pencil-alt"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php if (isset($account) && $account->isLoaded()) { ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-10">
|
|
||||||
<div class="card card-primary card-outline card-outline-tabs">
|
|
||||||
<div class="card-header p-0 border-bottom-0">
|
|
||||||
<ul class="nav nav-tabs" id="accounts-tab" role="tablist">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="accounts-logs-tab" data-toggle="pill" href="#accounts-logs">Logs</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a>
|
|
||||||
</li>
|
|
||||||
<?php if ($db->hasTable('bans')) : ?>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="accounts-bans-tab" data-toggle="pill" href="#accounts-bans">Bans</a>
|
|
||||||
</li>
|
|
||||||
<?php endif;
|
|
||||||
|
|
||||||
if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) : ?>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a>
|
|
||||||
</li>
|
|
||||||
<?php endif; ?>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="tab-content" id="accounts-tabContent">
|
|
||||||
<div class="tab-pane fade active show" id="accounts-acc">
|
|
||||||
<form action="<?php echo $admin_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post">
|
|
||||||
<?php csrf(); ?>
|
|
||||||
<div class="form-group row">
|
|
||||||
<?php if (USE_ACCOUNT_NAME): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-4">
|
|
||||||
<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">
|
|
||||||
<input type="checkbox"
|
|
||||||
name="c_pass"
|
|
||||||
id="c_pass"
|
|
||||||
value="false"
|
|
||||||
class="form-check-input"/>
|
|
||||||
<label for="c_pass">Password: (check to change)</label>
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" class="form-control" id="pass" name="pass" autocomplete="off" maxlength="20" value=""/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-3">
|
|
||||||
<label for="account_id" class="control-label">Account ID:</label>
|
|
||||||
<input type="text" class="form-control" id="account_id" name="account_id" autocomplete="off" size="8" maxlength="11" disabled value="<?php echo $account->getId(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<?php
|
|
||||||
$acc_group = $account->getAccGroupId();
|
|
||||||
if ($hasTypeColumn) {
|
|
||||||
?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="group">Account Type:</label>
|
|
||||||
<select name="group" id="group" class="form-control">
|
|
||||||
<?php foreach ($acc_type as $_id => $a_type): ?>
|
|
||||||
<option value="<?php echo($_id); ?>" <?php echo($acc_group == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
} elseif ($hasGroupColumn) {
|
|
||||||
?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="group">Account Type:</label>
|
|
||||||
<select name="group" id="group" class="form-control">
|
|
||||||
<?php foreach ($groups->getGroups() as $_id => $group): ?>
|
|
||||||
<option value="<?php echo $_id; ?>" <?php echo($acc_group == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="web_flags">Website Access:</label>
|
|
||||||
<select name="web_flags" id="web_flags" class="form-control">
|
|
||||||
<?php foreach ($web_acc as $_id => $a_type): ?>
|
|
||||||
<option value="<?php echo($_id); ?>" <?php echo($account->getWebFlags() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<?php if ($hasSecretColumn): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="secret">Secret:</label>
|
|
||||||
<input type="text" class="form-control" id="secret" name="secret" autocomplete="off" value="<?php echo $account->getCustomField('secret'); ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="key">Recovery Key:</label>
|
|
||||||
<input type="text" class="form-control" id="key" name="key" autocomplete="off" value="<?php echo $account->getCustomField('key'); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="email">Email:</label><?php echo (setting('core.mail_enabled') ? ' (<a href="' . ADMIN_URL . '?p=mailer&mail_to=' . $account->getEMail() . '">Send Mail</a>)' : ''); ?>
|
|
||||||
<input type="text" class="form-control" id="email" name="email" autocomplete="off" value="<?php echo $account->getEMail(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php if ($hasCoinsColumn): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="t_coins">Tibia Coins:</label>
|
|
||||||
<input type="text" class="form-control" id="t_coins" name="t_coins" autocomplete="off" maxlength="11" value="<?php echo $account->getCustomField('coins') ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="p_days">Premium Days:</label>
|
|
||||||
<input type="text" class="form-control" id="p_days" name="p_days" autocomplete="off" maxlength="11" value="<?php echo $account->getPremDays(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php if ($hasPointsColumn): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="p_points" class="control-label">Premium Points:</label>
|
|
||||||
<input type="text" class="form-control" id="p_points" name="p_points" autocomplete="off" maxlength="8" value="<?php echo $account->getCustomField('premium_points') ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-4">
|
|
||||||
<label for="rl_name">RL Name:</label>
|
|
||||||
<input type="text" class="form-control" id="rl_name" name="rl_name"
|
|
||||||
autocomplete="off" maxlength="20"
|
|
||||||
value="<?php echo $account->getRLName(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-4">
|
|
||||||
<label for="rl_loca">Location:</label>
|
|
||||||
<input type="text" class="form-control" id="rl_loca" name="rl_loca"
|
|
||||||
autocomplete="off" maxlength="20"
|
|
||||||
value="<?php echo $account->getLocation(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php if(setting('core.account_country')): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-4">
|
|
||||||
<label for="rl_country">Country:</label>
|
|
||||||
<select name="rl_country" id="rl_country" class="form-control">
|
|
||||||
<?php foreach ($countries as $_id => $a_type): ?>
|
|
||||||
<option value="<?php echo($_id); ?>" <?php echo($account->getCountry() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="created" class="control-label">Created:</label>
|
|
||||||
<input type="text" class="form-control" id="created" name="created" autocomplete="off" maxlength="20" value="<?php echo date("M d Y, H:i:s", $account->getCustomField('created')); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="web_lastlogin" class="control-label">Web Last Login:</label>
|
|
||||||
<input type="text" class="form-control" id="web_lastlogin" name="web_lastlogin" autocomplete="off" maxlength="20" value="<?php echo date("M d Y, H:i:s", $account->getCustomField('web_lastlogin')); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="hidden" name="save" value="yes"/>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-info"><i class="fas fa-update"></i> Update</button>
|
|
||||||
<a href="<?php echo ADMIN_URL; ?>?p=accounts" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="accounts-logs">
|
|
||||||
<div class="row">
|
|
||||||
<table class="table table-striped table-condensed table-responsive d-md-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>#</th>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Action</th>
|
|
||||||
<th>IP</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
$accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
|
|
||||||
foreach ($accountActions as $i => $log):
|
|
||||||
$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6));
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo $i + 1; ?></td>
|
|
||||||
<td><?= date("M d Y, H:i:s", $log->date); ?></td>
|
|
||||||
<td><?= $log->action; ?></td>
|
|
||||||
<td><?= $log->ip; ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="accounts-chars">
|
|
||||||
<div class="row">
|
|
||||||
<?php
|
|
||||||
if (isset($account) && $account->isLoaded()) {
|
|
||||||
$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get();
|
|
||||||
if (isset($account_players)) { ?>
|
|
||||||
<table class="table table-striped table-condensed table-responsive d-md-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>#</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Level</th>
|
|
||||||
<th>Vocation</th>
|
|
||||||
<th style="width: 40px">Edit</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($account_players as $i => $player): ?>
|
|
||||||
<tr>
|
|
||||||
<th><?php echo $i + 1; ?></th>
|
|
||||||
<td><?php echo $player->name; ?></td>
|
|
||||||
<td><?php echo $player->level; ?></td>
|
|
||||||
<td><?php echo $player->vocation_name; ?></td>
|
|
||||||
<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php if ($db->hasTable('bans')) : ?>
|
|
||||||
<div class="tab-pane fade" id="accounts-bans">
|
|
||||||
<?php
|
|
||||||
$bans = $db->query('SELECT * FROM ' . $db->tableName('bans') . ' WHERE ' . $db->fieldName('active') . ' = 1 AND ' . $db->fieldName('id') . ' = ' . $account->getId() . ' ORDER BY ' . $db->fieldName('added') . ' DESC LIMIT 10');
|
|
||||||
if ($bans->rowCount()) {
|
|
||||||
?>
|
|
||||||
<table class="table table-striped table-condensed table-responsive d-md-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Nick</th>
|
|
||||||
<th>Type</th>
|
|
||||||
<th>Expires</th>
|
|
||||||
<th>Reason</th>
|
|
||||||
<th>Comment</th>
|
|
||||||
<th>Added by:</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
foreach ($bans as $ban) {
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td><?php
|
|
||||||
$pName = getPlayerNameByAccount($ban['value']);
|
|
||||||
echo '<a href="?p=players&search=' . $pName . '">' . $pName . '</a>'; ?>
|
|
||||||
</td>
|
|
||||||
<td><?php echo getBanType($ban['type']); ?></td>
|
|
||||||
<td>
|
|
||||||
<?php
|
|
||||||
if ($ban['expires'] == "-1")
|
|
||||||
echo 'Never';
|
|
||||||
else
|
|
||||||
echo date("H:i:s", $ban['expires']) . '<br/>' . date("d M Y", $ban['expires']);
|
|
||||||
?>
|
|
||||||
</td>
|
|
||||||
<td><?php echo getBanReason($ban['reason']); ?></td>
|
|
||||||
<td><?php echo $ban['comment']; ?></td>
|
|
||||||
<td>
|
|
||||||
<?php
|
|
||||||
if ($ban['admin_id'] == "0")
|
|
||||||
echo 'Autoban';
|
|
||||||
else
|
|
||||||
$aName = getPlayerNameByAccount($ban['admin_id']);
|
|
||||||
echo '<a href="?p=players&search=' . $aName . '">' . $aName . '</a>';
|
|
||||||
echo '<br/>' . date("d.m.Y", $ban['added']);
|
|
||||||
?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php } ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<?php
|
|
||||||
} else {
|
|
||||||
echo 'No Account bans.';
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
||||||
<?php endif;
|
|
||||||
if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) { ?>
|
|
||||||
<div class="tab-pane fade" id="accounts-store">
|
|
||||||
<?php $store_history = $db->query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?>
|
|
||||||
<table class="table table-striped table-condensed table-responsive d-md-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Description</th>
|
|
||||||
<th>Coins</th>
|
|
||||||
<th>Date</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($store_history as $p): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo $p['description']; ?></td>
|
|
||||||
<td><?php echo $p['coin_amount']; ?></td>
|
|
||||||
<td><?php echo date('d M y H:i:s', $p['time']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-2">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Search Accounts</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-6 col-lg-12">
|
|
||||||
<form action="<?php echo $admin_base; ?>" method="post">
|
|
||||||
<?php csrf(); ?>
|
|
||||||
<label for="search">Account E-Mail:</label>
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input type="email" class="form-control" id="search_email" name="search_email" value="<?= escapeHtml($search_account_email); ?>" maxlength="255" size="255">
|
|
||||||
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 col-lg-12">
|
|
||||||
<form action="<?php echo $admin_base; ?>" method="post">
|
|
||||||
<?php csrf(); ?>
|
|
||||||
<label for="search">Account Name:</label>
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_account); ?>" maxlength="32" size="32">
|
|
||||||
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 col-lg-12">
|
|
||||||
<form action="<?php echo $admin_base; ?>" method="post">
|
|
||||||
<?php csrf(); ?>
|
|
||||||
<label for="id">Account ID:</label>
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32">
|
|
||||||
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('#created').datetimepicker({format: "M d Y, H:i:s",});
|
|
||||||
$('#web_lastlogin').datetimepicker({format: 'M d Y, H:i:s'});
|
|
||||||
|
|
||||||
$('#c_pass').change(function () {
|
|
||||||
const ipass = $('input[name=pass]');
|
|
||||||
ipass[0].disabled = !this.checked;
|
|
||||||
ipass[0].value = '';
|
|
||||||
}).change();
|
|
||||||
|
|
||||||
$('.acc_datatable').DataTable({
|
|
||||||
"order": [[0, "asc"]]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -1,131 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* CHANGELOG modifier
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @author Lee
|
|
||||||
* @copyright 2020 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Changelog;
|
|
||||||
use MyAAC\Models\Changelog as ModelsChangelog;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$title = 'Changelog';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
|
|
||||||
echo 'Access denied.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$use_datatable = true;
|
|
||||||
const CL_LIMIT = 600; // maximum changelog body length
|
|
||||||
|
|
||||||
$id = $_GET['id'] ?? 0;
|
|
||||||
|
|
||||||
if(!empty($action) && isRequestMethod('post'))
|
|
||||||
{
|
|
||||||
$id = $_POST['id'] ?? null;
|
|
||||||
$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null;
|
|
||||||
$create_date = isset($_POST['createdate']) ? (int)strtotime($_POST['createdate'] ): null;
|
|
||||||
$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null;
|
|
||||||
$type = isset($_POST['type']) ? (int)$_POST['type'] : null;
|
|
||||||
$where = isset($_POST['where']) ? (int)$_POST['where'] : null;
|
|
||||||
|
|
||||||
$errors = array();
|
|
||||||
|
|
||||||
if($action == 'new') {
|
|
||||||
|
|
||||||
if(isset($body) && Changelog::add($body, $type, $where, $player_id, $create_date, $errors)) {
|
|
||||||
$body = '';
|
|
||||||
$type = $where = $player_id = $create_date = 0;
|
|
||||||
|
|
||||||
success('Added successful.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if($action == 'delete') {
|
|
||||||
if (Changelog::delete($id, $errors)) {
|
|
||||||
success('Deleted successful.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if($action == 'edit')
|
|
||||||
{
|
|
||||||
if(isset($id) && !isset($body)) {
|
|
||||||
$cl = Changelog::get($id);
|
|
||||||
$body = $cl['body'];
|
|
||||||
$type = $cl['type'];
|
|
||||||
$where = $cl['where'];
|
|
||||||
$create_date = $cl['date'];
|
|
||||||
$player_id = $cl['player_id'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(Changelog::update($id, $body, $type, $where, $player_id, $create_date,$errors)) {
|
|
||||||
$action = $body = '';
|
|
||||||
$type = $where = $player_id = $create_date = 0;
|
|
||||||
|
|
||||||
success('Updated successful.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if($action == 'hide') {
|
|
||||||
if (Changelog::toggleHide($id, $errors, $status)) {
|
|
||||||
success(($status == 1 ? 'Hide' : 'Show') . ' successful.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!empty($errors))
|
|
||||||
error(implode(", ", $errors));
|
|
||||||
}
|
|
||||||
|
|
||||||
$changelogs = ModelsChangelog::orderBy('id')->get()->toArray();
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
|
|
||||||
$log_type = [
|
|
||||||
['id' => 1, 'icon' => 'added'],
|
|
||||||
['id' => 2, 'icon' => 'removed'],
|
|
||||||
['id' => 3, 'icon' => 'changed'],
|
|
||||||
['id' => 4, 'icon' => 'fixed'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$log_where = [
|
|
||||||
['id' => 1, 'icon' => 'server'],
|
|
||||||
['id' => 2, 'icon' => 'website'],
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach($changelogs as $key => &$log)
|
|
||||||
{
|
|
||||||
$log['type'] = getChangelogType($log['type']);
|
|
||||||
$log['where'] = getChangelogWhere($log['where']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($action == 'edit' || $action == 'new') {
|
|
||||||
if($action == 'edit') {
|
|
||||||
$player = new OTS_Player();
|
|
||||||
$player->load($player_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$account_players = $account_logged->getPlayersList();
|
|
||||||
$account_players->orderBy('group_id', POT::ORDER_DESC);
|
|
||||||
$twig->display('admin.changelog.form.html.twig', array(
|
|
||||||
'action' => $action,
|
|
||||||
'cl_link_form' => constant('ADMIN_URL').'?p=changelog',
|
|
||||||
'cl_id' => $id ?? null,
|
|
||||||
'body' => isset($body) ? escapeHtml($body) : '',
|
|
||||||
'create_date' => $create_date ?? '',
|
|
||||||
'player_id' => $player_id ?? null,
|
|
||||||
'account_players' => $account_players,
|
|
||||||
'type' => $type ?? 0,
|
|
||||||
'where' => $where ?? 0,
|
|
||||||
'log_type' => $log_type,
|
|
||||||
'log_where' => $log_where,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
$twig->display('admin.changelog.html.twig', array(
|
|
||||||
'changelogs' => $changelogs,
|
|
||||||
));
|
|
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* CHANGELOG viewer
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @author Lee
|
|
||||||
* @copyright 2020 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'MyAAC Changelog';
|
|
||||||
|
|
||||||
if (!file_exists(BASE . 'CHANGELOG.md')) {
|
|
||||||
echo 'File CHANGELOG.md doesn\'t exist.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$changelog = file_get_contents(BASE . 'CHANGELOG.md');
|
|
||||||
|
|
||||||
$Parsedown = new Parsedown();
|
|
||||||
|
|
||||||
$changelog = $Parsedown->text($changelog); # prints: <p>Hello <em>Parsedown</em>!</p>
|
|
||||||
|
|
||||||
echo '<div>' . $changelog . '</div>';
|
|
@ -1,63 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Dashboard
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Dashboard';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
if (isset($_POST['clear_cache'])) {
|
|
||||||
if (clearCache()) {
|
|
||||||
success('Cache cleared.');
|
|
||||||
} else {
|
|
||||||
error('Error while clearing cache.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['maintenance'])) {
|
|
||||||
$message = (!empty($_POST['message']) ? $_POST['message'] : null);
|
|
||||||
$_status = (isset($_POST['status']) && $_POST['status'] == 'true');
|
|
||||||
$_status = ($_status ? '0' : '1');
|
|
||||||
|
|
||||||
if (empty($message)) {
|
|
||||||
error('Message cannot be empty.');
|
|
||||||
} else if (strlen($message) > 255) {
|
|
||||||
error('Message is too long. Maximum length allowed is 255 chars.');
|
|
||||||
} else {
|
|
||||||
$tmp = '';
|
|
||||||
if (fetchDatabaseConfig('site_closed', $tmp))
|
|
||||||
updateDatabaseConfig('site_closed', $_status);
|
|
||||||
else
|
|
||||||
registerDatabaseConfig('site_closed', $_status);
|
|
||||||
|
|
||||||
if (fetchDatabaseConfig('site_closed_message', $tmp))
|
|
||||||
updateDatabaseConfig('site_closed_message', $message);
|
|
||||||
else
|
|
||||||
registerDatabaseConfig('site_closed_message', $message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$is_closed = getDatabaseConfig('site_closed') == '1';
|
|
||||||
|
|
||||||
$closed_message = 'Server is under maintenance, please visit later.';
|
|
||||||
$tmp = '';
|
|
||||||
if (fetchDatabaseConfig('site_closed_message', $tmp))
|
|
||||||
$closed_message = $tmp;
|
|
||||||
|
|
||||||
$settingAdminPanelModules = setting('core.admin_panel_modules');
|
|
||||||
if (count($settingAdminPanelModules) > 0) {
|
|
||||||
echo '<div class="row">';
|
|
||||||
$twig_loader->prependPath(__DIR__ . '/modules/templates');
|
|
||||||
foreach ($settingAdminPanelModules as $box) {
|
|
||||||
$file = __DIR__ . '/modules/' . $box . '.php';
|
|
||||||
if (file_exists($file)) {
|
|
||||||
include($file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Load items.xml
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Server Data';
|
|
||||||
|
|
||||||
$twig->display('admin.data.html.twig');
|
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Login
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Login';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
require PAGES . 'account/login.php';
|
|
||||||
if ($logged) {
|
|
||||||
header('Location: ' . (admin() ? ADMIN_URL : BASE_URL));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.login.html.twig', [
|
|
||||||
'logout' => (ACTION == 'logout' ? 'You have been logged out!' : ''),
|
|
||||||
'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number',
|
|
||||||
'account_login_by' => getAccountLoginByLabel(),
|
|
||||||
'errors' => $errors ?? ''
|
|
||||||
]);
|
|
@ -1,83 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Logs
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2020 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Logs Viewer';
|
|
||||||
$use_datatable = true;
|
|
||||||
|
|
||||||
$files = array();
|
|
||||||
$aac_path_logs = BASE . 'system/logs/';
|
|
||||||
foreach (scandir($aac_path_logs, SCANDIR_SORT_ASCENDING) as $f) {
|
|
||||||
if ($f[0] === '.' || is_dir($aac_path_logs . $f) || $f === 'index.html') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$files[] = array($f, $aac_path_logs);
|
|
||||||
}
|
|
||||||
|
|
||||||
$server_path_logs = $config['server_path'] . 'logs/';
|
|
||||||
if (!file_exists($server_path_logs)) {
|
|
||||||
$server_path_logs = $config['data_path'] . 'logs/';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_exists($server_path_logs)) {
|
|
||||||
foreach (scandir($server_path_logs, SCANDIR_SORT_ASCENDING) as $f) {
|
|
||||||
if ($f[0] === '.') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_dir($server_path_logs . $f)) {
|
|
||||||
foreach (scandir($server_path_logs . $f, SCANDIR_SORT_ASCENDING) as $f2) {
|
|
||||||
if ($f2[0] === '.') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$files[] = array($f . '/' . $f2, $server_path_logs);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$files[] = array($f, $server_path_logs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($files as &$f) {
|
|
||||||
$f['mtime'] = filemtime($f[1] . $f[0]);
|
|
||||||
$f['name'] = $f[0];
|
|
||||||
}
|
|
||||||
unset($f);
|
|
||||||
|
|
||||||
|
|
||||||
define('EXIST_NONE', 0);
|
|
||||||
define('EXIST_SERVER_LOG', 1);
|
|
||||||
define('EXIST_AAC_LOG', 2);
|
|
||||||
|
|
||||||
$exist = EXIST_NONE;
|
|
||||||
$file = isset($_GET['file']) ? $_GET['file'] : null;
|
|
||||||
if (!empty($file)) {
|
|
||||||
if (!preg_match('/[^A-z0-9\' _\/\-\.]/', $file)) {
|
|
||||||
if (file_exists($aac_path_logs . $file)) {
|
|
||||||
$exist = EXIST_AAC_LOG;
|
|
||||||
} else if (file_exists($server_path_logs . $file)) {
|
|
||||||
$exist = EXIST_SERVER_LOG;
|
|
||||||
} else {
|
|
||||||
echo 'Specified file does not exist.';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($exist !== EXIST_NONE) {
|
|
||||||
$file_content = nl2br(file_get_contents(($exist === EXIST_SERVER_LOG ? $server_path_logs : $aac_path_logs) . $file));
|
|
||||||
$twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $file_content));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo 'Invalid file name specified.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.logs.html.twig', array('files' => $files));
|
|
@ -1,88 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Mailer
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Models\Account;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Mailer';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) {
|
|
||||||
echo 'Access denied.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!setting('core.mail_enabled')) {
|
|
||||||
echo 'Mail support disabled in config.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$mail_to = isset($_POST['mail_to']) ? stripslashes(trim($_POST['mail_to'])) : null;
|
|
||||||
$mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null;
|
|
||||||
$mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null;
|
|
||||||
|
|
||||||
if (isset($_POST['submit'])) {
|
|
||||||
if (empty($mail_subject)) {
|
|
||||||
warning('Please enter subject of the message.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($mail_content)) {
|
|
||||||
warning('Please enter content of the message.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!empty($mail_to)) {
|
|
||||||
if(!Validator::email($mail_to)) {
|
|
||||||
warning('E-Mail is invalid.');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!empty($mail_content) && !empty($mail_subject)) {
|
|
||||||
if (_mail($mail_to, $mail_subject, $mail_content)) {
|
|
||||||
success("Successfully mailed <strong>$mail_to</strong>");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error("Error while sending mail to <strong>$mail_to</strong>. More info can be found in system/logs/mailer-error.log");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($mail_content) && !empty($mail_subject) && empty($mail_to)) {
|
|
||||||
$success = 0;
|
|
||||||
$failed = 0;
|
|
||||||
|
|
||||||
$add = '';
|
|
||||||
if (setting('core.account_mail_verify')) {
|
|
||||||
note('Note: Sending only to users with verified E-Mail.');
|
|
||||||
$add = ' AND `email_verified` = 1';
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = Account::where('email', '!=', '')->get(['email']);
|
|
||||||
foreach ($query as $email) {
|
|
||||||
if (_mail($email->email, $mail_subject, $mail_content)) {
|
|
||||||
$success++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$failed++;
|
|
||||||
echo '<br />';
|
|
||||||
error('An error occorred while sending email to <b>' . $email->email . '</b>. For Admin: More info can be found in system/logs/mailer-error.log');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
success('Mailing finished.');
|
|
||||||
success("$success emails delivered.");
|
|
||||||
warning("$failed emails failed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.mailer.html.twig', [
|
|
||||||
'mail_to' => $mail_to,
|
|
||||||
'mail_subject' => $mail_subject,
|
|
||||||
'mail_content' => $mail_content
|
|
||||||
]);
|
|
@ -1,186 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Account Admin Tool
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @author Lee
|
|
||||||
* @copyright 2020 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Models\Account;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$title = 'Mass Account Actions';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
$hasCoinsColumn = $db->hasColumn('accounts', 'coins');
|
|
||||||
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
|
|
||||||
$freePremium = $config['lua']['freePremium'];
|
|
||||||
|
|
||||||
function admin_give_points($points)
|
|
||||||
{
|
|
||||||
global $hasPointsColumn;
|
|
||||||
|
|
||||||
if (!$hasPointsColumn) {
|
|
||||||
displayMessage('Points not supported.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Account::query()->increment('premium_points', $points)) {
|
|
||||||
displayMessage('Failed to add points.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
displayMessage($points . ' points added to all accounts.', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function admin_give_coins($coins)
|
|
||||||
{
|
|
||||||
global $hasCoinsColumn;
|
|
||||||
|
|
||||||
if (!$hasCoinsColumn) {
|
|
||||||
displayMessage('Coins not supported.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Account::query()->increment('coins', $coins)) {
|
|
||||||
displayMessage('Failed to add coins.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayMessage($coins . ' coins added to all accounts.', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function admin_give_premdays($days)
|
|
||||||
{
|
|
||||||
global $db, $freePremium;
|
|
||||||
|
|
||||||
if ($freePremium) {
|
|
||||||
displayMessage('Premium days not supported. Free Premium enabled.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = $days * 86400;
|
|
||||||
$now = time();
|
|
||||||
// othire
|
|
||||||
if ($db->hasColumn('accounts', 'premend')) {
|
|
||||||
// append premend
|
|
||||||
if (Account::where('premend', '>', $now)->increment('premend', $value)) {
|
|
||||||
// set premend
|
|
||||||
if (Account::where('premend', '<=', $now)->update(['premend' => $now + $value])) {
|
|
||||||
displayMessage($days . ' premium days added to all accounts.', true);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
displayMessage('Failed to execute set query.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayMessage('Failed to execute append query.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// tfs 0.x
|
|
||||||
if ($db->hasColumn('accounts', 'premdays')) {
|
|
||||||
// append premdays
|
|
||||||
if (Account::query()->update(['premdays' => $days])) {
|
|
||||||
// append lastday
|
|
||||||
if (Account::where('lastday', '>', $now)->increment('lastday', $value)) {
|
|
||||||
// set lastday
|
|
||||||
if (Account::where('lastday', '<=', $now)->update(['lastday' => $now + $value])) {
|
|
||||||
displayMessage($days . ' premium days added to all accounts.', true);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
displayMessage('Failed to execute set query.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
displayMessage('Failed to execute append query.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayMessage('Failed to execute set days query.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// tfs 1.x
|
|
||||||
if ($db->hasColumn('accounts', 'premium_ends_at')) {
|
|
||||||
// append premium_ends_at
|
|
||||||
if (Account::where('premium_ends_at', '>', $now)->increment('premium_ends_at', $value)) {
|
|
||||||
// set premium_ends_at
|
|
||||||
if (Account::where('premium_ends_at', '<=', $now)->update(['premium_ends_at' => $now + $value])) {
|
|
||||||
displayMessage($days . ' premium days added to all accounts.', true);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
displayMessage('Failed to execute set query.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayMessage('Failed to execute append query.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayMessage('Premium Days not supported.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty(ACTION) && isRequestMethod('post')) {
|
|
||||||
|
|
||||||
$action = ACTION;
|
|
||||||
|
|
||||||
if (preg_match("/[^A-z0-9_\-]/", $action)) {
|
|
||||||
displayMessage('Invalid action.');
|
|
||||||
} else {
|
|
||||||
$value = isset($_POST['value']) ? intval($_POST['value']) : 0;
|
|
||||||
|
|
||||||
if (!$value) {
|
|
||||||
displayMessage('Please fill all inputs');
|
|
||||||
} else {
|
|
||||||
switch ($action) {
|
|
||||||
case 'give-points':
|
|
||||||
admin_give_points($value);
|
|
||||||
break;
|
|
||||||
case 'give-coins':
|
|
||||||
admin_give_coins($value);
|
|
||||||
break;
|
|
||||||
case 'give-premdays':
|
|
||||||
admin_give_premdays($value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
displayMessage('Action ' . $action . 'not found.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$twig->display('admin.tools.account.html.twig', array(
|
|
||||||
'hasCoinsColumn' => $hasCoinsColumn,
|
|
||||||
'hasPointsColumn' => $hasPointsColumn,
|
|
||||||
'freePremium' => $freePremium,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayMessage($message, $success = false) {
|
|
||||||
global $twig, $hasCoinsColumn, $hasPointsColumn, $freePremium;
|
|
||||||
|
|
||||||
$success ? success($message): error($message);
|
|
||||||
|
|
||||||
$twig->display('admin.tools.account.html.twig', array(
|
|
||||||
'hasCoinsColumn' => $hasCoinsColumn,
|
|
||||||
'hasPointsColumn' => $hasPointsColumn,
|
|
||||||
'freePremium' => $freePremium,
|
|
||||||
));
|
|
||||||
}
|
|
@ -1,107 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Teleport Admin Tool
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @author Lee
|
|
||||||
* @copyright 2020 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Models\Player;
|
|
||||||
use MyAAC\Models\PlayerOnline;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$title = 'Mass Teleport Actions';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
function admin_teleport_position($x, $y, $z) {
|
|
||||||
if (!Player::query()->update([
|
|
||||||
'posx' => $x, 'posy' => $y, 'posz' => $z
|
|
||||||
])) {
|
|
||||||
displayMessage('Failed to execute query. Probably already updated.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayMessage('Player\'s position updated.', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function admin_teleport_town($town_id) {
|
|
||||||
if (!Player::query()->update([
|
|
||||||
'town_id' => $town_id,
|
|
||||||
])) {
|
|
||||||
displayMessage('Failed to execute query. Probably already updated.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayMessage('Player\'s town updated.', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty(ACTION) && isRequestMethod('post')) {
|
|
||||||
|
|
||||||
$action = ACTION;
|
|
||||||
|
|
||||||
if (preg_match("/[^A-z0-9_\-]/", $action)) {
|
|
||||||
displayMessage('Invalid action.');
|
|
||||||
} else {
|
|
||||||
|
|
||||||
$playersOnline = 0;
|
|
||||||
if($db->hasTable('players_online')) {// tfs 1.0
|
|
||||||
$playersOnline = PlayerOnline::count();
|
|
||||||
} else {
|
|
||||||
$playersOnline = Player::online()->count();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($playersOnline > 0) {
|
|
||||||
displayMessage('Please, close the server before execute this action otherwise players will not be affected.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$town_id = isset($_POST['town_id']) ? intval($_POST['town_id']) : null;
|
|
||||||
$posx = isset($_POST['posx']) ? intval($_POST['posx']) : null;
|
|
||||||
$posy = isset($_POST['posy']) ? intval($_POST['posy']) : null;
|
|
||||||
$posz = isset($_POST['posz']) ? intval($_POST['posz']) : null;
|
|
||||||
$to_temple = $_POST['to_temple'] ?? null;
|
|
||||||
|
|
||||||
switch ($action) {
|
|
||||||
case 'set-town':
|
|
||||||
if (!$town_id) {
|
|
||||||
displayMessage('Please fill all inputs');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($config['towns'][$town_id])) {
|
|
||||||
displayMessage('Specified town does not exist');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
admin_teleport_town($town_id);
|
|
||||||
break;
|
|
||||||
case 'set-position':
|
|
||||||
if (!$to_temple && ($posx < 0 || $posx > 65535 || $posy < 0 || $posy > 65535|| $posz < 0 || $posz > 16)) {
|
|
||||||
displayMessage('Invalid Position');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
admin_teleport_position($posx, $posy, $posz);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
displayMessage('Action ' . $action . 'not found.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$twig->display('admin.tools.teleport.html.twig', array());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function displayMessage($message, $success = false) {
|
|
||||||
global $twig;
|
|
||||||
|
|
||||||
$success ? success($message): error($message);
|
|
||||||
$twig->display('admin.tools.teleport.html.twig', array());
|
|
||||||
}
|
|
@ -1,210 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Menus
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Cache\Cache;
|
|
||||||
use MyAAC\Models\Menu;
|
|
||||||
use MyAAC\Plugins;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Menus';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) {
|
|
||||||
echo 'Access denied.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pluginThemes = Plugins::getThemes();
|
|
||||||
|
|
||||||
if (isset($_POST['template'])) {
|
|
||||||
$template = $_POST['template'];
|
|
||||||
|
|
||||||
if (isset($_POST['save'])) {
|
|
||||||
$post_menu = $_POST['menu'] ?? [];
|
|
||||||
$post_menu_link = $_POST['menu_link'] ?? [];
|
|
||||||
$post_menu_blank = $_POST['menu_blank'] ?? [];
|
|
||||||
$post_menu_color = $_POST['menu_color'] ?? [];
|
|
||||||
if (count($post_menu) != count($post_menu_link)) {
|
|
||||||
echo 'Menu count is not equal menu links. Something went wrong when sending form.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu::where('template', $template)->delete();
|
|
||||||
foreach ($post_menu as $category => $menus) {
|
|
||||||
foreach ($menus as $i => $menu) {
|
|
||||||
if (empty($menu)) // don't save empty menu item
|
|
||||||
continue;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Menu::create([
|
|
||||||
'template' => $template,
|
|
||||||
'name' => $menu,
|
|
||||||
'link' => $post_menu_link[$category][$i],
|
|
||||||
'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0,
|
|
||||||
'color' => str_replace('#', '', $post_menu_color[$category][$i]),
|
|
||||||
'category' => $category,
|
|
||||||
'ordering' => $i
|
|
||||||
]);
|
|
||||||
} catch (PDOException $error) {
|
|
||||||
warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onTemplateMenusChange();
|
|
||||||
success('Saved at ' . date('H:i'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$path = TEMPLATES . $template;
|
|
||||||
|
|
||||||
if (isset($pluginThemes[$template])) {
|
|
||||||
$path = BASE . $pluginThemes[$template];
|
|
||||||
}
|
|
||||||
|
|
||||||
$path .= '/config.php';
|
|
||||||
|
|
||||||
if (file_exists($path)) {
|
|
||||||
require_once $path;
|
|
||||||
} else {
|
|
||||||
echo 'Cannot find template config.php file.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($config['menu_categories'])) {
|
|
||||||
echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET['reset_colors'])) {
|
|
||||||
foreach ($config['menu_categories'] as $id => $options) {
|
|
||||||
$color = $options['default_links_color'] ?? ($config['menu_default_links_color'] ?? ($config['menu_default_color'] ?? '#ffffff'));
|
|
||||||
Menu::where('template', $template)->where('category', $id)->update(['color' => str_replace('#', '', $color)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
onTemplateMenusChange();
|
|
||||||
success('Colors has been reset at ' . date('H:i'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET['reset_menus'])) {
|
|
||||||
$configMenus = config('menus');
|
|
||||||
if (isset($configMenus)) {
|
|
||||||
Plugins::installMenus($template, config('menus'), true);
|
|
||||||
|
|
||||||
onTemplateMenusChange();
|
|
||||||
success('Menus has been reset at ' . date('H:i'));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error("This template don't support reinstalling menus.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$title = 'Menus - ' . $template;
|
|
||||||
|
|
||||||
$canResetColors = isset($config['menu_default_color']) || isset($config['menu_default_links_color']);
|
|
||||||
foreach ($config['menu_categories'] as $id => $options) {
|
|
||||||
if (isset($options['default_links_color'])) {
|
|
||||||
$canResetColors = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.menus.header.html.twig', [
|
|
||||||
'template' => $template,
|
|
||||||
'canResetColors' => $canResetColors
|
|
||||||
]);
|
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
$menus = Menu::query()
|
|
||||||
->select('name', 'link', 'blank', 'color', 'category', 'ordering')
|
|
||||||
->where('enabled', 1)
|
|
||||||
->where('template', $template)
|
|
||||||
->orderBy('ordering')
|
|
||||||
->get()
|
|
||||||
->groupBy('category')
|
|
||||||
->toArray();
|
|
||||||
|
|
||||||
$last_id = array();
|
|
||||||
?>
|
|
||||||
<form method="post" id="menus-form" action="?p=menus">
|
|
||||||
<?php csrf(); ?>
|
|
||||||
<input type="hidden" name="template" value="<?php echo $template ?>"/>
|
|
||||||
<button type="submit" name="save" class="btn btn-info">Save</button><br/><br/>
|
|
||||||
<div class="row">
|
|
||||||
<?php foreach ($config['menu_categories'] as $id => $cat): ?>
|
|
||||||
<div class="col-md-12 col-lg-6">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0"><?php echo $cat['name'] ?> <i class="far fa-plus-square add-button" id="add-button-<?php echo $id ?>"></i></h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<ul class="sortable" id="sortable-<?php echo $id ?>">
|
|
||||||
<?php
|
|
||||||
if (isset($menus[$id])) {
|
|
||||||
$i = 0;
|
|
||||||
foreach ($menus[$id] as $menu):
|
|
||||||
$color = (empty($menu['color']) ? ($cat['default_links_color'] ?? ($config['menu_default_links_color'] ?? ($config['menu_default_color'] ?? '#ffffff'))) : '#' . $menu['color']);
|
|
||||||
?>
|
|
||||||
<li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo escapeHtml($menu['name']); ?>"/>
|
|
||||||
<label>Link:</label> <input type="text" name="menu_link[<?php echo $id ?>][]" value="<?php echo $menu['link'] ?>"/>
|
|
||||||
<input type="hidden" name="menu_blank[<?php echo $id ?>][]" value="0"/>
|
|
||||||
<label><input class="blank-checkbox" type="checkbox" <?php echo($menu['blank'] == 1 ? 'checked' : '') ?>/><span title="Open in New Window">New Window</span></label>
|
|
||||||
<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo $color; ?>"/>
|
|
||||||
<a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li>
|
|
||||||
<?php $i++; $last_id[$id] = $i;
|
|
||||||
endforeach;
|
|
||||||
} ?>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</div>
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<button type="submit" name="save" class="btn btn-info">Save</button>
|
|
||||||
<?php
|
|
||||||
echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>';
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
$twig->display('admin.menus.js.html.twig', array(
|
|
||||||
'menus' => $menus,
|
|
||||||
'last_id' => $last_id,
|
|
||||||
));
|
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
} else {
|
|
||||||
$templates = Menu::select('template')->distinct()->get()->toArray();
|
|
||||||
foreach ($templates as $key => $value) {
|
|
||||||
$path = TEMPLATES . $value['template'];
|
|
||||||
|
|
||||||
if (isset($pluginThemes[$value['template']])) {
|
|
||||||
$path = BASE . $pluginThemes[$value['template']];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file_exists($path . '/config.php')) {
|
|
||||||
unset($templates[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.menus.form.html.twig', array(
|
|
||||||
'templates' => $templates
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onTemplateMenusChange(): void
|
|
||||||
{
|
|
||||||
$cache = Cache::getInstance();
|
|
||||||
if ($cache->enabled()) {
|
|
||||||
$cache->delete('template_menus');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use MyAAC\Models\Player;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$balance = 0;
|
|
||||||
|
|
||||||
if ($db->hasColumn('players', 'balance')) {
|
|
||||||
$balance = Player::orderByDesc('balance')->limit(10)->get(['balance', 'id','name', 'level'])->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('balance.html.twig', array(
|
|
||||||
'balance' => $balance
|
|
||||||
));
|
|
@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use MyAAC\Models\Account;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$coins = 0;
|
|
||||||
|
|
||||||
if ($db->hasColumn('accounts', 'coins')) {
|
|
||||||
$coins = Account::orderByDesc('coins')->limit(10)->get(['coins', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('coins.html.twig', array(
|
|
||||||
'coins' => $coins
|
|
||||||
));
|
|
@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use MyAAC\Models\Account;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$accounts = 0;
|
|
||||||
|
|
||||||
if ($db->hasColumn('accounts', 'created')) {
|
|
||||||
$accounts = Account::orderByDesc('created')->limit(10)->get(['id', 'created'])->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('created.html.twig', array(
|
|
||||||
'accounts' => $accounts,
|
|
||||||
));
|
|
@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use MyAAC\Models\Player;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$players = 0;
|
|
||||||
|
|
||||||
if ($db->hasColumn('players', 'lastlogin')) {
|
|
||||||
$players = Player::orderByDesc('lastlogin')->limit(10)->get(['name', 'level', 'lastlogin'])->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('lastlogin.html.twig', array(
|
|
||||||
'players' => $players,
|
|
||||||
));
|
|
@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use MyAAC\Models\Account;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$points = 0;
|
|
||||||
|
|
||||||
if ($db->hasColumn('accounts', 'premium_points')) {
|
|
||||||
$coins = Account::orderByDesc('premium_points')->limit(10)->get(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('points.html.twig', array(
|
|
||||||
'points' => $points,
|
|
||||||
));
|
|
@ -1,46 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
if (isset($status)) {
|
|
||||||
|
|
||||||
$error_icon = '<i class="fas fa-exclamation-circle text-danger"></i>'; ?>
|
|
||||||
<div class=" col-md-6 col-lg-6">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header border-bottom-0">
|
|
||||||
<span class="font-weight-bold m-0">Server Status</span> <span class="float-right small"><b>Last checked</b>: <?php echo(isset($status['lastCheck']) ? date("l, d.m.Y H:i:s", $status['lastCheck']) : $error_icon); ?></span>
|
|
||||||
</div>
|
|
||||||
<div class="card-body p-0 ">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th width="30%">Server</th>
|
|
||||||
<td><?php echo(isset($status['server']) & isset($status['serverVersion']) ? $status['server'] . ' x ' . $status['serverVersion'] : $error_icon) ?></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Client</th>
|
|
||||||
<td><?php echo(isset($status['clientVersion']) ? $status['clientVersion'] : $error_icon) ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Map</th>
|
|
||||||
<td>
|
|
||||||
<?php if (isset($status['mapName']) & isset($status['mapAuthor']) & isset($status['mapWidth']) & isset($status['mapHeight'])) {
|
|
||||||
echo $status['mapName'] . ' by <b>' . $status['mapAuthor'] . '</b><br/>' . $status['mapWidth'] . ' x ' . $status['mapHeight'];
|
|
||||||
} else {
|
|
||||||
echo $error_icon;
|
|
||||||
} ?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Monsters</th>
|
|
||||||
<td><?php echo (isset($status['monsters']) ? $status['monsters'] : $error_icon); ?></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>MOTD:</th>
|
|
||||||
<td><?php echo(isset($status['motd']) ? $status['motd'] : $error_icon); ?></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use MyAAC\Models\Account;
|
|
||||||
use MyAAC\Models\Guild;
|
|
||||||
use MyAAC\Models\House;
|
|
||||||
use MyAAC\Models\Monster;
|
|
||||||
use MyAAC\Models\Player;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$count = $eloquentConnection->query()
|
|
||||||
->select([
|
|
||||||
'total_accounts' => Account::selectRaw('COUNT(id)'),
|
|
||||||
'total_players' => Player::selectRaw('COUNT(id)'),
|
|
||||||
'total_guilds' => Guild::selectRaw('COUNT(id)'),
|
|
||||||
'total_monsters' => Monster::selectRaw('COUNT(id)'),
|
|
||||||
'total_houses' => House::selectRaw('COUNT(id)'),
|
|
||||||
])->first();
|
|
||||||
|
|
||||||
$twig->display('statistics.html.twig', array(
|
|
||||||
'count' => $count,
|
|
||||||
));
|
|
@ -1,31 +0,0 @@
|
|||||||
{% if balance is iterable %}
|
|
||||||
<div class=" col-md-6 col-lg-3">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Top 10 - Balance</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<table class="table table-striped table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>#</th>
|
|
||||||
<th>Player</th>
|
|
||||||
<th>Balance</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% set i = 0 %}
|
|
||||||
{% for result in balance %}
|
|
||||||
{% set i = i + 1 %}
|
|
||||||
<tr>
|
|
||||||
<th>{{ i }}</th>
|
|
||||||
<td><a href="?p=players&search_name={{ result.name }}">{{ result.name }}</a></td>
|
|
||||||
<td>{{ result.balance }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
@ -1,31 +0,0 @@
|
|||||||
{% if coins is iterable %}
|
|
||||||
<div class=" col-md-6 col-lg-3">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Top 10 - Most coins</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<table class="table table-striped table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>#</th>
|
|
||||||
<th>Account</th>
|
|
||||||
<th>Tibia coins</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% set i = 0 %}
|
|
||||||
{% for result in coins %}
|
|
||||||
{% set i = i + 1 %}
|
|
||||||
<tr>
|
|
||||||
<th>{{ i }}</th>
|
|
||||||
<td><a href="?p=accounts&search_name={{ result.name }}">{{ result.name }}</a></td>
|
|
||||||
<td>{{ result.coins }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
@ -1,31 +0,0 @@
|
|||||||
{% if accounts is iterable %}
|
|
||||||
<div class=" col-md-6 col-lg-3">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Last 10 created</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<table class="table table-striped table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>#</th>
|
|
||||||
<th>Account</th>
|
|
||||||
<th>Creation Date</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% set i = 0 %}
|
|
||||||
{% for result in accounts %}
|
|
||||||
{% set i = i + 1 %}
|
|
||||||
<tr>
|
|
||||||
<th>{{ i }}</th>
|
|
||||||
<td><a href="?p=accounts&id={{ result.id }}">{{ result.id }}</a></td>
|
|
||||||
<td>{{ result.created|date("M d Y, H:i:s") }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
@ -1,31 +0,0 @@
|
|||||||
{% if players is iterable %}
|
|
||||||
<div class=" col-md-6 col-lg-3">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Last 10 logins</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<table class="table table-striped table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>#</th>
|
|
||||||
<th>Player</th>
|
|
||||||
<th>Login Date</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% set i = 0 %}
|
|
||||||
{% for result in players %}
|
|
||||||
{% set i = i + 1 %}
|
|
||||||
<tr>
|
|
||||||
<th>{{ i }}</th>
|
|
||||||
<td><a href="?p=players&search_name={{ result.name }}">{{ result.name }}</a></td>
|
|
||||||
<td>{{ result.lastlogin|date("M d Y, H:i:s") }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
@ -1,31 +0,0 @@
|
|||||||
{% if points is iterable %}
|
|
||||||
<div class=" col-md-6 col-lg-3">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Top 10 - Most premium points</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body p-0">
|
|
||||||
<table class="table table-striped table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>#</th>
|
|
||||||
<th>Account</th>
|
|
||||||
<th>Premium points</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% set i = 0 %}
|
|
||||||
{% for result in points %}
|
|
||||||
{% set i = i + 1 %}
|
|
||||||
<tr>
|
|
||||||
<th>{{ i }}</th>
|
|
||||||
<td><a href="?p=accounts&search_name={{ result.name }}">{{ result.name }}</a></td>
|
|
||||||
<td>{{ result.premium_points }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
@ -1,45 +0,0 @@
|
|||||||
<div class="col">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-info elevation-1"><i class="fas fa-user-plus"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Accounts:</span>
|
|
||||||
<span class="info-box-number">{{ count.total_accounts }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-red elevation-1"><i class="fas fa-user-plus"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Players:</span>
|
|
||||||
<span class="info-box-number">{{ count.total_players }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-teal elevation-1"><i class="fas fa-pastafarianism"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Monsters:</span>
|
|
||||||
<span class="info-box-number">{{ count.total_monsters }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-green elevation-1"><i class="fas fa-chart-pie"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Guilds:</span>
|
|
||||||
<span class="info-box-number">{{ count.total_guilds }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="info-box">
|
|
||||||
<span class="info-box-icon bg-yellow elevation-1"><i class="fas fa-home"></i></span>
|
|
||||||
<div class="info-box-content">
|
|
||||||
<span class="info-box-text">Houses:</span>
|
|
||||||
<span class="info-box-number">{{ count.total_houses }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,43 +0,0 @@
|
|||||||
<div class="col-12 col-md-6">
|
|
||||||
<div class="card card-warning card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<span class="m-0">Website Status<span class="float-right">
|
|
||||||
<div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success">
|
|
||||||
<input form="maintenance-form" type="checkbox" class="custom-control-input" name="status" id="status" value="true" {% if not is_closed %} checked{% endif %}>
|
|
||||||
<label id="status-label" class="custom-control-label" for="status"> {% if is_closed %}Closed{% else %}Open{% endif %}</label>
|
|
||||||
</div></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-body p-2">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<label for="message" class="col-form-label">Maintenance Message</label>
|
|
||||||
<textarea form="maintenance-form" name="message" class="form-control" cols="40" rows="3" maxlength="255" placeholder="Enter ...">{{ closed_message }}</textarea>
|
|
||||||
<small>(only visible if closed)</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<form id="maintenance-form" method="post" action="?p=dashboard" class="float-left">
|
|
||||||
{{ csrf() }}
|
|
||||||
<input type="hidden" name="maintenance" value="1" />
|
|
||||||
<button type="submit" class="btn btn-info"><i class="far fa-update"></i> Update</button>
|
|
||||||
</form>
|
|
||||||
<form method="post" action="?p=dashboard" class="float-right">
|
|
||||||
{{ csrf() }}
|
|
||||||
<input type="hidden" name="clear_cache" value="1" />
|
|
||||||
<button type="submit" onclick="return confirm('Are you sure that you want to clear cache?');" class="btn btn-danger" title="Clear Cache"><i class="fas fa-clear"></i>Clear cache</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
$("#status").change(function() {
|
|
||||||
$statusLabel = $("#status-label");
|
|
||||||
$statusLabel.html("Closed");
|
|
||||||
if ($(this).is(':checked')) {
|
|
||||||
$statusLabel.html("Open");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$twig->display('web_status.twig', array(
|
|
||||||
'is_closed' => $is_closed,
|
|
||||||
'closed_message' => $closed_message,
|
|
||||||
'status' => $status,
|
|
||||||
'account_type' => USE_ACCOUNT_NAME ? 'name' : 'number'
|
|
||||||
));
|
|
||||||
?>
|
|
@ -1,165 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Pages
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Forum;
|
|
||||||
use MyAAC\News;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$title = 'News Panel';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
$use_datatable = true;
|
|
||||||
|
|
||||||
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
|
|
||||||
echo 'Access denied.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
header('X-XSS-Protection:0');
|
|
||||||
|
|
||||||
// some constants, used mainly by database (cannot be modified without schema changes)
|
|
||||||
const NEWS_TITLE_LIMIT = 100;
|
|
||||||
const NEWS_BODY_LIMIT = 65535; // maximum news body length
|
|
||||||
const ARTICLE_TEXT_LIMIT = 300;
|
|
||||||
const ARTICLE_IMAGE_LIMIT = 100;
|
|
||||||
|
|
||||||
$name = $p_title = '';
|
|
||||||
if(!empty($action))
|
|
||||||
{
|
|
||||||
$id = $_POST['id'] ?? null;
|
|
||||||
$p_title = $_POST['title'] ?? null;
|
|
||||||
$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null;
|
|
||||||
$comments = $_POST['comments'] ?? null;
|
|
||||||
$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : 1;
|
|
||||||
$category = isset($_POST['category']) ? (int)$_POST['category'] : null;
|
|
||||||
$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null;
|
|
||||||
$article_text = $_POST['article_text'] ?? null;
|
|
||||||
$article_image = $_POST['article_image'] ?? null;
|
|
||||||
$forum_section = $_POST['forum_section'] ?? null;
|
|
||||||
$errors = [];
|
|
||||||
|
|
||||||
if (isRequestMethod('post')) {
|
|
||||||
if ($action == 'new') {
|
|
||||||
if (isset($forum_section) && $forum_section != '-1') {
|
|
||||||
$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($p_title) && News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) {
|
|
||||||
$p_title = $body = $comments = $article_text = $article_image = '';
|
|
||||||
$type = $category = $player_id = 0;
|
|
||||||
|
|
||||||
success('Added successful.');
|
|
||||||
}
|
|
||||||
} else if ($action == 'delete') {
|
|
||||||
if (News::delete($id, $errors)) {
|
|
||||||
success('Deleted successful.');
|
|
||||||
}
|
|
||||||
} else if ($action == 'edit') {
|
|
||||||
if (isset($id) && !isset($p_title)) {
|
|
||||||
$news = News::get($id);
|
|
||||||
$p_title = $news['title'];
|
|
||||||
$body = $news['body'];
|
|
||||||
$comments = $news['comments'];
|
|
||||||
$type = $news['type'];
|
|
||||||
$category = $news['category'];
|
|
||||||
$player_id = $news['player_id'];
|
|
||||||
$article_text = $news['article_text'];
|
|
||||||
$article_image = $news['article_image'];
|
|
||||||
} else {
|
|
||||||
if (News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) {
|
|
||||||
// update forum thread if exists
|
|
||||||
if (isset($forum_section) && Validator::number($forum_section)) {
|
|
||||||
$db->query("UPDATE `" . TABLE_PREFIX . "forum` SET `author_guid` = " . (int)$player_id . ", `post_text` = " . $db->quote($body) . ", `post_topic` = " . $db->quote($p_title) . ", `edit_date` = " . time() . " WHERE `id` = " . $db->quote($forum_section));
|
|
||||||
}
|
|
||||||
|
|
||||||
$action = $p_title = $body = $comments = $article_text = $article_image = '';
|
|
||||||
$type = $category = $player_id = 0;
|
|
||||||
|
|
||||||
success('Updated successful.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ($action == 'hide') {
|
|
||||||
if (News::toggleHide($id, $errors, $status)) {
|
|
||||||
success(($status == 1 ? 'Hide' : 'Show') . ' successful.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!empty($errors))
|
|
||||||
error(implode(", ", $errors));
|
|
||||||
}
|
|
||||||
|
|
||||||
$categories = array();
|
|
||||||
foreach($db->query('SELECT `id`, `name`, `icon_id` FROM `' . TABLE_PREFIX . 'news_categories` WHERE `hide` != 1') as $cat)
|
|
||||||
{
|
|
||||||
$categories[$cat['id']] = array(
|
|
||||||
'name' => $cat['name'],
|
|
||||||
'icon_id' => $cat['icon_id']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($action == 'edit' || $action == 'new') {
|
|
||||||
if($action == 'edit') {
|
|
||||||
$player = new OTS_Player();
|
|
||||||
$player->load($player_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$account_players = $account_logged->getPlayersList();
|
|
||||||
$account_players->orderBy('group_id', POT::ORDER_DESC);
|
|
||||||
$twig->display('admin.news.form.html.twig', array(
|
|
||||||
'action' => $action,
|
|
||||||
'news_id' => $id ?? null,
|
|
||||||
'title' => $p_title ?? '',
|
|
||||||
'body' => isset($body) ? escapeHtml($body) : '',
|
|
||||||
'type' => $type,
|
|
||||||
'player' => isset($player) && $player->isLoaded() ? $player : null,
|
|
||||||
'player_id' => $player_id ?? null,
|
|
||||||
'account_players' => $account_players,
|
|
||||||
'category' => $category ?? 0,
|
|
||||||
'categories' => $categories,
|
|
||||||
'forum_boards' => getForumBoards(),
|
|
||||||
'forum_section' => $forum_section ?? null,
|
|
||||||
'comments' => $comments ?? null,
|
|
||||||
'article_text' => $article_text ?? null,
|
|
||||||
'article_image' => $article_image ?? null
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news'));
|
|
||||||
$newses = array();
|
|
||||||
|
|
||||||
$cachePlayers = [];
|
|
||||||
foreach ($query as $_news) {
|
|
||||||
$playerId = $_news['player_id'];
|
|
||||||
if (isset($cachePlayers[$playerId])) {
|
|
||||||
$_player = $cachePlayers[$playerId];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$_player = new OTS_Player();
|
|
||||||
$_player->load($playerId);
|
|
||||||
$cachePlayers[$playerId] = $_player;
|
|
||||||
}
|
|
||||||
|
|
||||||
$newses[$_news['type']][] = array(
|
|
||||||
'id' => $_news['id'],
|
|
||||||
'hide' => $_news['hide'],
|
|
||||||
'archive_link' => getLink('news') . '/archive/' . $_news['id'],
|
|
||||||
'title' => $_news['title'],
|
|
||||||
'date' => $_news['date'],
|
|
||||||
'player_name' => $_player->isLoaded() ? $_player->getName() : '',
|
|
||||||
'player_link' => $_player->isLoaded() ? getPlayerLink($_player, false) : '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.news.html.twig', array(
|
|
||||||
'newses' => $newses
|
|
||||||
));
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Notepad
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Models\Notepad as ModelsNotepad;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Notepad';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var OTS_Account $account_logged
|
|
||||||
*/
|
|
||||||
$_content = '';
|
|
||||||
$notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first();
|
|
||||||
if (isset($_POST['content'])) {
|
|
||||||
$_content = html_entity_decode(stripslashes($_POST['content']));
|
|
||||||
if (!$notepad) {
|
|
||||||
ModelsNotepad::create([
|
|
||||||
'account_id' => $account_logged->getId(),
|
|
||||||
'content' => $_content
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ModelsNotepad::where('account_id', $account_logged->getId())->update(['content' => $_content]);
|
|
||||||
}
|
|
||||||
|
|
||||||
success('Saved at ' . date('H:i'));
|
|
||||||
} else {
|
|
||||||
if ($notepad)
|
|
||||||
$_content = $notepad->content;
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.notepad.html.twig', ['content' => $_content]);
|
|
@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Open Source libraries
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2023 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$title = 'Open Source';
|
|
||||||
|
|
||||||
$twig->display('admin.open_source.html.twig');
|
|
@ -1,133 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Pages
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Models\Pages as ModelsPages;
|
|
||||||
use MyAAC\Admin\Pages;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Pages';
|
|
||||||
$use_datatable = true;
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
|
|
||||||
echo 'Access denied.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
header('X-XSS-Protection:0');
|
|
||||||
|
|
||||||
$name = $p_title = null;
|
|
||||||
$groups = new OTS_Groups_List();
|
|
||||||
|
|
||||||
$php = false;
|
|
||||||
$enable_tinymce = true;
|
|
||||||
$access = 0;
|
|
||||||
|
|
||||||
// some constants, used mainly by database (cannot by modified without schema changes)
|
|
||||||
const PAGE_TITLE_LIMIT = 30;
|
|
||||||
const PAGE_NAME_LIMIT = 30;
|
|
||||||
const PAGE_BODY_LIMIT = 65535; // maximum page body length
|
|
||||||
|
|
||||||
if (!empty($action) && isRequestMethod('post')) {
|
|
||||||
if ($action == 'delete' || $action == 'edit' || $action == 'hide') {
|
|
||||||
$id = $_POST['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['name'])) {
|
|
||||||
$name = $_POST['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['title'])) {
|
|
||||||
$p_title = $_POST['title'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$php = isset($_POST['php']) && $_POST['php'] == 1;
|
|
||||||
$enable_tinymce = (isset($_POST['enable_tinymce']) && $_POST['enable_tinymce'] == 1) ?: $enable_tinymce;
|
|
||||||
if ($php) {
|
|
||||||
$body = $_POST['body'];
|
|
||||||
}
|
|
||||||
else if (isset($_POST['body'])) {
|
|
||||||
//$body = $_POST['body'];
|
|
||||||
$body = html_entity_decode(stripslashes($_POST['body']));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['access'])) {
|
|
||||||
$access = $_POST['access'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$errors = array();
|
|
||||||
$player_id = 1;
|
|
||||||
|
|
||||||
if ($action == 'new') {
|
|
||||||
if (isset($p_title) && Pages::add($name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
|
|
||||||
$name = $p_title = $body = '';
|
|
||||||
$player_id = $access = 0;
|
|
||||||
$php = false;
|
|
||||||
$enable_tinymce = true;
|
|
||||||
success('Added successful.');
|
|
||||||
}
|
|
||||||
} else if ($action == 'delete') {
|
|
||||||
if (Pages::delete($id, $errors))
|
|
||||||
success('Page with id ' . $id . ' has been deleted');
|
|
||||||
} else if ($action == 'edit') {
|
|
||||||
if (isset($id) && !isset($_POST['name'])) {
|
|
||||||
$_page = Pages::get($id);
|
|
||||||
$name = $_page['name'];
|
|
||||||
$p_title = $_page['title'];
|
|
||||||
$body = $_page['body'];
|
|
||||||
$php = $_page['php'] == '1';
|
|
||||||
$enable_tinymce = $_page['enable_tinymce'] == '1';
|
|
||||||
$access = $_page['access'];
|
|
||||||
} else {
|
|
||||||
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.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ($action == 'hide') {
|
|
||||||
if (Pages::toggleHide($id, $errors, $status)) {
|
|
||||||
success(($status == 0 ? 'Show' : 'Hide') . ' successful.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($errors))
|
|
||||||
error(implode(", ", $errors));
|
|
||||||
}
|
|
||||||
|
|
||||||
$pages = ModelsPages::all()->map(function ($e) {
|
|
||||||
return [
|
|
||||||
'link' => getFullLink($e->name, $e->name, true),
|
|
||||||
'title' => substr($e->title, 0, 20),
|
|
||||||
'php' => $e->php == '1',
|
|
||||||
'id' => $e->id,
|
|
||||||
'hide' => $e->hide
|
|
||||||
];
|
|
||||||
})->toArray();
|
|
||||||
|
|
||||||
$twig->display('admin.pages.form.html.twig', [
|
|
||||||
'action' => $action,
|
|
||||||
'id' => $action == 'edit' ? $id : null,
|
|
||||||
'name' => $name,
|
|
||||||
'title' => $p_title,
|
|
||||||
'php' => $php,
|
|
||||||
'enable_tinymce' => $enable_tinymce,
|
|
||||||
'body' => isset($body) ? escapeHtml($body) : '',
|
|
||||||
'groups' => $groups->getGroups(),
|
|
||||||
'access' => $access
|
|
||||||
]);
|
|
||||||
|
|
||||||
$twig->display('admin.pages.html.twig', [
|
|
||||||
'pages' => $pages
|
|
||||||
]);
|
|
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* PHP Info
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'PHP Info';
|
|
||||||
|
|
||||||
if (!function_exists('phpinfo')) { ?>
|
|
||||||
<b>phpinfo()</b> function is disabled in your webserver config.<br/>
|
|
||||||
You can enable it by editing <b>php.ini</b> file.
|
|
||||||
<?php return;
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<iframe src="<?php echo ADMIN_URL; ?>tools/phpinfo.php" width="1024" height="550"></iframe>
|
|
@ -1,904 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Players editor
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Forum;
|
|
||||||
use MyAAC\Models\Player;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
|
|
||||||
$title = 'Player editor';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
$player_base = ADMIN_URL . '?p=players';
|
|
||||||
|
|
||||||
$use_datatable = true;
|
|
||||||
|
|
||||||
$skills = array(
|
|
||||||
POT::SKILL_FIST => array('Fist fighting', 'fist'),
|
|
||||||
POT::SKILL_CLUB => array('Club fighting', 'club'),
|
|
||||||
POT::SKILL_SWORD => array('Sword fighting', 'sword'),
|
|
||||||
POT::SKILL_AXE => array('Axe fighting', 'axe'),
|
|
||||||
POT::SKILL_DIST => array('Distance fighting', 'dist'),
|
|
||||||
POT::SKILL_SHIELD => array('Shielding', 'shield'),
|
|
||||||
POT::SKILL_FISH => array('Fishing', 'fish')
|
|
||||||
);
|
|
||||||
|
|
||||||
$hasBlessingsColumn = $db->hasColumn('players', 'blessings');
|
|
||||||
$hasBlessingColumn = $db->hasColumn('players', 'blessings1');
|
|
||||||
$hasLookAddons = $db->hasColumn('players', 'lookaddons');
|
|
||||||
|
|
||||||
$skull_type = array("None", "Yellow", "Green", "White", "Red", "Black", "Orange");
|
|
||||||
?>
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ >
|
|
||||||
<script src="<?php echo BASE_URL; ?>tools/js/jquery.datetimepicker.js"></script>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$id = 0;
|
|
||||||
$search_player = '';
|
|
||||||
if (isset($_REQUEST['id']))
|
|
||||||
$id = (int)$_REQUEST['id'];
|
|
||||||
else if (isset($_REQUEST['search'])) {
|
|
||||||
$search_player = $_REQUEST['search'];
|
|
||||||
if (strlen($search_player) < 3 && !Validator::number($search_player)) {
|
|
||||||
echo_error('Player name is too short.');
|
|
||||||
} else {
|
|
||||||
$query = Player::where('name', 'like', '%' . $search_player . '%')->orderBy('name')->limit(11)->get(['id', 'name']);
|
|
||||||
if (count($query) == 0) {
|
|
||||||
echo_error('No entries found.');
|
|
||||||
} else if (count($query) == 1) {
|
|
||||||
$id = $query->first()->getKey();
|
|
||||||
} else if (count($query) > 10) {
|
|
||||||
echo_error('Specified name resulted with too many players.');
|
|
||||||
} else {
|
|
||||||
$str_construct = 'Do you mean?<ul>';
|
|
||||||
foreach ($query as $row) {
|
|
||||||
$str_construct .= '<li><a href="' . $player_base . '&id=' . $row->getKey() . '">' . $row->name . '</a></li>';
|
|
||||||
}
|
|
||||||
$str_construct .= '</ul>';
|
|
||||||
echo_error($str_construct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<div class="row">
|
|
||||||
<?php
|
|
||||||
$groups = new OTS_Groups_List();
|
|
||||||
if ($id > 0) {
|
|
||||||
$player = new OTS_Player();
|
|
||||||
$player->load($id);
|
|
||||||
|
|
||||||
if ($player->isLoaded() && isset($_POST['save'])) {// we want to save
|
|
||||||
$error = false;
|
|
||||||
|
|
||||||
if ($player->isOnline())
|
|
||||||
echo_error('This player is actually online. You can\'t edit online players.');
|
|
||||||
|
|
||||||
$name = $_POST['name'];
|
|
||||||
$_error = '';
|
|
||||||
if (!Validator::characterName($name))
|
|
||||||
echo_error(Validator::getLastError());
|
|
||||||
|
|
||||||
//if(!Validator::newCharacterName($name)
|
|
||||||
// echo_error(Validator::getLastError());
|
|
||||||
|
|
||||||
$player_db = new OTS_Player();
|
|
||||||
$player_db->find($name);
|
|
||||||
if ($player_db->isLoaded() && $player->getName() != $name)
|
|
||||||
echo_error('This name is already used. Please choose another name!');
|
|
||||||
|
|
||||||
$account_id = $_POST['account_id'];
|
|
||||||
verify_number($account_id, 'Account id', 11);
|
|
||||||
|
|
||||||
$account_db = new OTS_Account();
|
|
||||||
$account_db->load($account_id);
|
|
||||||
if (!$account_db->isLoaded())
|
|
||||||
echo_error('Account with this id doesn\'t exist.');
|
|
||||||
|
|
||||||
$group = $_POST['group'];
|
|
||||||
if ($groups->getGroup($group) == false)
|
|
||||||
echo_error('Group with this id doesn\'t exist');
|
|
||||||
|
|
||||||
$level = $_POST['level'];
|
|
||||||
verify_number($level, 'Level', 11);
|
|
||||||
|
|
||||||
$experience = $_POST['experience'];
|
|
||||||
verify_number($experience, 'Experience', 20);
|
|
||||||
|
|
||||||
$vocation = $_POST['vocation'];
|
|
||||||
verify_number($vocation, 'Vocation id', 11);
|
|
||||||
|
|
||||||
if (!isset($config['vocations'][$vocation])) {
|
|
||||||
echo_error("Vocation with this id doesn't exist.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// health
|
|
||||||
$health = $_POST['health'];
|
|
||||||
verify_number($health, 'Health', 11);
|
|
||||||
$health_max = $_POST['health_max'];
|
|
||||||
verify_number($health_max, 'Health max', 11);
|
|
||||||
|
|
||||||
// mana
|
|
||||||
$magic_level = $_POST['magic_level'];
|
|
||||||
verify_number($magic_level, 'Magic_level', 11);
|
|
||||||
$mana = $_POST['mana'];
|
|
||||||
verify_number($mana, 'Mana', 11);
|
|
||||||
$mana_max = $_POST['mana_max'];
|
|
||||||
verify_number($mana_max, 'Mana max', 11);
|
|
||||||
$mana_spent = $_POST['mana_spent'];
|
|
||||||
verify_number($mana_spent, 'Mana spent', 11);
|
|
||||||
|
|
||||||
// look
|
|
||||||
$look_body = $_POST['look_body'];
|
|
||||||
verify_number($look_body, 'Look body', 11);
|
|
||||||
$look_feet = $_POST['look_feet'];
|
|
||||||
verify_number($look_feet, 'Look feet', 11);
|
|
||||||
$look_head = $_POST['look_head'];
|
|
||||||
verify_number($look_head, 'Look head', 11);
|
|
||||||
$look_legs = $_POST['look_legs'];
|
|
||||||
verify_number($look_legs, 'Look legs', 11);
|
|
||||||
$look_type = $_POST['look_type'];
|
|
||||||
verify_number($look_type, 'Look type', 11);
|
|
||||||
if ($hasLookAddons) {
|
|
||||||
$look_addons = $_POST['look_addons'];
|
|
||||||
verify_number($look_addons, 'Look addons', 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
// pos
|
|
||||||
$pos_x = $_POST['pos_x'];
|
|
||||||
verify_number($pos_x, 'Position x', 11);
|
|
||||||
$pos_y = $_POST['pos_y'];
|
|
||||||
verify_number($pos_y, 'Position y', 11);
|
|
||||||
$pos_z = $_POST['pos_z'];
|
|
||||||
verify_number($pos_z, 'Position z', 11);
|
|
||||||
|
|
||||||
$soul = $_POST['soul'];
|
|
||||||
verify_number($soul, 'Soul', 10);
|
|
||||||
|
|
||||||
$town = $_POST['town'];
|
|
||||||
verify_number($town, 'Town', 11);
|
|
||||||
|
|
||||||
$capacity = $_POST['capacity'];
|
|
||||||
verify_number($capacity, 'Capacity', 11);
|
|
||||||
$sex = $_POST['sex'];
|
|
||||||
verify_number($sex, 'Sex', 1);
|
|
||||||
|
|
||||||
$lastlogin = strtotime($_POST['lastlogin']);
|
|
||||||
verify_number($lastlogin, 'Last login', 20);
|
|
||||||
$lastlogout = strtotime($_POST['lastlogout']);
|
|
||||||
verify_number($lastlogout, 'Last logout', 20);
|
|
||||||
|
|
||||||
$skull = $_POST['skull'];
|
|
||||||
verify_number($skull, 'Skull', 1);
|
|
||||||
$skull_time = $_POST['skull_time'];
|
|
||||||
verify_number($skull_time, 'Skull time', 11);
|
|
||||||
|
|
||||||
if ($db->hasColumn('players', 'loss_experience')) {
|
|
||||||
$loss_experience = $_POST['loss_experience'];
|
|
||||||
verify_number($loss_experience, 'Loss experience', 11);
|
|
||||||
$loss_mana = $_POST['loss_mana'];
|
|
||||||
verify_number($loss_mana, 'Loss mana', 11);
|
|
||||||
$loss_skills = $_POST['loss_skills'];
|
|
||||||
verify_number($loss_skills, 'Loss skills', 11);
|
|
||||||
$loss_containers = $_POST['loss_containers'];
|
|
||||||
verify_number($loss_containers, 'Loss loss_containers', 11);
|
|
||||||
$loss_items = $_POST['loss_items'];
|
|
||||||
verify_number($loss_items, 'Loss items', 11);
|
|
||||||
}
|
|
||||||
if ($db->hasColumn('players', 'offlinetraining_time')) {
|
|
||||||
$offlinetraining = $_POST['offlinetraining'];
|
|
||||||
verify_number($offlinetraining, 'Offline Training time', 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($hasBlessingsColumn) {
|
|
||||||
$blessings = $_POST['blessings'];
|
|
||||||
verify_number($blessings, 'Blessings', 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
$balance = $_POST['balance'];
|
|
||||||
verify_number($balance, 'Balance', 20);
|
|
||||||
if ($db->hasColumn('players', 'stamina')) {
|
|
||||||
$stamina = $_POST['stamina'];
|
|
||||||
verify_number($stamina, 'Stamina', 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
$deleted = (isset($_POST['deleted']) && $_POST['deleted'] == 'true');
|
|
||||||
$hide = (isset($_POST['hide']) && $_POST['hide'] == 'true');
|
|
||||||
|
|
||||||
$created = strtotime($_POST['created']);
|
|
||||||
verify_number($created, 'Created', 11);
|
|
||||||
|
|
||||||
$comment = isset($_POST['comment']) ? htmlspecialchars(stripslashes(substr($_POST['comment'], 0, 2000))) : NULL;
|
|
||||||
|
|
||||||
foreach ($_POST['skills'] as $skill => $value)
|
|
||||||
verify_number($value, $skills[$skill][0], 10);
|
|
||||||
foreach ($_POST['skills_tries'] as $skill => $value)
|
|
||||||
verify_number($value, $skills[$skill][0] . ' tries', 10);
|
|
||||||
|
|
||||||
if ($hasBlessingColumn) {
|
|
||||||
$bless_count = $_POST['blesscount'];
|
|
||||||
for ($i = 1; $i <= $bless_count; $i++) {
|
|
||||||
$a = 'blessing' . $i;
|
|
||||||
${'blessing' . $i} = (isset($_POST[$a]) && $_POST[$a] == 'true');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$error) {
|
|
||||||
$player->setName($name);
|
|
||||||
$player->setAccount($account_db);
|
|
||||||
$player->setGroup($groups->getGroup($group));
|
|
||||||
$player->setLevel($level);
|
|
||||||
$player->setExperience($experience);
|
|
||||||
$player->setVocation($vocation);
|
|
||||||
$player->setHealth($health);
|
|
||||||
$player->setHealthMax($health_max);
|
|
||||||
$player->setMagLevel($magic_level);
|
|
||||||
$player->setMana($mana);
|
|
||||||
$player->setManaMax($mana_max);
|
|
||||||
$player->setManaSpent($mana_spent);
|
|
||||||
$player->setLookBody($look_body);
|
|
||||||
$player->setLookFeet($look_feet);
|
|
||||||
$player->setLookHead($look_head);
|
|
||||||
$player->setLookLegs($look_legs);
|
|
||||||
$player->setLookType($look_type);
|
|
||||||
if ($hasLookAddons)
|
|
||||||
$player->setLookAddons($look_addons);
|
|
||||||
if ($db->hasColumn('players', 'offlinetraining_time'))
|
|
||||||
$player->setCustomField('offlinetraining_time', $offlinetraining);
|
|
||||||
$player->setPosX($pos_x);
|
|
||||||
$player->setPosY($pos_y);
|
|
||||||
$player->setPosZ($pos_z);
|
|
||||||
$player->setSoul($soul);
|
|
||||||
$player->setTownId($town);
|
|
||||||
$player->setCap($capacity);
|
|
||||||
$player->setSex($sex);
|
|
||||||
$player->setLastLogin($lastlogin);
|
|
||||||
$player->setLastLogout($lastlogout);
|
|
||||||
//$player->setLastIP(ip2long($lastip));
|
|
||||||
$player->setSkull($skull);
|
|
||||||
$player->setSkullTime($skull_time);
|
|
||||||
if ($db->hasColumn('players', 'loss_experience')) {
|
|
||||||
$player->setLossExperience($loss_experience);
|
|
||||||
$player->setLossMana($loss_mana);
|
|
||||||
$player->setLossSkills($loss_skills);
|
|
||||||
$player->setLossContainers($loss_containers);
|
|
||||||
$player->setLossItems($loss_items);
|
|
||||||
}
|
|
||||||
if ($hasBlessingsColumn)
|
|
||||||
$player->setBlessings($blessings);
|
|
||||||
|
|
||||||
if ($hasBlessingColumn) {
|
|
||||||
for ($i = 1; $i <= $bless_count; $i++) {
|
|
||||||
$a = 'blessing' . $i;
|
|
||||||
$player->setCustomField('blessings' . $i, ${'blessing' . $i} ? '1' : '0');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$player->setBalance($balance);
|
|
||||||
if ($db->hasColumn('players', 'stamina'))
|
|
||||||
$player->setStamina($stamina);
|
|
||||||
if ($db->hasColumn('players', 'deletion'))
|
|
||||||
$player->setCustomField('deletion', $deleted ? '1' : '0');
|
|
||||||
else
|
|
||||||
$player->setCustomField('deleted', $deleted ? '1' : '0');
|
|
||||||
$player->setCustomField('hide', $hide ? '1' : '0');
|
|
||||||
$player->setCustomField('created', $created);
|
|
||||||
if (isset($comment))
|
|
||||||
$player->setCustomField('comment', $comment);
|
|
||||||
|
|
||||||
foreach ($_POST['skills'] as $skill => $value) {
|
|
||||||
$player->setSkill($skill, $value);
|
|
||||||
}
|
|
||||||
foreach ($_POST['skills_tries'] as $skill => $value) {
|
|
||||||
$player->setSkillTries($skill, $value);
|
|
||||||
}
|
|
||||||
$player->save();
|
|
||||||
echo_success('Player saved at: ' . date('G:i'));
|
|
||||||
$player->load($id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ($id == 0) {
|
|
||||||
$players_db = Player::orderBy('id')->get(['id','name', 'level']);
|
|
||||||
?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-10">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Players</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<table class="player_datatable table table-striped table-bordered table-responsive d-md-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>ID</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Level</th>
|
|
||||||
<th style="width: 40px">Edit</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($players_db as $player_db): ?>
|
|
||||||
<tr>
|
|
||||||
<th><?php echo $player_db->id; ?></th>
|
|
||||||
<td><?php echo $player_db->name; ?></a></td>
|
|
||||||
<td><?php echo $player_db->level; ?></a></td>
|
|
||||||
|
|
||||||
<td><a href="?p=players&id=<?php echo $player_db->id; ?>" class="btn btn-success btn-sm" title="Edit">
|
|
||||||
<i class="fas fa-pencil-alt"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if (isset($player) && $player->isLoaded()) {
|
|
||||||
$account = $player->getAccount();
|
|
||||||
?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-10">
|
|
||||||
<div class="card card-primary card-outline card-outline-tabs">
|
|
||||||
<div class="card-header p-0 border-bottom-0">
|
|
||||||
<ul class="nav nav-tabs" id="tabs-tab" role="tablist">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link active" id="tabs-home-tab" data-toggle="pill" href="#tabs-home">Player</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="tabs-home-tab" data-toggle="pill" href="#tabs-stats">Stats</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="tabs-home-tab" data-toggle="pill" href="#tabs-skills">Skills</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="tabs-home-tab" data-toggle="pill" href="#tabs-pos">Pos/Look</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="tabs-home-tab" data-toggle="pill" href="#tabs-misc">Misc</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="tabs-posts-tab" data-toggle="pill" href="#tabs-posts">Posts</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="tabs-chars-tab" data-toggle="pill" href="#tabs-chars">Characters</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<form action="<?php echo $player_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post">
|
|
||||||
<?php csrf(); ?>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="tab-content" id="tabs-tabContent">
|
|
||||||
<div class="tab-pane fade active show" id="tabs-home">
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="name" class="control-label">Name</label>
|
|
||||||
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $player->getName(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="account_id">Account id:</label>
|
|
||||||
<input type="text" class="form-control" id="account_id" name="account_id" autocomplete="off" size="8" maxlength="11" value="<?php echo $account->getId(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="group">Group:</label>
|
|
||||||
<select name="group" id="group" class="form-control custom-select">
|
|
||||||
<?php foreach ($groups->getGroups() as $_id => $group): ?>
|
|
||||||
<option value="<?php echo $_id; ?>" <?php echo($player->getGroup()->getId() == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="vocation">Vocation</label>
|
|
||||||
<select name="vocation" id="vocation" class="form-control custom-select">
|
|
||||||
<?php
|
|
||||||
foreach ($config['vocations'] as $_id => $name) {
|
|
||||||
echo '<option value=' . $_id . ($_id == $player->getVocation() ? ' selected' : '') . '>' . $name . '</option>';
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="sex">Sex:</label>
|
|
||||||
<select name="sex" id="sex" class="form-control custom-select">>
|
|
||||||
<?php foreach ($config['genders'] as $_id => $sex): ?>
|
|
||||||
<option value="<?php echo $_id; ?>" <?php echo($player->getSex() == $_id ? 'selected' : ''); ?>><?php echo strtolower($sex); ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="town">Town:</label>
|
|
||||||
<select name="town" id="town" class="form-control">
|
|
||||||
<?php
|
|
||||||
$configTowns = config('towns');
|
|
||||||
if (!isset($configTowns[$player->getTownId()])) {
|
|
||||||
$configTowns[$player->getTownId()] = 'Unknown Town';
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($configTowns as $_id => $town): ?>
|
|
||||||
<option value="<?php echo $_id; ?>" <?php echo($player->getTownId() == $_id ? 'selected' : ''); ?>><?php echo $town; ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="skull">Skull:</label>
|
|
||||||
<select name="skull" id="skull" class="form-control custom-select">
|
|
||||||
<?php
|
|
||||||
|
|
||||||
foreach ($skull_type as $_id => $s_name) {
|
|
||||||
echo '<option value=' . $_id . ($_id == $player->getSkull() ? ' selected' : '') . '>' . $s_name . '</option>';
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="skull_time">Skull time:</label>
|
|
||||||
<input type="text" class="form-control" id="skull_time" name="skull_time"
|
|
||||||
autocomplete="off" maxlength="11"
|
|
||||||
value="<?php echo $player->getSkullTime(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<?php if ($hasBlessingColumn):
|
|
||||||
$bless_count = $player->countBlessings();
|
|
||||||
$bless = $player->checkBlessings($bless_count); ?>
|
|
||||||
<input type="hidden" name="blesscount" value="<?php echo $bless_count; ?>"/>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label>Blessings:</label><br/>
|
|
||||||
<?php for ($i = 1; $i <= $bless_count; $i++): ?>
|
|
||||||
<label><input class="" type="checkbox" name="blessing<?php echo $i; ?>" id="blessing<?php echo $i; ?>" value="true"<?php echo(($bless[$i - 1] == 1) ? ' checked' : '') ?>/><?php echo $i; ?></label>
|
|
||||||
<?php endfor ?>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php if ($hasBlessingsColumn): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="blessings">Blessings:</label>
|
|
||||||
<input type="text" class="form-control" id="blessings" name="blessings" autocomplete="off" maxlength="11" value="<?php echo $player->getBlessings(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="balance" class="control-label">Bank Balance:</label>
|
|
||||||
<input type="text" class="form-control" id="balance" name="balance" autocomplete="off" maxlength="20" value="<?php echo $player->getBalance(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<div class="custom-control custom-switch custom-switch-on-danger">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="deleted" id="deleted" value="true" <?php echo($player->getCustomField($db->hasColumn('players', 'deletion') ? 'deletion' : 'deleted') == '1' ? ' checked' : ''); ?>>
|
|
||||||
<label class="custom-control-label" for="deleted">Deleted</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<div class="custom-control custom-switch custom-switch-on-success">
|
|
||||||
<input type="checkbox" class="custom-control-input" name="hide" id="hide" value="true" <?php echo($player->isHidden() ? ' checked' : ''); ?>>
|
|
||||||
<label class="custom-control-label" for="hide">Hidden</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="tabs-stats">
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="level" class="control-label">Level:</label>
|
|
||||||
<input type="text" class="form-control" id="level" name="level" autocomplete="off" value="<?php echo $player->getLevel(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="experience" class="control-label">Experience:</label>
|
|
||||||
<input type="text" class="form-control" id="experience" name="experience" autocomplete="off" value="<?php echo $player->getExperience(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="magic_level" class="control-label">Magic level:</label>
|
|
||||||
<input type="text" class="form-control" id="magic_level" name="magic_level" autocomplete="off" size="8" maxlength="11" value="<?php echo $player->getMagLevel(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="mana_spent" class="control-label">Mana spent:</label>
|
|
||||||
<input type="text" class="form-control" id="mana_spent" name="mana_spent" autocomplete="off" size="3" maxlength="11" value="<?php echo $player->getManaSpent(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="health" class="control-label">Health:</label>
|
|
||||||
<input type="text" class="form-control" id="health" name="health" autocomplete="off" size="5" maxlength="11" value="<?php echo $player->getHealth(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="health_max" class="control-label">Health max:</label>
|
|
||||||
<input type="text" class="form-control" id="health_max" name="health_max" autocomplete="off" size="5" maxlength="11" value="<?php echo $player->getHealthMax(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="mana" class="control-label">Mana:</label>
|
|
||||||
<input type="text" class="form-control" id="mana" name="mana" autocomplete="off" size="3" maxlength="11" value="<?php echo $player->getMana(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="mana_max" class="control-label">Mana max:</label>
|
|
||||||
<input type="text" class="form-control" id="mana_max" name="mana_max" autocomplete="off" size="3" maxlength="11" value="<?php echo $player->getManaMax(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="capacity" class="control-label">Capacity:</label>
|
|
||||||
<input type="text" class="form-control" id="capacity" name="capacity" autocomplete="off" size="3" maxlength="11" value="<?php echo $player->getCap(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="soul" class="control-label">Soul:</label>
|
|
||||||
<input type="text" class="form-control" id="soul" name="soul" autocomplete="off" size="3" maxlength="10" value="<?php echo $player->getSoul(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php if ($db->hasColumn('players', 'stamina')): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="stamina" class="control-label">Stamina:</label>
|
|
||||||
<input type="text" class="form-control" id="stamina" name="stamina" autocomplete="off" maxlength="20" value="<?php echo $player->getStamina(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php if ($db->hasColumn('players', 'offlinetraining_time')): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="offlinetraining" class="control-label">Offline Training
|
|
||||||
Time:</label>
|
|
||||||
<input type="text" class="form-control" id="offlinetraining" name="offlinetraining" autocomplete="off" maxlength="11" value="<?php echo $player->getCustomField('offlinetraining_time'); ?>"/>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="tabs-skills">
|
|
||||||
<?php
|
|
||||||
foreach ($skills as $_id => $info) {
|
|
||||||
?>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<?php echo '<label for="skills[' . $_id . ']" class="control-label">' . $info[0] . '</label>
|
|
||||||
<input type="text" class="form-control" id="skills[' . $_id . ']" name="skills[' . $_id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkill($_id) . '"/>'; ?>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<?php echo '<label for="skills_tries[' . $_id . ']" class="control-label">' . $info[0] . ' tries</label>
|
|
||||||
<input type="text" class="form-control" id="skills_tries[' . $_id . ']" name="skills_tries[' . $_id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkillTries($_id) . '"/>'; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="tabs-pos">
|
|
||||||
<?php $outfit = setting('core.outfit_images_url') . '?id=' . $player->getLookType() . ($hasLookAddons ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); ?>
|
|
||||||
<div id="imgchar" style="width:64px;height:64px;position:absolute; top:30px; right:30px">
|
|
||||||
<img id="player_outfit" style="margin-left:0;margin-top:0;width:64px;height:64px;" src="<?php echo $outfit; ?>" alt="player outfit"/>
|
|
||||||
</div>
|
|
||||||
<td>Position:</td>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-4">
|
|
||||||
<label for="pos_x" class="control-label">X:</label>
|
|
||||||
<input type="text" class="form-control" id="pos_x" name="pos_x" autocomplete="off" maxlength="11" value="<?php echo $player->getPosX(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-4">
|
|
||||||
<label for="pos_y" class="control-label">Y:</label>
|
|
||||||
<input type="text" class="form-control" id="pos_y" name="pos_y" autocomplete="off" maxlength="11" value="<?php echo $player->getPosY(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-4">
|
|
||||||
<label for="pos_z" class="control-label">Z:</label>
|
|
||||||
<input type="text" class="form-control" id="pos_z" name="pos_z" autocomplete="off" maxlength="11" value="<?php echo $player->getPosZ(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<td>Look:</td>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-3">
|
|
||||||
<label for="look_head" class="control-label">Head: <span id="look_head_val" class="font-weight-bold text-primary"></span></label>
|
|
||||||
<input class="custom-range" type="range" min="0" max="132" id="look_head" name="look_head" value="<?php echo $player->getLookHead(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-3">
|
|
||||||
<label for="look_body" class="control-label">Body: <span id="look_body_val" class="font-weight-bold text-primary"></span></label>
|
|
||||||
<input type="range" min="0" max="132"
|
|
||||||
value="<?php echo $player->getLookBody(); ?>"
|
|
||||||
class="custom-range" id="look_body" name="look_body">
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-3">
|
|
||||||
<label for="look_legs" class="control-label">Legs: <span id="look_legs_val" class="font-weight-bold text-primary"></span></label>
|
|
||||||
<input type="range" min="0" max="132"
|
|
||||||
value="<?php echo $player->getLookLegs(); ?>"
|
|
||||||
class="custom-range" id="look_legs" name="look_legs">
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-3">
|
|
||||||
<label for="look_feet" class="control-label">Feet: <span id="look_feet_val" class="font-weight-bold text-primary"></span></label>
|
|
||||||
<input type="range" min="0" max="132"
|
|
||||||
value="<?php echo $player->getLookBody(); ?>"
|
|
||||||
class="custom-range" id="look_feet" name="look_feet">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="look_type" class="control-label">Type:</label>
|
|
||||||
<?php
|
|
||||||
$outfitlist = null;
|
|
||||||
$outfitlist = Outfits_loadfromXML();
|
|
||||||
if ($outfitlist) { ?>
|
|
||||||
<select name="look_type" id="look_type" class="form-control custom-select">
|
|
||||||
<?php
|
|
||||||
foreach ($outfitlist as $_id => $outfit) {
|
|
||||||
if ($outfit['enabled'] == 'yes') ;
|
|
||||||
echo '<option value=' . $outfit['id'] . ($outfit['id'] == $player->getLookType() ? ' selected' : '') . '>' . $outfit['name'] . ' - ' . ($outfit['type'] == 1 ? 'Male' : 'Female') . '</option>';
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
<?php } else { ?>
|
|
||||||
<input type="text" class="form-control" id="look_type" name="look_type" autocomplete="off" maxlength="11" value="<?php echo $player->getLookType(); ?>"/>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
<?php if ($hasLookAddons): ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="look_addons" class="control-label">Addons:</label>
|
|
||||||
<select name="look_addons" id="look_addons" class="form-control custom-select">
|
|
||||||
<?php
|
|
||||||
$addon_type = array("None", "First", "Second", "Both");
|
|
||||||
foreach ($addon_type as $_id => $s_name) {
|
|
||||||
echo '<option value=' . $_id . ($_id == $player->getLookAddons() ? ' selected' : '') . '>' . $s_name . '</option>';
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="tabs-misc">
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="created" class="control-label">Created:</label>
|
|
||||||
<input type="text" class="form-control" id="created" name="created"
|
|
||||||
autocomplete="off"
|
|
||||||
maxlength="10"
|
|
||||||
value="<?php echo date("M d Y, H:i:s", $player->getCustomField('created')); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="lastlogin" class="control-label">Last login:</label>
|
|
||||||
<input type="text" class="form-control" id="lastlogin" name="lastlogin" autocomplete="off" maxlength="20" value="<?php echo date("M d Y, H:i:s", $player->getLastLogin()); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="lastlogout" class="control-label">Last logout:</label>
|
|
||||||
<input type="text" class="form-control" id="lastlogout" name="lastlogout" autocomplete="off" maxlength="20" value="<?php echo date("M d Y, H:i:s", $player->getLastLogout()); ?>"/>
|
|
||||||
</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
|
|
||||||
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')): ?>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="loss_experience" class="control-label">Experience
|
|
||||||
Loss:</label>
|
|
||||||
<input type="text" class="form-control" id="loss_experience" name="loss_experience" autocomplete="off" maxlength="11" value="<?php echo $player->getLossExperience(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="loss_mana" class="control-label">Mana Loss:</label>
|
|
||||||
<input type="text" class="form-control" id="loss_mana" name="loss_mana" autocomplete="off" maxlength="11" value="<?php echo $player->getLossMana(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="loss_skills" class="control-label">Skills Loss:</label>
|
|
||||||
<input type="text" class="form-control" id="loss_skills" name="loss_skills" autocomplete="off" maxlength="11" value="<?php echo $player->getLossSkills(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="loss_containers" class="control-label">Containers Loss:</label>
|
|
||||||
<input type="text" class="form-control" id="loss_containers" name="loss_containers" autocomplete="off" maxlength="11" value="<?php echo $player->getLossContainers(); ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-6">
|
|
||||||
<label for="loss_items" class="control-label">Items Loss:</label>
|
|
||||||
<input type="text" class="form-control" id="loss_items" name="loss_items" autocomplete="off" maxlength="11" value="<?php echo $player->getLossItems(); ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12">
|
|
||||||
<label for="comment" class="control-label">Comment:</label>
|
|
||||||
<textarea class="form-control" id="comment" name="comment" rows="10" cols="50" wrap="virtual"><?php echo $player->getCustomField("comment"); ?></textarea>
|
|
||||||
<small>[max. length: 2000 chars, 50 lines (ENTERs)]</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="tabs-posts">
|
|
||||||
<table class="table table-striped table-condensed table-responsive d-md-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="w-25">Topic</th>
|
|
||||||
<th>Content</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
$posts = $db->query('SELECT `author_guid`,`section`,`first_post`,`post_text`,`post_date`, `post_topic`,`post_html`,`post_smile`,`' . TABLE_PREFIX . 'forum_boards`.`name` AS `forum_Name` FROM `' .
|
|
||||||
TABLE_PREFIX . 'forum` LEFT JOIN `' . TABLE_PREFIX . 'forum_boards` ON `' .
|
|
||||||
TABLE_PREFIX . 'forum`.section = `' . TABLE_PREFIX . 'forum_boards`.id WHERE `author_guid` = "' . $player->getId() . '" ORDER BY `post_date` DESC LIMIT 10');
|
|
||||||
if ($posts->rowCount() > 0) {
|
|
||||||
$posts = $posts->fetchAll();
|
|
||||||
foreach ($posts as $post) {
|
|
||||||
$text = ($post['post_html'] > 0 ? $post['post_text'] : htmlspecialchars($post['post_text']));
|
|
||||||
$post['content'] = ($post['post_html'] > 0 ? $text : Forum::parseBBCode(nl2br($text), $post['post_smile'] == 0));
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<th><?php echo htmlspecialchars($post['post_topic']); ?><br/><small><?php echo date('d M y H:i:s', $post['post_date']); ?></small><br/>
|
|
||||||
Topic: <a href="<?php echo getForumThreadLink($post['first_post']); ?>" class="link-black text-sm"><i class="fa fa-share margin-r-5"></i> Link</a><br/>
|
|
||||||
Forum: <a href="<?php echo getForumBoardLink($post['section']); ?>" class="link-black text-sm"><i class="fa fa-share margin-r-5"></i> <?php echo $post['forum_Name']; ?></a></th>
|
|
||||||
<th><?php echo $post['content']; ?></th>
|
|
||||||
</tr>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
unset($post);
|
|
||||||
} else {
|
|
||||||
echo '<tr><td colspan="2">This user has no posts</td></tr>';
|
|
||||||
}; ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="tabs-chars">
|
|
||||||
<div class="row">
|
|
||||||
<?php
|
|
||||||
if (isset($account) && $account->isLoaded()) {
|
|
||||||
$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get();
|
|
||||||
if (isset($account_players)) { ?>
|
|
||||||
<table class="table table-striped table-condensed table-responsive d-md-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>#</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Level</th>
|
|
||||||
<th>Vocation</th>
|
|
||||||
<th style="width: 40px">Edit</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($account_players as $i => $player): ?>
|
|
||||||
<tr>
|
|
||||||
<th><?php echo $i + 1; ?></th>
|
|
||||||
<td><?php echo $player->name; ?></td>
|
|
||||||
<td><?php echo $player->level; ?></td>
|
|
||||||
<td><?php echo $player->vocation_name; ?></td>
|
|
||||||
<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer text-center">
|
|
||||||
<input type="hidden" name="save" value="yes"/>
|
|
||||||
<button type="submit" class="btn btn-info float-left"><i class="fas fa-update"></i> Update</button>
|
|
||||||
<a href="<?php echo ADMIN_URL; ?>?p=accounts&id=<?php echo $account->getId(); ?>" class="btn btn-secondary">Edit Account</a>
|
|
||||||
<a href="<?php echo ADMIN_URL; ?>?p=players" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
$('#lastlogin').datetimepicker({format: "M d Y, H:i:s",});
|
|
||||||
$('#lastlogout').datetimepicker({format: "M d Y, H:i:s",});
|
|
||||||
$('#created').datetimepicker({format: "M d Y, H:i:s",});
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
const $headSpan = $('#look_head_val');
|
|
||||||
const $headvalue = $('#look_head');
|
|
||||||
$headSpan.html($headvalue.val());
|
|
||||||
$headvalue.on('input', () => {
|
|
||||||
$headSpan.html($headvalue.val());
|
|
||||||
});
|
|
||||||
$headvalue.on('change', () => {
|
|
||||||
updateOutfit();
|
|
||||||
});
|
|
||||||
|
|
||||||
const $bodySpan = $('#look_body_val');
|
|
||||||
const $bodyvalue = $('#look_body');
|
|
||||||
$bodySpan.html($bodyvalue.val());
|
|
||||||
$bodyvalue.on('input', () => {
|
|
||||||
$bodySpan.html($bodyvalue.val());
|
|
||||||
});
|
|
||||||
$bodyvalue.on('change', () => {
|
|
||||||
updateOutfit();
|
|
||||||
});
|
|
||||||
|
|
||||||
const $legsSpan = $('#look_legs_val');
|
|
||||||
const $legsvalue = $('#look_legs');
|
|
||||||
$legsSpan.html($legsvalue.val());
|
|
||||||
$legsvalue.on('input', () => {
|
|
||||||
$legsSpan.html($legsvalue.val());
|
|
||||||
});
|
|
||||||
$legsvalue.on('change', () => {
|
|
||||||
updateOutfit();
|
|
||||||
});
|
|
||||||
|
|
||||||
const $feetSpan = $('#look_feet_val');
|
|
||||||
const $feetvalue = $('#look_feet');
|
|
||||||
$feetSpan.html($feetvalue.val());
|
|
||||||
$feetvalue.on('input', () => {
|
|
||||||
$feetSpan.html($feetvalue.val());
|
|
||||||
});
|
|
||||||
$feetvalue.on('change', () => {
|
|
||||||
updateOutfit();
|
|
||||||
});
|
|
||||||
|
|
||||||
const $lookvalue = $('#look_type');
|
|
||||||
$lookvalue.on('change', () => {
|
|
||||||
updateOutfit();
|
|
||||||
});
|
|
||||||
|
|
||||||
<?php if($hasLookAddons): ?>
|
|
||||||
const $addonvalue = $('#look_addons');
|
|
||||||
$addonvalue.on('change', () => {
|
|
||||||
updateOutfit();
|
|
||||||
});
|
|
||||||
<?php endif; ?>
|
|
||||||
});
|
|
||||||
|
|
||||||
function updateOutfit() {
|
|
||||||
const look_head = $('#look_head').val();
|
|
||||||
const look_body = $('#look_body').val();
|
|
||||||
const look_legs = $('#look_legs').val();
|
|
||||||
const look_feet = $('#look_feet').val();
|
|
||||||
const look_type = $('#look_type').val();
|
|
||||||
|
|
||||||
let look_addons = '';
|
|
||||||
<?php if($hasLookAddons): ?>
|
|
||||||
look_addons = '&addons=' + $('#look_addons').val();
|
|
||||||
<?php endif; ?>
|
|
||||||
$("#player_outfit").attr("src", '<?= setting('core.outfit_images_url'); ?>?id=' + look_type + look_addons + '&head=' + look_head + '&body=' + look_body + '&legs=' + look_legs + '&feet=' + look_feet);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<?php } ?>
|
|
||||||
<div class="col-12 col-sm-12 col-lg-2">
|
|
||||||
<div class="card card-info card-outline">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="m-0">Search Player</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body row">
|
|
||||||
<div class="col-6 col-lg-12">
|
|
||||||
<form action="<?php echo $player_base; ?>" method="post">
|
|
||||||
<?php csrf(); ?>
|
|
||||||
<label for="search">Player Name:</label>
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_player); ?>" maxlength="32" size="32">
|
|
||||||
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 col-lg-12">
|
|
||||||
<form action="<?php echo $player_base; ?>" method="post">
|
|
||||||
<?php csrf(); ?>
|
|
||||||
<label for="id">Player ID:</label>
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32">
|
|
||||||
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(function () {
|
|
||||||
$('.player_datatable').DataTable({
|
|
||||||
"order": [[0, "asc"]]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -1,146 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Plugins
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Plugins;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Plugin manager';
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
$use_datatable = true;
|
|
||||||
|
|
||||||
if (!setting('core.admin_plugins_manage_enable')) {
|
|
||||||
warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$pluginUploadEnabled = true;
|
|
||||||
if(!\class_exists('\ZipArchive')) {
|
|
||||||
error('Please install PHP zip extension. Plugins upload disabled until then.');
|
|
||||||
$pluginUploadEnabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.plugins.form.html.twig', ['pluginUploadEnabled' => $pluginUploadEnabled]);
|
|
||||||
|
|
||||||
if (isset($_POST['uninstall'])) {
|
|
||||||
$uninstall = $_POST['uninstall'];
|
|
||||||
|
|
||||||
if (Plugins::uninstall($uninstall)) {
|
|
||||||
success('Successfully uninstalled plugin ' . $uninstall);
|
|
||||||
} else {
|
|
||||||
error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError());
|
|
||||||
}
|
|
||||||
} else if (isset($_POST['enable'])) {
|
|
||||||
$enable = $_POST['enable'];
|
|
||||||
if (Plugins::enable($enable)) {
|
|
||||||
success('Successfully enabled plugin ' . $enable);
|
|
||||||
} else {
|
|
||||||
error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError());
|
|
||||||
}
|
|
||||||
} else if (isset($_POST['disable'])) {
|
|
||||||
$disable = $_POST['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'];
|
|
||||||
|
|
||||||
$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 (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.');
|
|
||||||
}
|
|
||||||
|
|
||||||
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('Error uploading file - unknown error.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$plugins = array();
|
|
||||||
foreach (get_plugins(true) as $plugin) {
|
|
||||||
$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json');
|
|
||||||
$plugin_info = json_decode($string, true);
|
|
||||||
|
|
||||||
if (!$plugin_info) {
|
|
||||||
warning('Cannot load plugin info ' . $plugin . '.json');
|
|
||||||
} else {
|
|
||||||
$disabled = (str_contains($plugin, 'disabled.'));
|
|
||||||
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
|
|
||||||
$plugins[] = array(
|
|
||||||
'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'])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.plugins.html.twig', array(
|
|
||||||
'plugins' => $plugins
|
|
||||||
));
|
|
@ -1,61 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Reports
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Lee
|
|
||||||
* @copyright 2020 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Report Viewer';
|
|
||||||
$use_datatable = true;
|
|
||||||
|
|
||||||
$files = array();
|
|
||||||
$server_path_reports = $config['data_path'] . 'reports/';
|
|
||||||
|
|
||||||
if (file_exists($server_path_reports)) {
|
|
||||||
foreach (scandir($server_path_reports, SCANDIR_SORT_ASCENDING) as $f) {
|
|
||||||
if ($f[0] === '.') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_dir($server_path_reports . $f)) {
|
|
||||||
foreach (scandir($server_path_reports . $f, SCANDIR_SORT_ASCENDING) as $f2) {
|
|
||||||
if ($f2[0] === '.') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$files[] = array($f . '/' . $f2, $server_path_reports);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$files[] = array($f, $server_path_reports);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($files as &$f) {
|
|
||||||
$f['mtime'] = filemtime($f[1] . $f[0]);
|
|
||||||
$f['name'] = $f[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($f);
|
|
||||||
|
|
||||||
$file = isset($_GET['file']) ? $_GET['file'] : NULL;
|
|
||||||
if (!empty($file)) {
|
|
||||||
if (!preg_match('/[^A-z0-9\' _\/\-\.]/', $file)) {
|
|
||||||
if (file_exists($server_path_reports . $file)) {
|
|
||||||
$file_content = nl2br(file_get_contents($server_path_reports . $file));
|
|
||||||
|
|
||||||
$twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $file_content));
|
|
||||||
} else {
|
|
||||||
echo 'Specified file does not exist.';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo 'Invalid file name specified.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$twig->display('admin.reports.html.twig', array('files' => $files));
|
|
@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Menus
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Plugins;
|
|
||||||
use MyAAC\Settings;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Settings';
|
|
||||||
|
|
||||||
require_once SYSTEM . 'clients.conf.php';
|
|
||||||
if (empty($_GET['plugin'])) {
|
|
||||||
error('Please select plugin from left Panel.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$plugin = $_GET['plugin'];
|
|
||||||
|
|
||||||
if($plugin != 'core') {
|
|
||||||
$pluginSettings = Plugins::getPluginSettings($plugin);
|
|
||||||
if (!$pluginSettings) {
|
|
||||||
error('This plugin does not exist or does not have settings defined.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$settingsFilePath = BASE . $pluginSettings;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$settingsFilePath = SYSTEM . 'settings.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file_exists($settingsFilePath)) {
|
|
||||||
error("Plugin $plugin does not exist or does not have settings defined.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$settingsFile = require $settingsFilePath;
|
|
||||||
if (!is_array($settingsFile)) {
|
|
||||||
error("Cannot load settings file for plugin $plugin");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$settingsKeyName = ($plugin == 'core' ? $plugin : $settingsFile['key']);
|
|
||||||
|
|
||||||
$title = ($plugin == 'core' ? 'Settings' : 'Plugin Settings - ' . $settingsFile['name']);
|
|
||||||
|
|
||||||
$settingsParsed = Settings::display($settingsKeyName, $settingsFile['settings']);
|
|
||||||
|
|
||||||
$twig->display('admin.settings.html.twig', [
|
|
||||||
'settingsParsed' => $settingsParsed['content'],
|
|
||||||
'settings' => $settingsFile['settings'],
|
|
||||||
'script' => $settingsParsed['script'],
|
|
||||||
'settingsKeyName' => $settingsKeyName,
|
|
||||||
]);
|
|
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Statistics
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\Models\Account;
|
|
||||||
use MyAAC\Models\Guild;
|
|
||||||
use MyAAC\Models\House;
|
|
||||||
use MyAAC\Models\Player;
|
|
||||||
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Statistics';
|
|
||||||
|
|
||||||
$total_accounts = Account::count();
|
|
||||||
$total_players = Player::count();
|
|
||||||
$total_guilds = Guild::count();
|
|
||||||
$total_houses = House::count();
|
|
||||||
|
|
||||||
$points = Account::select(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')])
|
|
||||||
->orderByDesc('premium_points')
|
|
||||||
->limit(10)
|
|
||||||
->get()
|
|
||||||
->toArray();
|
|
||||||
|
|
||||||
$twig->display('admin.statistics.html.twig', array(
|
|
||||||
'total_accounts' => $total_accounts,
|
|
||||||
'total_players' => $total_players,
|
|
||||||
'total_guilds' => $total_guilds,
|
|
||||||
'total_houses' => $total_houses,
|
|
||||||
'account_type' => (USE_ACCOUNT_NAME ? 'name' : 'number'),
|
|
||||||
'points' => $points
|
|
||||||
));
|
|
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Tools
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
defined('MYAAC') or die('Direct access not allowed!');
|
|
||||||
$title = 'Tools';
|
|
||||||
|
|
||||||
if (!isset($_GET['tool'])) {
|
|
||||||
echo 'Tool not set.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$tool = $_GET['tool'];
|
|
||||||
if (preg_match("/[^A-z0-9_\-]/", $tool)) {
|
|
||||||
echo 'Invalid tool.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = ADMIN . 'tools/' . $tool . '.php';
|
|
||||||
|
|
||||||
if (@file_exists($file)) {
|
|
||||||
require $file;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo 'Tool <strong>' . $tool . '</strong> not found.';
|
|
||||||
|
|
||||||
?>
|
|
@ -1,66 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Visitors viewer
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2019 MyAAC
|
|
||||||
* @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;
|
|
||||||
use MyAAC\Visitors;
|
|
||||||
|
|
||||||
$title = 'Visitors';
|
|
||||||
$use_datatable = true;
|
|
||||||
|
|
||||||
if (!setting('core.visitors_counter')): ?>
|
|
||||||
Visitors counter is disabled.<br/>
|
|
||||||
You can enable it by editing this configurable in <b>config.local.php</b> file:<br/>
|
|
||||||
<p style="margin-left: 3em;"><b>$config['visitors_counter'] = true;</b></p>
|
|
||||||
<?php
|
|
||||||
return;
|
|
||||||
endif;
|
|
||||||
|
|
||||||
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
|
|
||||||
|
|
||||||
function compare($a, $b): int {
|
|
||||||
return $a['lastvisit'] > $b['lastvisit'] ? -1 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$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' => setting('core.visitors_counter_ttl'),
|
|
||||||
'visitors' => $tmp
|
|
||||||
));
|
|
||||||
?>
|
|
@ -1,69 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
$menus = [
|
|
||||||
['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'],
|
|
||||||
['name' => 'Settings', 'icon' => 'edit', 'order' => 19, 'link' =>
|
|
||||||
require ADMIN . 'includes/settings_menus.php'
|
|
||||||
],
|
|
||||||
['name' => 'News', 'icon' => 'newspaper', 'order' => 20, 'link' =>
|
|
||||||
[
|
|
||||||
['name' => 'View', 'link' => 'news', 'icon' => 'list', 'order' => 10],
|
|
||||||
['name' => 'Add news', 'link' => 'news&action=new&type=1', 'icon' => 'plus', 'order' => 20],
|
|
||||||
['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'icon' => 'plus', 'order' => 30],
|
|
||||||
['name' => 'Add article', 'link' => 'news&action=new&type=3', 'icon' => 'plus', 'order' => 40],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
['name' => 'Changelogs', 'icon' => 'newspaper', 'order' => 30, 'link' =>
|
|
||||||
[
|
|
||||||
['name' => 'View', 'link' => 'changelog', 'icon' => 'list', 'order' => 10],
|
|
||||||
['name' => 'Add', 'link' => 'changelog&action=new', 'icon' => 'plus', 'order' => 20],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !setting('core.mail_enabled')],
|
|
||||||
['name' => 'Pages', 'icon' => 'book', 'order' => 50, 'link' =>
|
|
||||||
[
|
|
||||||
['name' => 'View', 'link' => 'pages', 'icon' => 'list', 'order' => 10],
|
|
||||||
['name' => 'Add', 'link' => 'pages&action=new', 'icon' => 'plus', 'order' => 20],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
['name' => 'Menus', 'icon' => 'list', 'order' => 60, 'link' => 'menus'],
|
|
||||||
['name' => 'Plugins', 'icon' => 'plug', 'order' => 70, 'link' => 'plugins'],
|
|
||||||
['name' => 'Server Data', 'icon' => 'gavel', 'order' => 80, 'link' => 'data'],
|
|
||||||
['name' => 'Editor', 'icon' => 'edit', 'order' => 90, 'link' =>
|
|
||||||
[
|
|
||||||
['name' => 'Accounts', 'link' => 'accounts', 'icon' => 'users', 'order' => 10],
|
|
||||||
['name' => 'Players', 'link' => 'players', 'icon' => 'user-astronaut', 'order' => 20],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
['name' => 'Tools', 'icon' => 'tools', 'order' => 100, 'link' =>
|
|
||||||
[
|
|
||||||
['name' => 'Mass Account Actions', 'link' => 'mass_account', 'icon' => 'globe', 'order' => 10],
|
|
||||||
['name' => 'Mass Teleport Actions', 'link' => 'mass_teleport', 'icon' => 'globe', 'order' => 20],
|
|
||||||
['name' => 'Notepad', 'link' => 'notepad', 'icon' => 'marker', 'order' => 30],
|
|
||||||
['name' => 'phpinfo', 'link' => 'phpinfo', 'icon' => 'server', 'order' => 40],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
['name' => 'Logs', 'icon' => 'bug', 'order' => 110, 'link' =>
|
|
||||||
[
|
|
||||||
['name' => 'Logs', 'link' => 'logs', 'icon' => 'book', 'order' => 10],
|
|
||||||
['name' => 'Reports', 'link' => 'reports', 'icon' => 'book', 'order' => 20],
|
|
||||||
['name' => 'Visitors', 'link' => 'visitors', 'icon' => 'user', 'order' => 30],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$hooks->trigger(HOOK_ADMIN_MENU);
|
|
||||||
|
|
||||||
usort($menus, function ($a, $b) {
|
|
||||||
return $a['order'] - $b['order'];
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach ($menus as $i => $menu) {
|
|
||||||
if (isset($menu['link']) && is_array($menu['link'])) {
|
|
||||||
usort($menus[$i]['link'], function ($a, $b) {
|
|
||||||
return $a['order'] - $b['order'];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $menus;
|
|
@ -1,15 +1,147 @@
|
|||||||
.menu-text-li {color: #4b646f; background: #1a2226;}
|
*{
|
||||||
.menu-text {
|
margin:0;
|
||||||
display: block;
|
padding:0;
|
||||||
padding: .5rem 1rem;
|
}
|
||||||
white-space: nowrap;
|
body {
|
||||||
|
font-family: Helvetica;
|
||||||
|
color: #313334;
|
||||||
|
background: /*#f9f9f9 #EEEEEE*/#F7F6F1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-mini.sidebar-collapse .menu-text {
|
img {border: none;}
|
||||||
display: none;
|
|
||||||
|
a:link {color: #000; text-decoration: none;}
|
||||||
|
a:visited {color: #000; text-decoration: none;}
|
||||||
|
a:focus {color: #000; text-decoration: none;}
|
||||||
|
a:active {color: #000; text-decoration: underline;}
|
||||||
|
a:hover {color: #000; text-decoration: underline;}
|
||||||
|
a.current {font-weight: bold;}
|
||||||
|
|
||||||
|
h5.blue {color: #6b7b95;}
|
||||||
|
h5.red {color: #c17878;}
|
||||||
|
h5.green {color: #78ba91;}
|
||||||
|
h5.purple {color: #a87aad;}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {color: #313334; font-weight: bold;}
|
||||||
|
.separator {color:#BCE}
|
||||||
|
.margin-left{
|
||||||
|
margin-left:5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.myaac-table tbody tr:nth-child(even) {background: #FFF} /* light border */
|
.button { background:#eee repeat-x 0 0; border:solid 1px #b1a874; color:#7f7f7f; font-size:11px; padding:2px 6px 2px 6px; cursor:pointer; line-height:14px !important; }
|
||||||
.myaac-table tbody tr:nth-child(odd) {background: #CCC} /* dark border */
|
.button:hover { color:#333; border-color:#857b42; }
|
||||||
.myaac-table thead td {background: #000000; color: #ffffff !important;} /* vdark border */
|
|
||||||
.myaac-table tfoot td {background: #000000; color: #ffffff !important;} /* vdark border */
|
.field, .button { -moz-border-radius:4px; -webkit-border-radius:4px; }
|
||||||
|
.small-field, .button, .pagging a { -moz-border-radius:3px; -webkit-border-radius:3px; }
|
||||||
|
|
||||||
|
.table th {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table, .table td, .table th{
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table th a:link {color: white; text-decoration: none;}
|
||||||
|
.table th a:link {color: white; text-decoration: none;}
|
||||||
|
.table th a:visited {color: white; text-decoration: none;}
|
||||||
|
.table th a:focus {color: white; text-decoration: none;}
|
||||||
|
.table th a:active {color: white; text-decoration: underline;}
|
||||||
|
.table th a:hover {color: white; text-decoration: underline;}
|
||||||
|
|
||||||
|
.table tr:nth-child(odd) {background-color: #d1d1d1}
|
||||||
|
|
||||||
|
a.ico { color:#9d9c9a; font-size:10px; text-decoration: none; padding:0 0 0 14px; background-repeat:no-repeat; background-position:0 0; }
|
||||||
|
a.ico:hover { color:#333;}
|
||||||
|
|
||||||
|
#container{
|
||||||
|
width:960px;
|
||||||
|
margin-left:auto;
|
||||||
|
margin-right:auto;
|
||||||
|
}
|
||||||
|
#header {
|
||||||
|
/*width: 960px;*/
|
||||||
|
padding-left: auto;
|
||||||
|
padding-right: auto;
|
||||||
|
border-bottom: 1px dotted black;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
#header h1 {
|
||||||
|
margin: 0;
|
||||||
|
padding-top: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#sidebar{
|
||||||
|
background: #FFF;
|
||||||
|
width: 170px;
|
||||||
|
float: left;
|
||||||
|
margin: 10px 0 10px 0;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #CCC;
|
||||||
|
}
|
||||||
|
#content {
|
||||||
|
width: 740px;
|
||||||
|
float: right;
|
||||||
|
margin: 20px 0 10px 0;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
#footer {
|
||||||
|
margin-top: 20px;
|
||||||
|
border-top: 1px dotted black;
|
||||||
|
text-align: center;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
/*********************
|
||||||
|
Sidebar
|
||||||
|
*********************/
|
||||||
|
#sidebar ul{
|
||||||
|
list-style:none;
|
||||||
|
line-height:22px;
|
||||||
|
}
|
||||||
|
#sidebar ul li a,#sidebar ul li a:visited{
|
||||||
|
padding-left:19px;
|
||||||
|
text-decoration:none;
|
||||||
|
margin:0 3px;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
#sidebar ul li a:hover{
|
||||||
|
text-decoration:underline;
|
||||||
|
}
|
||||||
|
#sidebar ul li ul{
|
||||||
|
margin-left:10px;
|
||||||
|
}
|
||||||
|
#sidebar h3{
|
||||||
|
padding:2px;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
/*********************
|
||||||
|
Status & version boxes
|
||||||
|
*********************/
|
||||||
|
#status {
|
||||||
|
position: absolute; top: 10px; left: 10px;
|
||||||
|
margin: 0px;
|
||||||
|
float: right;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
#status .success {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
#version {
|
||||||
|
position: absolute; top: 10px; right: 10px;
|
||||||
|
float: right;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
/*********************
|
||||||
|
Infobox
|
||||||
|
*********************/
|
||||||
|
#infobox{
|
||||||
|
border:1px solid #e9e8e3;
|
||||||
|
}
|
||||||
|
#infobox h3{
|
||||||
|
background:#f7f6f1;
|
||||||
|
border-bottom:1px solid #e9e8e3;
|
||||||
|
color:#654322;
|
||||||
|
}
|
@ -1,203 +1,110 @@
|
|||||||
<?php defined('MYAAC') or die('Direct access not allowed!'); ?>
|
<?php defined('MYAAC') or die('Direct access not allowed!'); ?>
|
||||||
<!doctype html>
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<?php $hooks->trigger(HOOK_ADMIN_HEAD_START); ?>
|
|
||||||
<?php echo template_header(true); ?>
|
<?php echo template_header(true); ?>
|
||||||
<title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title>
|
<title><?php echo $title . $config['title_separator'] . $config['lua']['serverName']; ?> - Powered by MyAAC</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<link rel="stylesheet" type="text/css" href="<?php echo $template_path; ?>style.css" />
|
||||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/adminlte.min.css">
|
|
||||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/font-awesome.min.css">
|
|
||||||
<?php if (isset($use_datatable)) { ?>
|
|
||||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/datatables.bs.min.css">
|
|
||||||
<?php } ?>
|
|
||||||
<link rel="stylesheet" type="text/css" href="<?php echo $template_path; ?>style.css"/>
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="<?php echo BASE_URL; ?>tools/js/html5shiv.min.js"></script>
|
|
||||||
<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>
|
</head>
|
||||||
<body class="sidebar-mini ">
|
<body>
|
||||||
<?php $hooks->trigger(HOOK_ADMIN_BODY_START); ?>
|
<?php if($page != 'tools'): ?>
|
||||||
<?php if ($logged && admin()) { ?>
|
<div id="container">
|
||||||
<div class="wrapper">
|
<div id="header">
|
||||||
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
|
<?php if($logged && admin()): ?>
|
||||||
<ul class="navbar-nav">
|
<div id="status">
|
||||||
<li class="nav-item">
|
<?php if($status['online']): ?>
|
||||||
<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
|
<p class="success" style="width: 120px; text-align: center;">Status: Online<br/>
|
||||||
</li>
|
<?php echo $status['uptimeReadable'] . ', ' . $status['players'] . '/' . $status['playersMax']; ?><br/>
|
||||||
<li class="nav-item d-none d-sm-inline-block">
|
<?php echo $config['lua']['ip'] . ' : ' . $config['lua']['loginPort']; ?>
|
||||||
<a href="<?php echo ADMIN_URL; ?>" class="nav-link">Home</a>
|
</p>
|
||||||
</li>
|
<?php else: ?>
|
||||||
</ul>
|
<p class="error" style="width: 120px; text-align: center;">Status: Offline</p>
|
||||||
<ul class="navbar-nav ml-auto">
|
<?php endif; ?>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#"><i class="fas fa-th-large"></i></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
<aside class="main-sidebar sidebar-dark-info elevation-4">
|
|
||||||
<a href="<?php echo ADMIN_URL; ?>" class="brand-link navbar-info">
|
|
||||||
<img src="<?php echo ADMIN_URL; ?>images/logo.png" class="brand-image img-circle elevation-3" style="opacity: .8">
|
|
||||||
<span class="brand-text"><b>My</b>AAC</span>
|
|
||||||
</a>
|
|
||||||
<div class="sidebar">
|
|
||||||
<nav class="mt-1">
|
|
||||||
<ul class="nav nav-pills nav-sidebar flex-column nav-legacy nav-child-indent" data-widget="treeview" data-accordion="false">
|
|
||||||
<li class="menu-text-li">
|
|
||||||
<span class="menu-text">
|
|
||||||
<a class="text-info" href="<?php echo BASE_URL; ?>" target="_blank">
|
|
||||||
<?php echo $config['lua']['serverName'] ?>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
// name = Display name of link
|
|
||||||
// icon = fontawesome icon name without "fas fa-"
|
|
||||||
// link = Page link or use as array for sub items
|
|
||||||
$menus = require __DIR__ . '/menus.php';
|
|
||||||
|
|
||||||
foreach ($menus as $category => $menu) {
|
|
||||||
if (isset($menu['disabled']) && $menu['disabled']) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$has_child = is_array($menu['link']);
|
|
||||||
if (!$has_child) { ?>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link<?php echo(strpos($menu['link'], $page) !== false ? ' active' : '') ?>" href="?p=<?php echo $menu['link'] ?>">
|
|
||||||
<i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i>
|
|
||||||
<p><?php echo $menu['name'] ?></p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
} else if ($has_child) {
|
|
||||||
$used_menu = null;
|
|
||||||
$nav_construct = '';
|
|
||||||
foreach ($menu['link'] as $sub_category => $sub_menu) {
|
|
||||||
$nav_construct .= '<li class="nav-item"><a href="?p=' . $sub_menu['link'] . '" class="nav-link';
|
|
||||||
if ($_SERVER['QUERY_STRING'] == 'p=' . $sub_menu['link']) {
|
|
||||||
$nav_construct .= ' active';
|
|
||||||
$used_menu = true;
|
|
||||||
}
|
|
||||||
$nav_construct .= '"><i class="fas fa-' . ($sub_menu['icon'] ?? 'circle') . ' nav-icon"></i><p>' . $sub_menu['name'] . '</p></a></li>';
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<li class="nav-item has-treeview<?php echo($used_menu ? ' menu-open' : '') ?>">
|
|
||||||
<a href="#" class="nav-link<?php echo($used_menu ? ' active' : '') ?>">
|
|
||||||
<i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i>
|
|
||||||
<p><?php echo $menu['name'] ?></p><i class="right fas fa-angle-left"></i>
|
|
||||||
</a>
|
|
||||||
<ul class="nav nav-treeview">
|
|
||||||
<?php echo $nav_construct; ?>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = $db->query('SELECT `name`, `page`, `flags` FROM `' . TABLE_PREFIX . 'admin_menu` ORDER BY `ordering`');
|
|
||||||
$menu_db = $query->fetchAll();
|
|
||||||
foreach ($menu_db as $item) {
|
|
||||||
if ($item['flags'] == 0 || hasFlag($item['flags'])) { ?>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link<?php echo($page == $item['page'] ? ' active' : '') ?>" href="?p=<?php echo $item['page'] ?>">
|
|
||||||
<i class="nav-icon fas fa-link"></i>
|
|
||||||
<p><?php echo $item['name'] ?></p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
<div id="version">Version: <?php echo MYAAC_VERSION; ?> (<a id="update" href="?p=version">Check for updates</a>)<br/>
|
||||||
|
Logged in as: <b><?php echo (USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()); ?></b><br/>
|
||||||
<div class="content-wrapper" style="min-height: 823px;">
|
<a href="<?php echo BASE_URL; ?>" target="_blank">Preview</a> <span class="separator">|</span> <a href="?action=logout">Log out<img src="<?php echo BASE_URL; ?>images/icons/logout.png" alt="" title="Log out" /></a>
|
||||||
<div class="content-header">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<h3 class="m-0 text-dark"><?php echo(isset($title) ? $title : ''); ?><small> - Admin Panel</small></h3>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<div class="float-sm-right d-none d-sm-inline">
|
|
||||||
<span class="p-2 right badge badge-<?php echo((isset($status['online']) and $status['online']) ? 'success' : 'danger'); ?>"><?php echo $config['lua']['serverName'] ?></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<?php echo $content; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<h1><?php echo $config['lua']['serverName'] . (isset($title) ? ' - ' . $title : ''); ?> - Admin Panel</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="wrapper">
|
||||||
|
<?php
|
||||||
|
if($logged && admin()) {
|
||||||
|
?>
|
||||||
|
<div id="sidebar">
|
||||||
|
<ul>
|
||||||
|
<?php
|
||||||
|
$menus = array(
|
||||||
|
'Dashboard' => 'dashboard',
|
||||||
|
'Mailer' => 'mailer',
|
||||||
|
'Pages' => 'pages',
|
||||||
|
'Menus' => 'menus',
|
||||||
|
'Plugins' => 'plugins',
|
||||||
|
'Statistics' => 'statistics',
|
||||||
|
'Visitors' => 'visitors',
|
||||||
|
'Players' => 'players',
|
||||||
|
'Items' => 'items',
|
||||||
|
'Tools' => array(
|
||||||
|
'phpinfo' => 'phpinfo'
|
||||||
|
),
|
||||||
|
'Notepad' => 'notepad',
|
||||||
|
'Logs' => 'logs'
|
||||||
|
);
|
||||||
|
|
||||||
<aside class="control-sidebar control-sidebar-dark">
|
$i = 0;
|
||||||
<div class="p-3">
|
foreach($menus as $_name => $_page) {
|
||||||
<h4>Account:</h4>
|
//echo '<a ' . ($page == $_page ? ' class="current"' : '') . 'href="?p=' . $_page . '">' . $_name . '</a>';
|
||||||
<p><h5><a href="?action=logout"><i class="fas fa-sign-out-alt text-danger"></i> Log out</h5></a>
|
echo '<li><h3>';
|
||||||
<small>This will log you out</small></p>
|
$has_child = is_array($_page);
|
||||||
</div>
|
if(!$has_child) {
|
||||||
<div class="p-3">
|
echo '<a href="?p=' . $_page . '">';
|
||||||
<h4>Site:</h4>
|
if($page == $_page) echo '<u>';
|
||||||
<p><h5><a href="<?php echo BASE_URL; ?>" target="_blank"><i class="far fa-eye text-blue"></i> Preview</a></h5>
|
echo $_name;
|
||||||
<small>This will open a new tab</small></p>
|
if($page == $_page) echo '</u>';
|
||||||
</div>
|
echo '</a>';
|
||||||
<div class="p-3">
|
}
|
||||||
<h4>Version:</h4>
|
else
|
||||||
<p><h5><a href="?p=version"><i class="fas fa-code-branch"></i> <?php echo MYAAC_VERSION; ?></a></h5>
|
echo $_name;
|
||||||
<small>Check for updates</small></p>
|
|
||||||
</div>
|
|
||||||
<div class="p-3">
|
|
||||||
<h4>Site:</h4>
|
|
||||||
<p><h5><a href="https://github.com/slawkens/myaac" target="_blank"><i class="fab fa-github"></i> Github</a></h5>
|
|
||||||
<small>Goto GitHub Page</small></p>
|
|
||||||
|
|
||||||
<p><h5><a href="http://my-aac.org/" target="_blank"><i class="fas fa-shoe-prints"></i> MyAAC Official</a></h5>
|
echo '</h3>';
|
||||||
<small>Goto MyAAC Official Website</small></p>
|
if($has_child) {
|
||||||
|
echo '<ul>';
|
||||||
<p><h5><a href="?p=open_source"><i class="fas fa-wrench"></i> Open Source</a></h5>
|
foreach($_page as $__name => $__page)
|
||||||
<small>View Open Source Software MyAAC is using</small></p>
|
echo '<li><a href="?p=' . $__page . '">';
|
||||||
</div>
|
if($page == $__page) echo '<u>';
|
||||||
</aside>
|
echo $__name;
|
||||||
|
if($page == $__page) echo '</u>';
|
||||||
<footer class="main-footer">
|
echo '</a></li>';
|
||||||
<div class="float-sm-right d-none d-sm-inline">
|
echo '</ul>';
|
||||||
<span class="p-2 right badge badge-<?php echo((isset($status['online']) and $status['online']) ? 'success' : 'danger'); ?>"><?php echo $config['lua']['serverName'] ?></span>
|
}
|
||||||
|
echo '</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $db->query('SELECT `name`, `page`, `flags` FROM `' . TABLE_PREFIX . 'admin_menu` ORDER BY `ordering`');
|
||||||
|
$menu_db = $query->fetchAll();
|
||||||
|
foreach($menu_db as $item) {
|
||||||
|
if($item['flags'] == 0 || hasFlag($item['flags'])) {
|
||||||
|
echo '<li><h3>
|
||||||
|
<a href="?p=' . $item['page'] . '">';
|
||||||
|
if($page == $item['page']) echo '<u>';
|
||||||
|
echo $item['name'];
|
||||||
|
if($page == $item['page']) echo '</u>';
|
||||||
|
echo '</a></h3></li>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div id="content"><?php echo $content; ?></div>
|
||||||
|
</div>
|
||||||
|
<div id="footer">
|
||||||
<?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?>
|
<?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?>
|
||||||
</footer>
|
</div>
|
||||||
<div id="sidebar-overlay"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
<?php } else if (!$logged && !admin()) {
|
|
||||||
echo $content;
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @var OTS_Account $account_logged
|
|
||||||
*/
|
|
||||||
if ($logged && admin()) {
|
|
||||||
$twig->display('admin-bar.html.twig', [
|
|
||||||
'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<script src="<?php echo BASE_URL; ?>tools/ext/bootstrap/js/bootstrap.min.js"></script>
|
|
||||||
<script src="<?php echo BASE_URL; ?>tools/ext/jquery-ui/jquery-ui.min.js"></script>
|
|
||||||
<?php if (isset($use_datatable)) { ?>
|
|
||||||
<script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script>
|
|
||||||
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
define('MYAAC_ADMIN', true);
|
require('../../common.php');
|
||||||
|
require(SYSTEM . 'functions.php');
|
||||||
require '../../common.php';
|
require(SYSTEM . 'init.php');
|
||||||
require SYSTEM . 'functions.php';
|
require(SYSTEM . 'login.php');
|
||||||
require SYSTEM . 'init.php';
|
|
||||||
require SYSTEM . 'login.php';
|
|
||||||
|
|
||||||
if(!admin())
|
if(!admin())
|
||||||
die('Access denied.');
|
die('Access denied.');
|
||||||
@ -13,3 +11,4 @@ if(!function_exists('phpinfo'))
|
|||||||
die('phpinfo() disabled on this web server.');
|
die('phpinfo() disabled on this web server.');
|
||||||
|
|
||||||
phpinfo();
|
phpinfo();
|
||||||
|
?>
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Project: MyAAC
|
|
||||||
* Automatic Account Creator for Open Tibia Servers
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* @package MyAAC
|
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
|
||||||
* @copyright 2020 MyAAC
|
|
||||||
* @link https://my-aac.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
use MyAAC\DataLoader;
|
|
||||||
|
|
||||||
const MYAAC_ADMIN = true;
|
|
||||||
|
|
||||||
require '../../common.php';
|
|
||||||
require SYSTEM . 'functions.php';
|
|
||||||
require SYSTEM . 'init.php';
|
|
||||||
require SYSTEM . 'login.php';
|
|
||||||
|
|
||||||
if (!admin())
|
|
||||||
die('Access denied.');
|
|
||||||
|
|
||||||
ini_set('max_execution_time', 300);
|
|
||||||
ob_implicit_flush();
|
|
||||||
@ob_end_flush();
|
|
||||||
header('X-Accel-Buffering: no');
|
|
||||||
|
|
||||||
require LOCALE . 'en/main.php';
|
|
||||||
require LOCALE . 'en/install.php';
|
|
||||||
|
|
||||||
DataLoader::setLocale($locale);
|
|
||||||
DataLoader::load();
|
|
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use MyAAC\Hooks;
|
|
||||||
use MyAAC\Settings;
|
|
||||||
|
|
||||||
const MYAAC_ADMIN = true;
|
|
||||||
|
|
||||||
require '../../common.php';
|
|
||||||
require SYSTEM . 'functions.php';
|
|
||||||
require SYSTEM . 'init.php';
|
|
||||||
require SYSTEM . 'login.php';
|
|
||||||
|
|
||||||
if(!admin()) {
|
|
||||||
http_response_code(500);
|
|
||||||
die('Access denied.');
|
|
||||||
}
|
|
||||||
|
|
||||||
csrfProtect();
|
|
||||||
|
|
||||||
if (!isset($_REQUEST['plugin'])) {
|
|
||||||
http_response_code(500);
|
|
||||||
die('Please enter plugin name.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($_POST['settings'])) {
|
|
||||||
http_response_code(500);
|
|
||||||
die('Please enter settings.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$settings = Settings::getInstance();
|
|
||||||
|
|
||||||
$success = $settings->save($_REQUEST['plugin'], $_POST['settings']);
|
|
||||||
|
|
||||||
$errors = $settings->getErrors();
|
|
||||||
if (count($errors) > 0) {
|
|
||||||
http_response_code(500);
|
|
||||||
die(implode('<br/>', $errors));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($success) {
|
|
||||||
echo 'Saved at ' . date('H:i');
|
|
||||||
}
|
|
@ -1,11 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
define('MYAAC_ADMIN', true);
|
require('../../common.php');
|
||||||
|
require(SYSTEM . 'init.php');
|
||||||
require '../../common.php';
|
require(SYSTEM . 'functions.php');
|
||||||
require SYSTEM . 'init.php';
|
require(SYSTEM . 'status.php');
|
||||||
require SYSTEM . 'functions.php';
|
require(SYSTEM . 'login.php');
|
||||||
require SYSTEM . 'status.php';
|
|
||||||
require SYSTEM . 'login.php';
|
|
||||||
|
|
||||||
if(!admin())
|
if(!admin())
|
||||||
die('Access denied.');
|
die('Access denied.');
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
<?php
|
|
||||||
define('MYAAC_ADMIN', true);
|
|
||||||
|
|
||||||
require '../../common.php';
|
|
||||||
require SYSTEM . 'functions.php';
|
|
||||||
require SYSTEM . 'init.php';
|
|
||||||
require SYSTEM . 'login.php';
|
|
||||||
|
|
||||||
if(!admin())
|
|
||||||
die('Access denied.');
|
|
||||||
|
|
||||||
// Don't attempt to process the upload on an OPTIONS request
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
|
||||||
header('Access-Control-Allow-Methods: POST, OPTIONS');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$imageFolder = BASE . EDITOR_IMAGES_DIR;
|
|
||||||
|
|
||||||
reset ($_FILES);
|
|
||||||
$temp = current($_FILES);
|
|
||||||
if (is_uploaded_file($temp['tmp_name'])) {
|
|
||||||
header('Access-Control-Allow-Credentials: true');
|
|
||||||
header('P3P: CP="There is no P3P policy."');
|
|
||||||
|
|
||||||
// Sanitize input
|
|
||||||
if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
|
|
||||||
header('HTTP/1.1 400 Invalid file name.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify extension
|
|
||||||
$ext = strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION));
|
|
||||||
if (!in_array($ext, ['gif', 'jpg', 'png'])) {
|
|
||||||
header('HTTP/1.1 400 Invalid extension.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
$randomName = generateRandomString(8). ".$ext";
|
|
||||||
$fileToWrite = $imageFolder . $randomName;
|
|
||||||
} while (file_exists($fileToWrite));
|
|
||||||
|
|
||||||
move_uploaded_file($temp['tmp_name'], $fileToWrite);
|
|
||||||
|
|
||||||
$returnPathToImage = BASE_URL . EDITOR_IMAGES_DIR . $randomName;
|
|
||||||
echo json_encode(['location' => $returnPathToImage]);
|
|
||||||
} else {
|
|
||||||
// Notify editor that the upload failed
|
|
||||||
header('HTTP/1.1 500 Server Error');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
197
common.php
@ -20,164 +20,89 @@
|
|||||||
*
|
*
|
||||||
* @package MyAAC
|
* @package MyAAC
|
||||||
* @author Slawkens <slawkens@gmail.com>
|
* @author Slawkens <slawkens@gmail.com>
|
||||||
* @copyright 2024 MyAAC
|
* @copyright 2017 MyAAC
|
||||||
* @link https://my-aac.org
|
* @link http://my-aac.org
|
||||||
*/
|
*/
|
||||||
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
|
session_start();
|
||||||
|
|
||||||
const MYAAC = true;
|
define('MYAAC', true);
|
||||||
const MYAAC_VERSION = '1.4.1-dev';
|
define('MYAAC_VERSION', '0.7.5');
|
||||||
const DATABASE_VERSION = 43;
|
define('DATABASE_VERSION', 20);
|
||||||
const TABLE_PREFIX = 'myaac_';
|
define('TABLE_PREFIX', 'myaac_');
|
||||||
define('START_TIME', microtime(true));
|
define('START_TIME', microtime(true));
|
||||||
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
|
define('MYAAC_OS', (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'WINDOWS' : (strtoupper(PHP_OS) == 'DARWIN' ? 'MAC' : 'LINUX'));
|
||||||
define('IS_CLI', in_array(php_sapi_name(), ['cli', 'phpdb']));
|
|
||||||
|
|
||||||
// account flags
|
// account flags
|
||||||
const FLAG_NONE = 0;
|
define('FLAG_ADMIN', 1);
|
||||||
const FLAG_ADMIN = 1;
|
define('FLAG_SUPER_ADMIN', 2);
|
||||||
const FLAG_SUPER_ADMIN = 2;
|
define('FLAG_CONTENT_PAGES', 4);
|
||||||
const FLAG_SUPER_BOTH = 3;
|
define('FLAG_CONTENT_MAILER', 8);
|
||||||
const FLAG_CONTENT_PAGES = 4;
|
define('FLAG_CONTENT_NEWS', 16);
|
||||||
const FLAG_CONTENT_MAILER = 8;
|
define('FLAG_CONTENT_FORUM', 32);
|
||||||
const FLAG_CONTENT_NEWS = 16;
|
define('FLAG_CONTENT_COMMANDS', 64);
|
||||||
const FLAG_CONTENT_FORUM = 32;
|
define('FLAG_CONTENT_SPELLS', 128);
|
||||||
const FLAG_CONTENT_COMMANDS = 64;
|
define('FLAG_CONTENT_MONSTERS', 256);
|
||||||
const FLAG_CONTENT_SPELLS = 128;
|
define('FLAG_CONTENT_GALLERY', 512);
|
||||||
const FLAG_CONTENT_MONSTERS = 256;
|
define('FLAG_CONTENT_VIDEOS', 1024);
|
||||||
const FLAG_CONTENT_GALLERY = 512;
|
define('FLAG_CONTENT_FAQ', 2048);
|
||||||
const FLAG_CONTENT_VIDEOS = 1024;
|
define('FLAG_CONTENT_MENUS', 4096);
|
||||||
const FLAG_CONTENT_FAQ = 2048;
|
|
||||||
const FLAG_CONTENT_MENUS = 4096;
|
|
||||||
const FLAG_CONTENT_PLAYERS = 8192;
|
|
||||||
|
|
||||||
// account access types
|
|
||||||
const ACCOUNT_WEB_FLAGS = [
|
|
||||||
FLAG_NONE => 'None',
|
|
||||||
FLAG_ADMIN =>'Admin',
|
|
||||||
FLAG_SUPER_ADMIN => 'Super Admin',
|
|
||||||
FLAG_SUPER_BOTH =>'(Admin + Super Admin)',
|
|
||||||
];
|
|
||||||
|
|
||||||
// news
|
// news
|
||||||
const NEWS = 1;
|
define('NEWS', 1);
|
||||||
const TICKER = 2;
|
define('TICKER', 2);
|
||||||
const ARTICLE = 3;
|
define('ARTICLE', 3);
|
||||||
|
|
||||||
// here you can change location of admin panel
|
|
||||||
// you need also to rename folder "admin"
|
|
||||||
// this may improve security
|
|
||||||
const ADMIN_PANEL_FOLDER = 'admin';
|
|
||||||
|
|
||||||
// directories
|
// directories
|
||||||
const BASE = __DIR__ . '/';
|
define('BASE', dirname(__FILE__) . '/');
|
||||||
const ADMIN = BASE . ADMIN_PANEL_FOLDER . '/';
|
define('ADMIN', BASE . 'admin/');
|
||||||
const SYSTEM = BASE . 'system/';
|
define('SYSTEM', BASE . 'system/');
|
||||||
const CACHE = SYSTEM . 'cache/';
|
define('CACHE', SYSTEM . 'cache/');
|
||||||
const LOCALE = SYSTEM . 'locale/';
|
define('LOCALE', SYSTEM . 'locale/');
|
||||||
const LIBS = SYSTEM . 'libs/';
|
define('LIBS', SYSTEM . 'libs/');
|
||||||
const LOGS = SYSTEM . 'logs/';
|
define('LOGS', SYSTEM . 'logs/');
|
||||||
const PAGES = SYSTEM . 'pages/';
|
define('PAGES', SYSTEM . 'pages/');
|
||||||
const PLUGINS = BASE . 'plugins/';
|
define('PLUGINS', BASE . 'plugins/');
|
||||||
const TEMPLATES = BASE . 'templates/';
|
define('TEMPLATES', BASE . 'templates/');
|
||||||
const TOOLS = BASE . 'tools/';
|
define('TOOLS', BASE . 'tools/');
|
||||||
const VENDOR = BASE . 'vendor/';
|
|
||||||
|
|
||||||
// other dirs
|
|
||||||
const SESSIONS_DIR = SYSTEM . 'php_sessions';
|
|
||||||
const GUILD_IMAGES_DIR = 'images/guilds/';
|
|
||||||
const EDITOR_IMAGES_DIR = 'images/editor/';
|
|
||||||
const GALLERY_DIR = 'images/gallery/';
|
|
||||||
|
|
||||||
// menu categories
|
// menu categories
|
||||||
const MENU_CATEGORY_NEWS = 1;
|
define('MENU_CATEGORY_NEWS', 1);
|
||||||
const MENU_CATEGORY_ACCOUNT = 2;
|
define('MENU_CATEGORY_ACCOUNT', 2);
|
||||||
const MENU_CATEGORY_COMMUNITY = 3;
|
define('MENU_CATEGORY_COMMUNITY', 3);
|
||||||
const MENU_CATEGORY_FORUM = 4;
|
define('MENU_CATEGORY_FORUM', 4);
|
||||||
const MENU_CATEGORY_LIBRARY = 5;
|
define('MENU_CATEGORY_LIBRARY', 5);
|
||||||
const MENU_CATEGORY_SHOP = 6;
|
define('MENU_CATEGORY_SHOP', 6);
|
||||||
|
|
||||||
// otserv versions
|
// otserv versions
|
||||||
const OTSERV = 1;
|
define('OTSERV', 1);
|
||||||
const OTSERV_06 = 2;
|
define('OTSERV_06', 2);
|
||||||
const OTSERV_FIRST = OTSERV;
|
define('OTSERV_FIRST', OTSERV);
|
||||||
const OTSERV_LAST = OTSERV_06;
|
define('OTSERV_LAST', OTSERV_06);
|
||||||
const TFS_02 = 3;
|
define('TFS_02', 3);
|
||||||
const TFS_03 = 4;
|
define('TFS_03', 4);
|
||||||
const TFS_FIRST = TFS_02;
|
define('TFS_FIRST', TFS_02);
|
||||||
const TFS_LAST = TFS_03;
|
define('TFS_LAST', TFS_03);
|
||||||
|
|
||||||
// other definitions
|
|
||||||
const MAIL_MAIL = 0;
|
|
||||||
const MAIL_SMTP = 1;
|
|
||||||
|
|
||||||
const SMTP_SECURITY_NONE = 0;
|
|
||||||
const SMTP_SECURITY_SSL = 1;
|
|
||||||
const SMTP_SECURITY_TLS = 2;
|
|
||||||
|
|
||||||
const ACCOUNT_NUMBER_LENGTH = 8;
|
|
||||||
|
|
||||||
if (!IS_CLI) {
|
|
||||||
session_save_path(SESSIONS_DIR);
|
|
||||||
session_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
// basedir
|
// basedir
|
||||||
$basedir = '';
|
$basedir = '';
|
||||||
$tmp = explode('/', $_SERVER['SCRIPT_NAME']);
|
$tmp = explode('/', $_SERVER['SCRIPT_NAME']);
|
||||||
$size = count($tmp) - 1;
|
$size = sizeof($tmp) - 1;
|
||||||
for($i = 1; $i < $size; $i++)
|
for($i = 1; $i < $size; $i++)
|
||||||
$basedir .= '/' . $tmp[$i];
|
$basedir .= '/' . $tmp[$i];
|
||||||
|
|
||||||
$basedir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $basedir);
|
$basedir = str_replace('/admin', '', $basedir);
|
||||||
|
$basedir = str_replace('/install', '', $basedir);
|
||||||
define('BASE_DIR', $basedir);
|
define('BASE_DIR', $basedir);
|
||||||
|
|
||||||
if(!IS_CLI) {
|
if(isset($_SERVER['HTTP_HOST'])) {
|
||||||
if (isset($_SERVER['HTTP_HOST'][0])) {
|
if (isset($_SERVER['HTTPS'][0]) && $_SERVER['HTTPS'] == 'on')
|
||||||
$baseHost = $_SERVER['HTTP_HOST'];
|
define('SERVER_URL', 'https://' . $_SERVER['HTTP_HOST']);
|
||||||
} else {
|
else
|
||||||
if (isset($_SERVER['SERVER_NAME'][0])) {
|
define('SERVER_URL', 'http://' . $_SERVER['HTTP_HOST']);
|
||||||
$baseHost = $_SERVER['SERVER_NAME'];
|
|
||||||
} else {
|
|
||||||
$baseHost = $_SERVER['SERVER_ADDR'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define('SERVER_URL', 'http' . (isHttps() ? 's' : '') . '://' . $baseHost);
|
|
||||||
define('BASE_URL', SERVER_URL . BASE_DIR . '/');
|
define('BASE_URL', SERVER_URL . BASE_DIR . '/');
|
||||||
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/');
|
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/');
|
||||||
|
|
||||||
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
|
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
if (file_exists(BASE . 'config.local.php')) {
|
|
||||||
require BASE . 'config.local.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var array $config */
|
|
||||||
ini_set('log_errors', 1);
|
|
||||||
if(@$config['env'] === 'dev' || defined('MYAAC_INSTALL')) {
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
ini_set('display_startup_errors', 1);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ini_set('display_errors', 0);
|
|
||||||
ini_set('display_startup_errors', 0);
|
|
||||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
|
|
||||||
}
|
|
||||||
|
|
||||||
$autoloadFile = VENDOR . 'autoload.php';
|
|
||||||
if (!is_file($autoloadFile)) {
|
|
||||||
throw new RuntimeException('The vendor folder is missing. Please download Composer: <a href="https://getcomposer.org/download">https://getcomposer.org/download</a>, install it and execute in the main MyAAC directory this command: <b>composer install</b>. Or download MyAAC from <a href="https://github.com/slawkens/myaac/releases">GitHub releases</a>, which includes Vendor folder.');
|
|
||||||
}
|
|
||||||
|
|
||||||
require $autoloadFile;
|
|
||||||
|
|
||||||
function isHttps(): bool
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
|
|
||||||
|| (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|
|
||||||
|| (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443);
|
|
||||||
}
|
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"require": {
|
|
||||||
"php": "^8.1",
|
|
||||||
"ext-pdo": "*",
|
|
||||||
"ext-pdo_mysql": "*",
|
|
||||||
"ext-json": "*",
|
|
||||||
"ext-xml": "*",
|
|
||||||
"ext-dom": "*",
|
|
||||||
"phpmailer/phpmailer": "^6.1",
|
|
||||||
"composer/semver": "^3.2",
|
|
||||||
"twig/twig": "^3.11",
|
|
||||||
"erusev/parsedown": "^1.7",
|
|
||||||
"nikic/fast-route": "^1.3",
|
|
||||||
"matomo/device-detector": "^6.0",
|
|
||||||
"illuminate/database": "^10.18",
|
|
||||||
"peppeocchi/php-cron-scheduler": "4.*",
|
|
||||||
"symfony/console": "^6.4",
|
|
||||||
"symfony/string": "^6.4",
|
|
||||||
"symfony/var-dumper": "^6.4",
|
|
||||||
"filp/whoops": "^2.15",
|
|
||||||
"maximebf/debugbar": "1.*"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpstan/phpstan": "^1.10"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"MyAAC\\": "system/src"
|
|
||||||
},
|
|
||||||
"files": ["system/src/global.php"]
|
|
||||||
}
|
|
||||||
}
|
|
2926
composer.lock
generated
3
config.local.php
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<?php
|
||||||
|
// place for your configuration directives, so you can later easily update myaac
|
||||||
|
?>
|
249
config.php
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This is MyAAC's Main Configuration file
|
||||||
|
*
|
||||||
|
* All the default values are kept here, you should not modify it but use
|
||||||
|
* a config.local.php file instead to override the settings from here.
|
||||||
|
*
|
||||||
|
* This is a piece of PHP code so PHP syntax applies!
|
||||||
|
* For boolean values please use true/false.
|
||||||
|
*
|
||||||
|
* Minimally 'server_path' directive have to be filled, other options are optional.
|
||||||
|
*
|
||||||
|
* @package MyAAC
|
||||||
|
* @author Slawkens <slawkens@gmail.com>
|
||||||
|
* @copyright 2017 MyAAC
|
||||||
|
* @link http://my-aac.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
$config = array(
|
||||||
|
// directories & files
|
||||||
|
'server_path' => '', // path to the server directory (same directory where config file is located)
|
||||||
|
|
||||||
|
'template' => 'kathrine', // template used by website (kathrine, tibiacom)
|
||||||
|
'template_allow_change' => true, // allow users to choose their own template while browsing website?
|
||||||
|
|
||||||
|
'vocations_amount' => 4, // how much basic vocations your server got (without promotion)
|
||||||
|
|
||||||
|
// what client version are you using on this OT?
|
||||||
|
// used for the Downloads page and some templates aswell
|
||||||
|
'client' => 1098, // 954 = client 9.54
|
||||||
|
|
||||||
|
'session_prefix' => 'myaac_', // must be unique for every site on your server
|
||||||
|
'friendly_urls' => false, // mod_rewrite is required for this, it makes links looks more elegant to eye, and also are SEO friendly (example: http://my-aac.org/guilds/Testing instead of http://my-aac.org/?subtopic=guilds&name=Testing). Remember to rename .htaccess.dist to .htaccess
|
||||||
|
'gzip_output' => false, // gzip page content before sending it to the browser, uses less bandwidth but more cpu cycles
|
||||||
|
|
||||||
|
// gesior backward support (templates & pages)
|
||||||
|
// allows using gesior templates and pages with myaac
|
||||||
|
// might bring some performance when disabled
|
||||||
|
'backward_support' => true,
|
||||||
|
|
||||||
|
// head options (html)
|
||||||
|
'meta_description' => 'Tibia is a free massive multiplayer online role playing game (MMORPG).', // description of the site
|
||||||
|
'meta_keywords' => 'free online game, free multiplayer game, ots, open tibia server', // keywords list separated by commas
|
||||||
|
'title_separator' => ' - ',
|
||||||
|
|
||||||
|
// footer
|
||||||
|
'footer' => ''/*'<br/>Your Server © 2016. All rights reserved.'*/,
|
||||||
|
|
||||||
|
'debug_level' => 0, // 0 - disabled, 1 - show load time, 2 - show db query counter, 3 - both, 4 - memory usage, 5 - load time & memory usage, 6 - queries & memory usage, 7 - all
|
||||||
|
|
||||||
|
'language' => 'en', // default language (currently only 'en' available)
|
||||||
|
'language_allow_change' => false,
|
||||||
|
|
||||||
|
'visitors_counter' => true,
|
||||||
|
'visitors_counter_ttl' => 10, // how long visitor will be marked as online (in minutes)
|
||||||
|
'views_counter' => true,
|
||||||
|
|
||||||
|
// cache system. by default file cache is used
|
||||||
|
'cache_engine' => 'auto', // apc, eaccelerator, xcache, file, auto, or blank to disable.
|
||||||
|
'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache)
|
||||||
|
|
||||||
|
// database details (leave blank for auto detect from config.lua)
|
||||||
|
'database_host' => '',
|
||||||
|
'database_port' => '', // leave blank to default 3306
|
||||||
|
'database_user' => '',
|
||||||
|
'database_password' => '',
|
||||||
|
'database_name' => '',
|
||||||
|
|
||||||
|
// multiworld system (only TFS 0.3)
|
||||||
|
'multiworld' => false, // use multiworld system?
|
||||||
|
'worlds' => array( // list of worlds
|
||||||
|
//'1' => 'Your World Name',
|
||||||
|
//'2' => 'Your Second World Name'
|
||||||
|
),
|
||||||
|
|
||||||
|
// images
|
||||||
|
'outfit_images_url' => 'http://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit
|
||||||
|
'item_images_url' => 'http://item-images.ots.me/1092/', // set to images/items if you host your own items in images folder
|
||||||
|
|
||||||
|
// account
|
||||||
|
'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager)
|
||||||
|
'account_mail_verify' => false, // force users to confirm their email addresses when registering account
|
||||||
|
'account_mail_unique' => true, // email addresses cannot be duplicated? (one account = one email)
|
||||||
|
'account_premium_days' => 0, // default premium days on new account
|
||||||
|
'account_premium_points' => 0, // default premium points on new account
|
||||||
|
'account_welcome_mail' => true, // send welcome email when user registers
|
||||||
|
'account_mail_change' => 2, // how many days user need to change email to account - block hackers
|
||||||
|
'account_country' => true, // user will be able to set country of origin when registering account, this information will be viewable in others places aswell
|
||||||
|
'account_country_recognize' => true, // should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io
|
||||||
|
'account_change_character_name' => false, // can user change their character name for premium points?
|
||||||
|
'account_change_character_name_points' => 30, // cost of name change
|
||||||
|
'account_change_character_sex' => false, // can user change their character sex for premium points?
|
||||||
|
'account_change_character_sex_points' => 30, // cost of sex change
|
||||||
|
'characters_per_account' => 10, // max. number of characters per account
|
||||||
|
|
||||||
|
// mail
|
||||||
|
'mail_enabled' => false, // is aac maker configured to send e-mails?
|
||||||
|
'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:)
|
||||||
|
'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent
|
||||||
|
'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function
|
||||||
|
'plain' => ''/*'--\nMy Server,\nhttp://www.myserver.com'*/,
|
||||||
|
'html' => ''/*'<br/>My Server,\n<a href="http://www.myserver.com">myserver.com</a>'*/
|
||||||
|
),
|
||||||
|
'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function)
|
||||||
|
'smtp_host' => '', // mail host
|
||||||
|
'smtp_port' => 25, // 25 (default) / 465 (ssl, e.g. gmail)
|
||||||
|
'smtp_auth' => true, // need authorization?
|
||||||
|
'smtp_user' => 'admin@example.org',
|
||||||
|
'smtp_pass' => '',
|
||||||
|
|
||||||
|
// reCAPTCHA (prevent spam bots)
|
||||||
|
'recaptcha_enabled' => false, // enable recaptcha verification code
|
||||||
|
'recaptcha_site_key' => '', // get your own site and secret keys at https://www.google.com/recaptcha
|
||||||
|
'recaptcha_secret_key' => '',
|
||||||
|
'recaptcha_theme' => 'light', // light, dark
|
||||||
|
|
||||||
|
//
|
||||||
|
'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
|
||||||
|
'send_mail_when_change_password' => true, // send e-mail with new password when change password to account
|
||||||
|
'send_mail_when_generate_reckey' => true, // send e-mail with rec key (key is displayed on page anyway when generate)
|
||||||
|
|
||||||
|
// genders (aka sex)
|
||||||
|
'genders' => array(
|
||||||
|
0 => 'Female',
|
||||||
|
1 => 'Male'
|
||||||
|
),
|
||||||
|
|
||||||
|
// new character config
|
||||||
|
'character_samples' => array( // vocations, format: ID_of_vocation => 'Name of Character to copy'
|
||||||
|
//0 => 'Rook Sample',
|
||||||
|
1 => 'Sorcerer Sample',
|
||||||
|
2 => 'Druid Sample',
|
||||||
|
3 => 'Paladin Sample',
|
||||||
|
4 => 'Knight Sample'
|
||||||
|
),
|
||||||
|
|
||||||
|
// town list used when creating character
|
||||||
|
// won't be displayed if there is only one item (rookgaard for example)
|
||||||
|
'character_towns' => array(1),
|
||||||
|
|
||||||
|
// list of towns
|
||||||
|
'towns' => array(
|
||||||
|
0 => 'No town',
|
||||||
|
1 => 'Sample town'
|
||||||
|
),
|
||||||
|
|
||||||
|
// guilds
|
||||||
|
'guild_management' => true, // enable guild management system on the site?
|
||||||
|
'guild_need_level' => 1, // min. level to form a guild
|
||||||
|
'guild_need_premium' => true, // require premium account to form a guild?
|
||||||
|
'guild_image_size_kb' => 80, // maximum size of the guild logo image in KB (kilobytes)
|
||||||
|
'guild_description_chars_limit' => 1000, // limit of guild description
|
||||||
|
'guild_description_lines_limit' => 6, // limit of lines, if description has more lines it will be showed as long text, without 'enters'
|
||||||
|
'guild_motd_chars_limit' => 150, // limit of MOTD (message of the day) that is shown later in the game on the guild channel
|
||||||
|
|
||||||
|
'quests' => array(), // quests list (displayed in character view), name => storage
|
||||||
|
|
||||||
|
'signature_enabled' => true,
|
||||||
|
'signature_type' => 'tibian', // signature engine to use: tibian, mango, gesior
|
||||||
|
'signature_cache_time' => 5, // how long to store cached file (in minutes), default 5 minutes
|
||||||
|
'signature_browser_cache' => 60, // how long to cache by browser (in minutes), default 1 hour
|
||||||
|
|
||||||
|
// online page
|
||||||
|
'online_record' => true, // display players record?
|
||||||
|
'online_vocations' => false, // display vocation statistics?
|
||||||
|
'online_vocations_images' => false, // display vocation images?
|
||||||
|
'online_skulls' => false, // display skull images
|
||||||
|
'online_outfit' => true,
|
||||||
|
'online_afk' => false,
|
||||||
|
|
||||||
|
// support list page
|
||||||
|
'team_style' => 2, // 1/2 (1 - normal table, 2 - in boxes, grouped by group id)
|
||||||
|
'team_display_status' => true,
|
||||||
|
'team_display_lastlogin' => true,
|
||||||
|
'team_display_world' => false,
|
||||||
|
|
||||||
|
// bans page
|
||||||
|
'bans_limit' => 50,
|
||||||
|
'bans_display_all' => true, // should all bans be displayed? (sorted page by page)
|
||||||
|
|
||||||
|
// highscores page
|
||||||
|
'highscores_vocation_box' => true, // show 'Choose a vocation' box on the highscores (allowing peoples to sort highscores by vocation)?
|
||||||
|
'highscores_vocation' => true, // show player vocation under his nickname?
|
||||||
|
'highscores_frags' => false, // show 'Frags' tab (best fraggers on the server)? Only 0.3
|
||||||
|
'highscores_outfit' => true, // show player outfit?
|
||||||
|
'highscores_country_box' => false, // doesnt work yet! (not implemented)
|
||||||
|
'highscores_groups_hidden' => 4, // this group id and higher won't be shown on the highscores
|
||||||
|
'highscores_ids_hidden' => array(0), // this ids of players will be hidden on the highscores (should be ids of samples)
|
||||||
|
'highscores_length' => 100, // how many records per page on highscores
|
||||||
|
|
||||||
|
// characters page
|
||||||
|
'characters' => array( // what things to display on character view page (true/false in each option)
|
||||||
|
'level' => true,
|
||||||
|
'experience' => false,
|
||||||
|
'magic_level' => false,
|
||||||
|
'balance' => false,
|
||||||
|
'marriage_info' => true, // only 0.3
|
||||||
|
'outfit' => true,
|
||||||
|
'creation_date' => true,
|
||||||
|
'quests' => true,
|
||||||
|
'skills' => true,
|
||||||
|
'equipment' => true,
|
||||||
|
'frags' => false
|
||||||
|
),
|
||||||
|
|
||||||
|
// news page
|
||||||
|
'news_limit' => 5, // limit of news on the latest news page
|
||||||
|
'news_ticker_limit' => 5, // limit of news in tickers (mini news) (0 to disable)
|
||||||
|
'news_date_format' => 'j.n.Y', // check php manual date() function for more info about this
|
||||||
|
'news_author' => true, // show author of the news
|
||||||
|
|
||||||
|
// gifts/shop system
|
||||||
|
'gifts_system' => false,
|
||||||
|
|
||||||
|
// support/system
|
||||||
|
'bug_report' => true, // this configurable has no effect, its always enabled
|
||||||
|
|
||||||
|
// forum
|
||||||
|
'forum' => 'site', // link to the server forum, set to "site" if you want to use build in forum system, otherwise leave empty if you aren't going to use any forum
|
||||||
|
'forum_level_required' => 0, // level required to post, 0 to disable
|
||||||
|
'forum_post_interval' => 30, // in seconds
|
||||||
|
'forum_posts_per_page' => 20,
|
||||||
|
'forum_threads_per_page' => 20,
|
||||||
|
|
||||||
|
// last kills
|
||||||
|
'last_kills_limit' => 50, // max. number of deaths shown on the last kills page
|
||||||
|
|
||||||
|
// status, took automatically from config file if empty
|
||||||
|
'status_ip' => '',
|
||||||
|
'status_port' => '',
|
||||||
|
|
||||||
|
// other
|
||||||
|
'anonymous_usage_statistics' => true,
|
||||||
|
'email_lai_sec_interval' => 60, // time in seconds between e-mails to one account from lost account interface, block spam
|
||||||
|
'google_analytics_id' => '', // e.g.: UA-XXXXXXX-X
|
||||||
|
'experiencetable_columns' => 5, // how many columns to display in experience table page. * experiencetable_rows, 5 = 500 (will show up to 500 level)
|
||||||
|
'experiencetable_rows' => 100, // till how many levels in one column
|
||||||
|
'date_timezone' => 'Europe/Berlin', // more info at http://php.net/manual/en/timezones.php
|
||||||
|
|
||||||
|
'monsters' => array(),
|
||||||
|
'npc' => array()
|
||||||
|
);
|
||||||
|
|
||||||
|
// download link to client.
|
||||||
|
$config['client_download'] = 'http://tibia-clients.com/clients/download/'. $config['client'] .'/exe/windows';
|
||||||
|
$config['client_download_linux'] = 'http://tibia-clients.com/clients/download/'. $config['client'] .'/tar/linux';
|
||||||
|
|
||||||
|
?>
|
@ -1,9 +0,0 @@
|
|||||||
const { defineConfig } = require("cypress");
|
|
||||||
|
|
||||||
module.exports = defineConfig({
|
|
||||||
e2e: {
|
|
||||||
setupNodeEvents(on, config) {
|
|
||||||
// implement node event listeners here
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
@ -1,76 +0,0 @@
|
|||||||
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('[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: 60000 }).should('be.visible')
|
|
||||||
|
|
||||||
cy.wait(2000);
|
|
||||||
|
|
||||||
cy.screenshot('install-finish')
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,33 +0,0 @@
|
|||||||
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('#password_confirm').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')
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,174 +0,0 @@
|
|||||||
describe('Check Public Pages', () => {
|
|
||||||
|
|
||||||
/// news
|
|
||||||
it('Go to news page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/news',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to news archive page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/news/archive',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to changelog page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/changelog',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
/// account management
|
|
||||||
it('Go to account manage page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/manage',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to account create page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/create',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to account lost page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/lost',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to rules page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/rules',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// community
|
|
||||||
it('Go to online page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/online',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to characters list page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/characters',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to guilds page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/guilds',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to highscores page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/highscores',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to last kills page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/last-kills',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to houses page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/houses',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to bans page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/bans',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to forum page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/forum',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to team page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/team',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// library
|
|
||||||
it('Go to monsters page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/monsters',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to spells page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/spells',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to server info page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/server-info',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to commands page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/commands',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to downloads page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/downloads',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to gallery page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/gallery',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to experience table page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/exp-table',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to faq page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/faq',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,81 +0,0 @@
|
|||||||
const REQUIRED_LOGIN_MESSAGE = 'Please enter your account name and your password.';
|
|
||||||
const YOU_ARE_NOT_LOGGEDIN = 'You are not logged in.';
|
|
||||||
|
|
||||||
describe('Check Protected Pages', () => {
|
|
||||||
|
|
||||||
// character actions
|
|
||||||
it('Go to account character creation page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/character/create',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(REQUIRED_LOGIN_MESSAGE)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to account character deletion page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/character/delete',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(REQUIRED_LOGIN_MESSAGE)
|
|
||||||
})
|
|
||||||
|
|
||||||
// account actions
|
|
||||||
it('Go to account email change page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/email',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(REQUIRED_LOGIN_MESSAGE)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to account password change page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/password',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(REQUIRED_LOGIN_MESSAGE)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to account info change page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/info',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(REQUIRED_LOGIN_MESSAGE)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to account logout change page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/account/logout',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(REQUIRED_LOGIN_MESSAGE)
|
|
||||||
})
|
|
||||||
|
|
||||||
// guild actions
|
|
||||||
it('Go to guild creation page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/?subtopic=guilds&action=create',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(YOU_ARE_NOT_LOGGEDIN)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to guilds cleanup players action page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_players',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(YOU_ARE_NOT_LOGGEDIN)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Go to guilds cleanup guilds action page', () => {
|
|
||||||
cy.visit({
|
|
||||||
url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_guilds',
|
|
||||||
method: 'GET',
|
|
||||||
})
|
|
||||||
cy.contains(YOU_ARE_NOT_LOGGEDIN)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Using fixtures to represent data",
|
|
||||||
"email": "hello@cypress.io",
|
|
||||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
// ***********************************************
|
|
||||||
// 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) => { ... })
|
|
@ -1,20 +0,0 @@
|
|||||||
// ***********************************************************
|
|
||||||
// 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')
|
|
BIN
images/del.png
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 433 B |
BIN
images/druid.png
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 38 KiB |
BIN
images/edit.png
Before Width: | Height: | Size: 363 B After Width: | Height: | Size: 450 B |
BIN
images/error.ico
Before Width: | Height: | Size: 4.2 KiB |
BIN
images/error.png
Before Width: | Height: | Size: 592 B After Width: | Height: | Size: 706 B |
BIN
images/false.png
Before Width: | Height: | Size: 845 B After Width: | Height: | Size: 1004 B |
BIN
images/hist.png
Before Width: | Height: | Size: 110 B After Width: | Height: | Size: 117 B |
Before Width: | Height: | Size: 530 B |
BIN
images/info.png
Before Width: | Height: | Size: 631 B After Width: | Height: | Size: 783 B |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 3.0 KiB |
BIN
images/monsters/acolyte of the cult.gif
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
images/monsters/adept of the cult.gif
Normal file
After Width: | Height: | Size: 1.5 KiB |