Compare commits

..

No commits in common. "main" and "v0.0.1" have entirely different histories.
main ... v0.0.1

2342 changed files with 86213 additions and 61332 deletions

View File

@ -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
View File

@ -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
View File

@ -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']

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -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

29
.htaccess Normal file
View File

@ -0,0 +1,29 @@
Options -Indexes -MultiViews
RewriteEngine On
#RewriteBase /
# Page parser
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-_']+)\.png/?$ tools/signature/index.php?name=$1 [L]
RewriteRule ^images/items/([0-9]+)\.gif$ tools/item.php?id=$1
RewriteRule ^characters/([A-Za-z0-9-_+']+)$ index.php?subtopic=characters&name=$1
RewriteRule ^guilds/([A-Za-z0-9-_+']+)$ index.php?subtopic=guilds&action=show&guild=$1
RewriteRule ^forum/board/([0-9]+)$ index.php?subtopic=forum&action=show_board&id=$1
RewriteRule ^account/manage$ index.php?subtopic=accountmanagement
RewriteRule ^account/create$ index.php?subtopic=createaccount
RewriteRule ^account/lost$ index.php?subtopic=lostaccount
RewriteRule ^account/logout$ index.php?subtopic=accountmanagement&action=logout
RewriteRule ^news/archive/([0-9]+)$ index.php?subtopic=news&archive=true&id=$1
RewriteRule ^news/archive$ index.php?subtopic=news&archive=true
RewriteRule ^highscores/([A-Za-z0-9-_]+)/([A-Za-z0-9-_]+)?$ index.php?subtopic=highscores&list=$1&vocation=$2
RewriteRule ^highscores/([A-Za-z0-9-_']+)$ index.php?subtopic=highscores&list=$1
RewriteRule ^admin/$ admin/index.php
RewriteRule ^install/$ install/index.php
# temp solution >.>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-_]+)/?$ index.php?p=$1 [L]
RewriteRule ^([A-Za-z0-9-_]+)/([A-Za-z0-9-_]+)?$ index.php?p=$1&action=$2 [L]

View File

@ -1,21 +0,0 @@
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<FilesMatch "^(.*\.md|.*\.json|.*\.dist|.*\.sql|CHANGELOG|README|composer\.lock)$">
Require all denied
</FilesMatch>
<IfModule mod_rewrite.c>
RewriteEngine On
#RewriteBase /myaac/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [L]
</IfModule>

View File

@ -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

View File

@ -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>

View File

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

41
README Normal file
View File

@ -0,0 +1,41 @@
MyAAC 0.0.1 - http://www.my-aac.org
REQUIREMENTS
=====================================
- PHP 5.1.0 or later
- MySQL database
- (optional) mod_rewrite to use friendly_urls
INSTALLATION AND CONFIGURATION
=====================================
Just decompress and untar the source (which you should have done by now,
if you're reading this), into your webserver's document root.
MyAAC needs proper permissions to handle files correctly.
If you're using apache2, then your directory needs to have owner set to: www-data, you can do it by using following command:
chown -R www-data.www-data /var/www/*
(or any other path your MyAAC installation is located at..)
--------------------------
Note: Linux only
If you're under linux use these commands to set proper permissions:
chmod 660 config.local.php
chmod 660 images/guilds
chmod 660 images/houses
chmod 660 images/screenshots
--------------------------
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.
KNOWN PROBLEMS
=====================================
- none -
OTHER NOTES
=====================================
If you have a great idea or want contribute to the project - visit our website at http://www.my-aac.org
LICENSING
=====================================
This program and all associated files are released under the GNU Public
License, see LICENSE for details.

View File

@ -1,38 +1,15 @@
# [MyAAC](https://my-aac.org)
# myaac
MyAAC is a free and open-source Automatic Account Creator (AAC) written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases.
Official website: https://my-aac.org
Official website: http://my-aac.org
[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/slawkens/myaac/cypress.yml)](https://github.com/slawkens/myaac/actions)
[![License: GPL-3.0](https://img.shields.io/github/license/slawkens/myaac)](https://opensource.org/licenses/gpl-license)
[![Downloads Count](https://img.shields.io/github/downloads/slawkens/myaac/total)](https://github.com/slawkens/myaac/releases)
[![OpenTibia Discord](https://img.shields.io/discord/288399552581468162)](https://discord.gg/2J39Wus)
[![Closed Issues](https://img.shields.io/github/issues-closed-raw/slawkens/myaac)](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed)
| Version | Status | Branch | Requirements |
|:--------|:-----------------------|:--------|:---------------|
| 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
### REQUIREMENTS
- PHP 5.1.0 or later
- MySQL database
- PHP Extensions: pdo, xml, json
- (optional) apache2 mod_rewrite (to use friendly_urls)
- (optional) zip PHP Extension (to install plugins)
- (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,
if you're reading this), into your webserver's document root.
@ -47,52 +24,19 @@ The recommended version to install is 1.x, which can be found at releases page -
chmod 660 config.local.php
chmod 660 images/guilds
chmod 660 images/houses
chmod 660 images/gallery
chmod -R 760 system/cache
chmod 660 images/screenshots
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.
Cheatsheet: [Git-Flow-Cheatsheet](https://danielkummer.github.io/git-flow-cheatsheet)
### LICENSING
That means, we use:
* main branch, for current stable release
* 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.
[![JetBrains](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](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.
This program and all associated files are released under the GNU Public
License, see LICENSE for details.

View File

@ -1 +0,0 @@
theme: jekyll-theme-slate

36
aac
View File

@ -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();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -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();
});

View File

@ -1,2 +1 @@
<?php
// nothing yet here
<?php // nothing yet here ?>

View File

@ -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;

View File

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

View File

@ -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>

View File

@ -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,
));

View File

@ -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>';

View File

@ -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>';
}

View File

@ -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');

View File

@ -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 ?? ''
]);

View File

@ -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));

View File

@ -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
]);

View File

@ -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,
));
}

View File

@ -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());
}

View File

@ -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');
}
}

View File

@ -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
));

View File

@ -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
));

View File

@ -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,
));

View File

@ -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,
));

View File

@ -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,
));

View File

@ -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 } ?>

View File

@ -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,
));

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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>

View File

@ -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>

View File

@ -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'
));
?>

View File

@ -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
));

View File

@ -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]);

View File

@ -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');

View File

@ -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
]);

View File

@ -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>

View File

@ -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>

View File

@ -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
));

View File

@ -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));

View File

@ -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,
]);

View File

@ -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
));

View File

@ -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.';
?>

View File

@ -1,49 +0,0 @@
<?php
/**
* Version check
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Version check';
// fetch version
//$file = @fopen('https://my-aac.org/VERSION', 'r') or die('Error while fetching version.');
//$myaac_version = fgets($file);
$myaac_version = @file_get_contents('https://my-aac.org/VERSION');
if (!$myaac_version) {
warning('Error while fetching version info from https://my-aac.org<br/>
Please try again later.');
return;
}
// compare them
$version_compare = version_compare($myaac_version, MYAAC_VERSION);
if ($version_compare == 0) {
success('MyAAC latest version is ' . $myaac_version . '. You\'re using the latest version.
<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=clmd', 'here'));
} else if ($version_compare < 0) {
success('Woah, seems you\'re using newer version as latest released one! MyAAC latest released version is ' . $myaac_version . ', and you\'re using version ' . MYAAC_VERSION . '.
<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=clmd', 'here'));
} else {
warning('You\'re using outdated version.<br/>
Your version: <b>' . MYAAC_VERSION . '</b><br/>
Latest version: <b>' . $myaac_version . '</b><br/>
Download available at: <a href="https://my-aac.org" target="_blank">www.my-aac.org</a>');
}
/*
function version_revert($version)
{
$major = floor($version / 10000);
$version -= $major * 10000;
$minor = floor($version / 100);
$version -= $minor * 100;
$release = $version;
return $major . '.' . $minor . '.' . $release;
}*/

View File

@ -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
));
?>

View File

@ -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;

View File

@ -1,15 +0,0 @@
.menu-text-li {color: #4b646f; background: #1a2226;}
.menu-text {
display: block;
padding: .5rem 1rem;
white-space: nowrap;
}
.sidebar-mini.sidebar-collapse .menu-text {
display: none;
}
.myaac-table tbody tr:nth-child(even) {background: #FFF} /* light border */
.myaac-table tbody tr:nth-child(odd) {background: #CCC} /* dark border */
.myaac-table thead td {background: #000000; color: #ffffff !important;} /* vdark border */
.myaac-table tfoot td {background: #000000; color: #ffffff !important;} /* vdark border */

View File

@ -1,203 +0,0 @@
<?php defined('MYAAC') or die('Direct access not allowed!'); ?>
<!doctype html>
<html lang="en">
<head>
<?php $hooks->trigger(HOOK_ADMIN_HEAD_START); ?>
<?php echo template_header(true); ?>
<title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<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>
<body class="sidebar-mini ">
<?php $hooks->trigger(HOOK_ADMIN_BODY_START); ?>
<?php if ($logged && admin()) { ?>
<div class="wrapper">
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="<?php echo ADMIN_URL; ?>" class="nav-link">Home</a>
</li>
</ul>
<ul class="navbar-nav ml-auto">
<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>
</aside>
<div class="content-wrapper" style="min-height: 823px;">
<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>
<aside class="control-sidebar control-sidebar-dark">
<div class="p-3">
<h4>Account:</h4>
<p><h5><a href="?action=logout"><i class="fas fa-sign-out-alt text-danger"></i> Log out</h5></a>
<small>This will log you out</small></p>
</div>
<div class="p-3">
<h4>Site:</h4>
<p><h5><a href="<?php echo BASE_URL; ?>" target="_blank"><i class="far fa-eye text-blue"></i> Preview</a></h5>
<small>This will open a new tab</small></p>
</div>
<div class="p-3">
<h4>Version:</h4>
<p><h5><a href="?p=version"><i class="fas fa-code-branch"></i> <?php echo MYAAC_VERSION; ?></a></h5>
<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>
<small>Goto MyAAC Official Website</small></p>
<p><h5><a href="?p=open_source"><i class="fas fa-wrench"></i> Open Source</a></h5>
<small>View Open Source Software MyAAC is using</small></p>
</div>
</aside>
<footer class="main-footer">
<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>
<?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?>
</footer>
<div id="sidebar-overlay"></div>
</div>
<?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>
</html>

View File

@ -0,0 +1,136 @@
*{
margin:0;
padding:0;
}
body {
font-family: Helvetica;
color: #313334;
background: /*#f9f9f9 #EEEEEE*/#F7F6F1;
}
img {border: 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;
}
.button { background:#eee url(images/button.gif) repeat-x 0 0; border:solid 1px #b1a874; color:#7f7f7f; font-size:11px; padding:2px 6px 2px 6px; cursor:pointer; line-height:14px !important; }
.button:hover { color:#333; border-color:#857b42; }
.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 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;
}

View File

@ -0,0 +1,95 @@
<?php defined('MYAAC') or die('Direct access not allowed!'); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<?php echo template_header(true); ?>
<title><?php echo $title . $config['title_separator'] . $config['lua']['serverName']; ?> - Powered by MyAAC</title>
<link rel="stylesheet" type="text/css" href="<?php echo $template_path; ?>style.css" />
</head>
<body>
<?php if($page != 'tools'): ?>
<div id="container">
<div id="header">
<?php if($logged && admin()): ?>
<div id="status">
<?php if($status['online']): ?>
<p class="success" style="width: 120px; text-align: center;">Status: Online<br/>
<?php echo $status['uptimeReadable'] . ', ' . $status['players'] . '/' . $status['playersMax']; ?><br/>
<?php echo $config['lua']['ip'] . ' : ' . $config['lua']['loginPort']; ?>
</p>
<?php else: ?>
<p class="error" style="width: 120px; text-align: center;">Status: Offline</p>
<?php endif; ?>
</div>
<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 $account_logged->getName(); ?></b><br/>
<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>
<?php endif; ?>
<h1><?php echo $config['lua']['serverName'] . ' - ' . $title; ?> - Admin Panel</h1>
</div>
<div id="wrapper">
<?php
if($logged && admin()) {
?>
<div id="sidebar">
<ul>
<?php
$menus = array(
'Dashboard' => 'dashboard',
'Mailer' => 'mailer',
'Pages' => 'pages',
'Plugins' => 'plugins',
'Statistics' => 'statistics',
'Visitors' => 'visitors',
'Players' => 'players',
'Tools' => array(
'phpinfo' => 'phpinfo'
),
'Notepad' => 'notepad',
'Logs' => 'logs'
);
$i = 0;
foreach($menus as $_name => $_page) {
//echo '<a ' . ($page == $_page ? ' class="current"' : '') . 'href="?p=' . $_page . '">' . $_name . '</a>';
echo '<li><h3>';
$has_child = is_array($_page);
if(!$has_child) {
echo '<a href="?p=' . $_page . '">';
if($page == $_page) echo '<u>';
echo $_name;
if($page == $_page) echo '</u>';
echo '</a>';
}
else
echo $_name;
echo '</h3>';
if($has_child) {
echo '<ul>';
foreach($_page as $__name => $__page)
echo '<li><a href="?p=' . $__page . '">';
if($page == $__page) echo '<u>';
echo $__name;
if($page == $__page) echo '</u>';
echo '</a></li>';
echo '</ul>';
}
echo '</li>';
}
?>
</ul>
</div>
<?php
}
?>
<div id="content"><?php echo $content; ?></div>
</div>
<div id="footer">
Powered by <a href="http://my-aac.org" target="_blank">MyAAC</a>
</div>
</div>
<?php endif; ?>
</body>
</html>

View File

@ -0,0 +1,281 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dashboard - Admin Template</title>
<link rel="stylesheet" type="text/css" href="css/theme2.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script>
var StyleFile = "theme" + document.cookie.charAt(6) + ".css";
document.writeln('<link rel="stylesheet" type="text/css" href="css/' + StyleFile + '">');
</script>
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="css/ie-sucks.css" />
<![endif]-->
</head>
<body>
<div id="container">
<div id="header">
<h2>My eCommerce Admin area</h2>
<div id="topmenu">
<ul>
<li class="current"><a href="index.html">Dashboard</a></li>
<li><a href="#">Orders</a></li>
<li><a href="users.html">Users</a></li>
<li><a href="#">Manage</a></li>
<li><a href="#">CMS</a></li>
<li><a href="#">Statistics</a></li>
<li><a href="#">Settings</a></li>
</ul>
</div>
</div>
<div id="top-panel">
<div id="panel">
<ul>
<li><a href="#" class="report">Sales Report</a></li>
<li><a href="#" class="report_seo">SEO Report</a></li>
<li><a href="#" class="search">Search</a></li>
<li><a href="#" class="feed">RSS Feed</a></li>
</ul>
</div>
</div>
<div id="wrapper">
<div id="content">
<div id="rightnow">
<h3 class="reallynow">
<span>Right Now</span>
<a href="#" class="add">Add New Product</a>
<a href="#" class="app_add">Some Action</a>
<br />
</h3>
<p class="youhave">You have <a href="#">19 new orders</a>, <a href="#">12 new users</a> and <a href="#">5 new reviews</a>, today you made <a href="#">$1523.63 in sales</a> and a total of <strong>$328.24 profit </strong>
</p>
</div>
<div id="infowrap">
<div id="infobox">
<h3>Sales for July</h3>
<p><img src="img/graph.jpg" width="360" height="266" /></p>
</div>
<div id="infobox" class="margin-left">
<h3>Traffic for July</h3>
<p><img src="img/graph2.jpg" alt="a" width="359" height="266" /></p>
</div>
<div id="infobox">
<h3>Last 5 Orders</h3>
<table>
<thead>
<tr>
<th>Customer</th>
<th>Items</th>
<th>Grand Total</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#">Jennifer Kyrnin</a></td>
<td>1</td>
<td>14.95 €</td>
</tr>
<tr>
<td><a href="#">Mark Kyrnin</a></td>
<td>2</td>
<td>34.27 €</td>
</tr>
<tr>
<td><a href="#">Virgílio Cezar</a></td>
<td>2</td>
<td>61.39 €</td>
</tr>
<tr>
<td><a href="#">Todd Simonides</a></td>
<td>5</td>
<td>1472.56 €</td>
</tr>
<tr>
<td><a href="#">Carol Elihu</a></td>
<td>1</td>
<td>9.95 €</td>
</tr>
</tbody>
</table>
</div>
<div id="infobox" class="margin-left">
<h3>Bestsellers</h3>
<table>
<thead>
<tr>
<th>Product Name</th>
<th>Price</th>
<th>Orders</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#">Apple iPhone 3G 8GB</a></td>
<td>199.00 €</td>
<td>24</td>
</tr>
<tr>
<td><a href="#">Fuji FinePix S5800</a></td>
<td>365.24 €</td>
<td>19</td>
</tr>
<tr>
<td><a href="#">Canon PIXMA MP140</a></td>
<td>59.50 €</td>
<td>12</td>
</tr>
<tr>
<td><a href="#">Apple iPhone 3G 16GB</a></td>
<td>199.00 €</td>
<td>10</td>
</tr>
<tr>
<td><a href="#">Prenosnik HP 530 1,6GHz</a></td>
<td>499.00 €</td>
<td>6</td>
</tr>
</tbody>
</table>
</div>
<div id="infobox">
<h3>New Customers</h3>
<table>
<thead>
<tr>
<th>Customer</th>
<th>Orders</th>
<th>Average</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#">Jennifer Kyrnin</a></td>
<td>1</td>
<td>5.6€</td>
<td>14.95 €</td>
</tr>
<tr>
<td><a href="#">Mark Kyrnin</a></td>
<td>2</td>
<td>14.97€</td>
<td>34.27 €</td>
</tr>
<tr>
<td><a href="#">Virgílio Cezar</a></td>
<td>2</td>
<td>15.31€</td>
<td>61.39 €</td>
</tr>
<tr>
<td><a href="#">Todd Simonides</a></td>
<td>5</td>
<td>502.61€</td>
<td>1472.56 €</td>
</tr>
<tr>
<td><a href="#">Carol Elihu</a></td>
<td>1</td>
<td>5.1€</td>
<td>9.95 €</td>
</tr>
</tbody>
</table>
</div>
<div id="infobox" class="margin-left">
<h3>Last 5 Reviews</h3>
<table>
<thead>
<tr>
<th>Reviewer</th>
<th>Product</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#">Jennifer Kyrnin</a></td>
<td><a href="#">Apple iPhone 3G 8GB</a></td>
<td><a href="#"><img src="img/icons/page_white_link.png" /></a><a href="#"><img src="img/icons/page_white_edit.png" /></a><a href="#"><img src="img/icons/page_white_delete.png" /></a></td>
</tr>
<tr>
<td><a href="#">Mark Kyrnin</a></td>
<td><a href="#">Prenosnik HP 530 1,6GHz</a></td>
<td><a href="#"><img src="img/icons/page_white_link.png" /></a><a href="#"><img src="img/icons/page_white_edit.png" /></a><a href="#"><img src="img/icons/page_white_delete.png" /></a></td>
</tr>
<tr>
<td><a href="#">Virgílio Cezar</a></td>
<td><a href="#">Fuji FinePix S5800</a></td>
<td><a href="#"><img src="img/icons/page_white_link.png" /></a><a href="#"><img src="img/icons/page_white_edit.png" /></a><a href="#"><img src="img/icons/page_white_delete.png" /></a></td>
</tr>
<tr>
<td><a href="#">Todd Simonides</a></td>
<td><a href="#">Canon PIXMA MP140</a></td>
<td><a href="#"><img src="img/icons/page_white_link.png" /></a><a href="#"><img src="img/icons/page_white_edit.png" /></a><a href="#"><img src="img/icons/page_white_delete.png" /></a></td>
</tr>
<tr>
<td><a href="#">Carol Elihu</a></td>
<td><a href="#">Prenosnik HP 530 1,6GHz</a></td>
<td><a href="#"><img src="img/icons/page_white_link.png" /></a><a href="#"><img src="img/icons/page_white_edit.png" /></a><a href="#"><img src="img/icons/page_white_delete.png" /></a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="sidebar">
<ul>
<li><h3><a href="#" class="house">Dashboard</a></h3>
<ul>
<li><a href="#" class="report">Sales Report</a></li>
<li><a href="#" class="report_seo">SEO Report</a></li>
<li><a href="#" class="search">Search</a></li>
</ul>
</li>
<li><h3><a href="#" class="folder_table">Orders</a></h3>
<ul>
<li><a href="#" class="addorder">New order</a></li>
<li><a href="#" class="shipping">Shipments</a></li>
<li><a href="#" class="invoices">Invoices</a></li>
</ul>
</li>
<li><h3><a href="#" class="manage">Manage</a></h3>
<ul>
<li><a href="#" class="manage_page">Pages</a></li>
<li><a href="#" class="cart">Products</a></li>
<li><a href="#" class="folder">Product categories</a></li>
<li><a href="#" class="promotions">Promotions</a></li>
</ul>
</li>
<li><h3><a href="#" class="user">Users</a></h3>
<ul>
<li><a href="#" class="useradd">Add user</a></li>
<li><a href="#" class="group">User groups</a></li>
<li><a href="#" class="search">Find user</a></li>
<li><a href="#" class="online">Users online</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="footer">
<div id="credits">
Template by <a href="http://www.bloganje.com">Bloganje</a>
</div>
<div id="styleswitcher">
<ul>
<li><a href="javascript: document.cookie='theme='; window.location.reload();" title="Default" id="defswitch">d</a></li>
<li><a href="javascript: document.cookie='theme=1'; window.location.reload();" title="Blue" id="blueswitch">b</a></li>
<li><a href="javascript: document.cookie='theme=2'; window.location.reload();" title="Green" id="greenswitch">g</a></li>
<li><a href="javascript: document.cookie='theme=3'; window.location.reload();" title="Brown" id="brownswitch">b</a></li>
<li><a href="javascript: document.cookie='theme=4'; window.location.reload();" title="Mix" id="mixswitch">m</a></li>
<li><a href="javascript: document.cookie='theme=5'; window.location.reload();" title="Mix" id="defswitch">m</a></li>
</ul>
</div><br />
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,100 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dashboard - Admin Template</title>
<link rel="stylesheet" type="text/css" href="css/theme.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script>
var StyleFile = "theme" + document.cookie.charAt(6) + ".css";
document.writeln('<link rel="stylesheet" type="text/css" href="css/' + StyleFile + '">');
</script>
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="css/ie-sucks.css" />
<![endif]-->
</head>
<body>
<div id="container">
<div id="header">
<h2>My eCommerce Admin area</h2>
<div id="topmenu">
<ul>
<li class="current"><a href="index.html">Dashboard</a></li>
<li><a href="#">Orders</a></li>
<li><a href="users.html">Users</a></li>
<li><a href="#">Manage</a></li>
<li><a href="#">CMS</a></li>
<li><a href="#">Statistics</a></li>
<li><a href="#">Settings</a></li>
</ul>
</div>
</div>
<div id="top-panel">
<div id="panel">
<ul>
<li><a href="#" class="report">Sales Report</a></li>
<li><a href="#" class="report_seo">SEO Report</a></li>
<li><a href="#" class="search">Search</a></li>
<li><a href="#" class="feed">RSS Feed</a></li>
</ul>
</div>
</div>
<div id="wrapper">
<div id="content">
<p>&nbsp;</p>
<p>&nbsp;</p>
</div>
<div id="sidebar">
<ul>
<li><h3><a href="#" class="house">Dashboard</a></h3>
<ul>
<li><a href="#" class="report">Sales Report</a></li>
<li><a href="#" class="report_seo">SEO Report</a></li>
<li><a href="#" class="search">Search</a></li>
</ul>
</li>
<li><h3><a href="#" class="folder_table">Orders</a></h3>
<ul>
<li><a href="#" class="addorder">New order</a></li>
<li><a href="#" class="shipping">Shipments</a></li>
<li><a href="#" class="invoices">Invoices</a></li>
</ul>
</li>
<li><h3><a href="#" class="manage">Manage</a></h3>
<ul>
<li><a href="#" class="manage_page">Pages</a></li>
<li><a href="#" class="cart">Products</a></li>
<li><a href="#" class="folder">Product categories</a></li>
<li><a href="#" class="promotions">Promotions</a></li>
</ul>
</li>
<li><h3><a href="#" class="user">Users</a></h3>
<ul>
<li><a href="#" class="useradd">Add user</a></li>
<li><a href="#" class="group">User groups</a></li>
<li><a href="#" class="search">Find user</a></li>
<li><a href="#" class="online">Users online</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="footer">
<div id="credits">
Template by <a href="http://www.bloganje.com">Bloganje</a>
</div>
<div id="styleswitcher">
<ul>
<li><a href="javascript: document.cookie='theme='; window.location.reload();" title="Default" id="defswitch">d</a></li>
<li><a href="javascript: document.cookie='theme=1'; window.location.reload();" title="Blue" id="blueswitch">b</a></li>
<li><a href="javascript: document.cookie='theme=2'; window.location.reload();" title="Green" id="greenswitch">g</a></li>
<li><a href="javascript: document.cookie='theme=3'; window.location.reload();" title="Brown" id="brownswitch">b</a></li>
<li><a href="javascript: document.cookie='theme=4'; window.location.reload();" title="Mix" id="mixswitch">m</a></li>
</ul>
</div><br />
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,121 @@
body{
background:#f7f6f0 url(../img/bg.jpg) repeat-x top;
color: #202020;
}
a, a:visited{
color:#993300;
}
input{
border:1px solid #e8e7e1;
}
select{
border:1px solid #e8e7e1;
}
#header h2{
color:#FFF;
}
#content{
background:#FFF;
}
#sidebar{
background:#FFF;
}
#sidebar h3{
background:#f7f6f0;
border-bottom:1px solid #e8e7e1;
}
#topmenu a,#topmenu a:visited{
color:#f7f6f0;
background:#cc3300;
}
#topmenu a:hover{
color: #FFF;
}
#topmenu .current a, #topmenu .current a:hover, #topmenu .current a:visited{
color:#993400;
background: #FFF url(../img/bg_menu_red.jpg) repeat-x top;
border-left: #FFF 1px solid;
border-right: #FFF 1px solid;
}
#top-panel{
background:#FFF;
}
table{
background:none;
}
td, th{
border:1px solid #e8e7e1;
}
thead{
background:#f7f6f0;
}
#styleswitcher{
background:#FFFFFF;
}
#footer{
background:#FFF;
}
#box{
border:1px solid #e8e7e1;
}
#box h3{
background:#f7f6f0;
border-bottom:1px solid #e8e7e1;
color:#993300;
}
/***************
Forms
***************/
form#form fieldset {
border:1px solid #e8e7e1;
}
form#form legend {
border:1px solid #e8e7e1;
background:#fff url(../img/form_red.gif) repeat-x center left;
color:#993300;
}
form#form input {
border:1px solid #e8e7e1;
background:#fff url(../img/form_red.gif) repeat-x top left;
}
form#form textarea {
border:1px solid #e8e7e1;
background:#fff url(../img/form_red.gif) repeat-x bottom left;
}
form#form option {
background:#FFF;
}
form#form optgroup {
background:#e8e7e1;
}
form#form optgroup option {
}
form#form #button1, form#form #button2 {
color:#c00;
}
form#form #button1:hover, form#form #button2:hover {
color:#000;
}
/***************
Home
***************/
#infobox{
border:1px solid #e8e7e1;
}
#infobox h3{
background:#f7f6f0;
border-bottom:1px solid #e8e7e1;
color:#993300;
}
#rightnow {
border:1px solid #e8e7e1;
}
#rightnow .reallynow {
background:#f7f6f0;
color:#993300;
}
#rightnow h3{
background:#f7f6f0;
border-bottom:1px solid #e8e7e1;
}

View File

@ -0,0 +1,21 @@
#content{
width:740px;
}
#topmenu{
margin-top:26px;
}
#sidebar{
width:160px;
}
#sidebar ul{
width:150px;
}
#sidebar ul li ul{
width:140px;
}
#sidebar h3{
margin-bottom:5px;
}
#rightnow .reallynow a {
padding:0 0 0 10px;
}

View File

@ -0,0 +1,68 @@
<public:component>
<public:attach event="onpropertychange" onevent="doFix()" />
<script type="text/javascript">
// IE5.5+ PNG Alpha Fix v1.0RC4
// (c) 2004-2005 Angus Turnbull http://www.twinhelix.com
// This is licensed under the CC-GNU LGPL, version 2.1 or later.
// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
// This must be a path to a blank image. That's all the configuration you need.
if (typeof blankImg == 'undefined') var blankImg = 'blank.gif';
var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
function filt(s, m)
{
if (filters[f])
{
filters[f].enabled = s ? true : false;
if (s) with (filters[f]) { src = s; sizingMethod = m }
}
else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
}
function doFix()
{
// Assume IE7 is OK.
if (!/MSIE (5\.5|6\.)/.test(navigator.userAgent) ||
(event && !/(background|src)/.test(event.propertyName))) return;
var bgImg = currentStyle.backgroundImage || style.backgroundImage;
if (tagName == 'IMG')
{
if ((/\.png$/i).test(src))
{
if (currentStyle.width == 'auto' && currentStyle.height == 'auto')
style.width = offsetWidth + 'px';
filt(src, 'scale');
src = blankImg;
}
else if (src.indexOf(blankImg) < 0) filt();
}
else if (bgImg && bgImg != 'none')
{
if (bgImg.match(/^url[("']+(.*\.png)[)"']+$/i))
{
var s = RegExp.$1;
if (currentStyle.width == 'auto' && currentStyle.height == 'auto')
style.width = offsetWidth + 'px';
style.backgroundImage = 'none';
filt(s, 'crop');
// IE link fix.
for (var n = 0; n < childNodes.length; n++)
if (childNodes[n].style) childNodes[n].style.position = 'relative';
}
else filt();
}
}
doFix();
</script>
</public:component>

View File

@ -0,0 +1,397 @@
/*********************
HTML Elements
*********************/
*{
margin:0;
padding:0;
}
img, div,a { behavior: url(css/iepngfix.htc) }
body{
font-size: 12px;
font-family: Arial, Tahoma, Verdana;
}
a, a:visited{
text-decoration:none;
}
img{
border:0;
margin:1px;
}
p{
padding:3px;
}
h2{
}
input{
padding:2px;
}
select{
padding:2px;
}
/*********************
Status
*********************/
#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;
}
/*********************
Structure
*********************/
#container{
width:960px;
margin-left:auto;
margin-right:auto;
}
#header{
width:960px;
}
#header h2{
margin-top:20px;
}
#content{
width:740px;
float:left;
margin:10px 0 10px 0;
padding:10px;
}
#sidebar{
background:#FFF;
width:170px;
float:right;
margin:10px 0 10px 0;
padding:10px;
}
#footer{
clear:both;
padding:5px;
margin-top:10px;
}
#box h3{
padding:5px;
font-size:14px;
}
/*********************
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;
}
/*********************
TopMenu, Top-Panel
*********************/
#topmenu{
margin-top:33px;
width:700px;
float:left;
voice-family:inherit;
}
#topmenu ul{
list-style:none;
line-height:25px;
}
#topmenu li{
display:inline;
}
#topmenu a,#topmenu a:visited{
padding:5px 12px 5px 12px;
text-decoration:none;
}
#topmenu .current a, #topmenu .current a:hover, #topmenu .current a:visited{
padding:5px 12px 5px 12px;
font-weight:bold;
}
#top-panel{
background:#FFF;
padding:5px;
height:20px;
float:left;
width:950px;
}
#top-panel ul{
list-style:none;
}
#top-panel ul li{
display:inline;
line-height:20px;
}
#top-panel ul li a{
padding-left:19px;
text-decoration:none;
margin:0 3px;
display:inline-block;
}
#top-panel a:hover{
text-decoration:underline;
}
/*********************
Other
*********************/
.a-right{text-align:right;}
.a-left{text-align:left;}
.a-center{text-align:center;}
#pager{
margin:5px;
height:25px;
}
#styleswitcher{
float:right;
}
#styleswitcher ul{
list-style:none;
line-height:10px;
}
#styleswitcher li{
height:12px;
display:inline;
}
#footer ul {
list-style:none;
}
#footer li {
display:inline;
}
a#defswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#bd3f09;
font-size: 8px;
color:#bd3f09;
display:inline-block;
}
a#blueswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#375b91;
font-size: 8px;
color:#375b91;
display:inline-block;
}
a#greenswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#d0e0b8;
font-size: 8px;
color:#d0e0b8;
display:inline-block;
}
a#brownswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#654322;
font-size: 8px;
color:#654322;
display:inline-block;
}
a#mixswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#294145;
font-size: 8px;
color:#294145;
display:inline-block;
}
#credits{
clear:both;
width:250px;
float:left;
}
/*********************
Tables
*********************/
table{
margin:5px;
border-collapse: collapse;
table-layout:automatic;
width:98%;
}
td, th{
padding: 2px;
}
thead{
}
/*********************
Home
*********************/
#infowrap li{
display:inline:
}
#infobox{
width:365px;
float:left;
margin-top:10px;
}
#infobox h3{
padding:5px;
font-size:14px;
}
.margin-left{
margin-left:5px;
}
#rightnow .reallynow {
padding: 5px;
font-size:14px;
}
#rightnow h3{
padding:2px;
padding: 0 10px;
font-size:14px;
}
#rightnow .reallynow span {
display: block;
text-align: left;
float: left;
padding:0 2px;
font-size:14px
}
#rightnow .reallynow a {
text-decoration:none;
display: block;
text-align: right;
float: right;
padding:0 0 0 18px;
margin-left:4px;
font-weight:normal;
font-size:12px;
}
#rightnow .reallynow a:hover{
text-decoration:underline;
}
#rightnow .youhave {
font-size: 12px;
padding: 10px;
}
#rightnow a {
font-weight: bold;
}
/*********************
Forms
*********************/
form{
padding:10px;
margin:0 auto;
}
form#form fieldset {
display:block;
padding:5px 10px 5px 10px;
line-height:20px;
margin-bottom:10px;
}
form#form legend {
font-size:12px;
font-weight:bold;
margin-bottom:5px;
padding:3px;
width:254px;
}
form#form label {
clear:left;
display:block;
float:left;
width:100px;
text-align:right;
padding-right:10px;
margin-bottom:5px;
}
form#form input {
padding:3px;
margin-bottom:5px;
}
form#form select {
margin-left:5px;
}
form#form textarea {
width:410px;
height:200px;
padding:5px;
overflow:auto;
}
form#form option {
background:#FFF;
}
form#form optgroup option {
}
form#form #button1, form#form #button2 {
padding-right:5px;
cursor:pointer;
width:205px;
margin-left:8px;
font-weight:bold;
}
form#form #button1:hover, form#form #button2:hover {
background-position:center left;
}
/*********************
Icons
*********************/
.icon{
padding-left:19px;
text-decoration:none;
height:20px;
font-size:12x;
margin:0 3px;
display:inline-block;
line-height:20px;
}
.user{background:transparent url(../img/icons/user.png) no-repeat left;}
.useradd{background:transparent url(../img/icons/user_add.png) no-repeat left;}
.group{background:transparent url(../img/icons/group.png) no-repeat left;}
.search{background:transparent url(../img/icons/magnifier.png) no-repeat left;}
.online{background:transparent url(../img/icons/world.png) no-repeat left;}
.pagenew{background:transparent url(../img/icons/page_add.png) no-repeat left;}
.rss{background:transparent url(../img/icons/rss.png) no-repeat left;}
.feed{background:transparent url(../img/icons/feed.png) no-repeat left;}
.report{background:transparent url(../img/icons/report.png) no-repeat left;}
.house{background:transparent url(../img/icons/house.png) no-repeat left;}
.manage{background:transparent url(../img/icons/cog.png) no-repeat left;}
.manage_page{background:transparent url(../img/icons/page_gear.png) no-repeat left;}
.folder{background:transparent url(../img/icons/folder.png) no-repeat left;}
.promotions{background:transparent url(../img/icons/coins.png) no-repeat left;}
.cart{background:transparent url(../img/icons/cart.png) no-repeat left;}
.folder_table{background:transparent url(../img/icons/folder_page.png) no-repeat left;}
.shipping{background:transparent url(../img/icons/car.png) no-repeat left;}
.invoices{background:transparent url(../img/icons/page_white_text_width.png) no-repeat left;}
.addorder{background:transparent url(../img/icons/folder_page_add.png) no-repeat left;}
.add{background:transparent url(../img/icons/add.png) no-repeat left;}
.app_add{background:transparent url(../img/icons/application_add.png) no-repeat left;}
.report_seo{background:transparent url(../img/icons/report_link.png) no-repeat left;}
.modules{background:transparent url(../img/icons/bricks.png) no-repeat left;}
.modules_manage{background:transparent url(../img/icons/bricks_gear.png) no-repeat left;}

View File

@ -0,0 +1,51 @@
#footer ul {
list-style:none;
}
#footer li {
display:inline;
}
a#defswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#bd3f09;
font-size: 8px;
color:#bd3f09;
display:inline-block;
}
a#blueswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#375b91;
font-size: 8px;
color:#375b91;
display:inline-block;
}
a#greenswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#d0e0b8;
font-size: 8px;
color:#d0e0b8;
display:inline-block;
}
a#brownswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#654322;
font-size: 8px;
color:#654322;
display:inline-block;
}
a#mixswitch {
width:15px;
height:10px;
margin: 3px 0 3px 0;
background-color:#294145;
font-size: 8px;
color:#294145;
display:inline-block;
}

View File

@ -0,0 +1,121 @@
body{
background:#f7f6f0 url(../img/bg.jpg) repeat-x top;
color: #202020;
}
a, a:visited{
color:#a43708;
}
input{
border:1px solid #e8e7e1;
}
select{
border:1px solid #e8e7e1;
}
#header h2{
color:#FFF;
}
#content{
background:#FFF;
}
#sidebar{
background:#FFF;
}
#sidebar h3{
background:#f7f6f0;
border-bottom:1px solid #e8e7e1;
}
#topmenu a,#topmenu a:visited{
color:#f7f6f0;
background:#bd3f09;
}
#topmenu a:hover{
color: #FFF;
}
#topmenu .current a, #topmenu .current a:hover, #topmenu .current a:visited{
color:#993400;
background: #FFF url(../img/bg_menu_red.jpg) repeat-x top;
border-left: #FFF 1px solid;
border-right: #FFF 1px solid;
}
#top-panel{
background:#FFF;
}
table{
background:none;
}
td, th{
border:1px solid #e8e7e1;
}
thead{
background:#f7f6f0;
}
#styleswitcher{
background:#FFFFFF;
}
#footer{
background:#FFF;
}
#box{
border:1px solid #e8e7e1;
}
#box h3{
background:#f7f6f0;
border-bottom:1px solid #e8e7e1;
color:#a43708;
}
/***************
Forms
***************/
form#form fieldset {
border:1px solid #e8e7e1;
}
form#form legend {
border:1px solid #e8e7e1;
background:#fff url(../img/form_red.gif) repeat-x center left;
color:#a43708;
}
form#form input {
border:1px solid #e8e7e1;
background:#fff url(../img/form_red.gif) repeat-x top left;
}
form#form textarea {
border:1px solid #e8e7e1;
background:#fff url(../img/form_red.gif) repeat-x bottom left;
}
form#form option {
background:#FFF;
}
form#form optgroup {
background:#e8e7e1;
}
form#form optgroup option {
}
form#form #button1, form#form #button2 {
color:#c00;
}
form#form #button1:hover, form#form #button2:hover {
color:#000;
}
/***************
Home
***************/
#infobox{
border:1px solid #e8e7e1;
}
#infobox h3{
background:#f7f6f0;
border-bottom:1px solid #e8e7e1;
color:#a43708;
}
#rightnow {
border:1px solid #e8e7e1;
}
#rightnow .reallynow {
background:#f7f6f0;
color:#a43708;
}
#rightnow h3{
background:#f7f6f0;
border-bottom:1px solid #e8e7e1;
}

View File

@ -0,0 +1,121 @@
body{
background:#f3f9ff url(../img/bg_blue.jpg) repeat-x top;
color: #202020;
}
a, a:visited{
color:#375b91;
}
input{
border:1px solid #d9e6f0;
}
select{
border:1px solid #d9e6f0;
}
#header h2{
color:#FFF;
}
#content{
background:#FFF;
}
#sidebar{
background:#FFF;
}
#sidebar h3{
background:#f3f9ff;
border-bottom:1px solid #d9e6f0;
}
#topmenu a,#topmenu a:visited{
color:#FFF;
background:#7e9dcc;
}
#topmenu a:hover{
color: #FFF;
}
#topmenu .current a, #topmenu .current a:hover, #topmenu .current a:visited{
color:#375b91;
background: #FFF url(../img/bg_menu_blue.jpg) repeat-x top;
border-left: #FFF 1px solid;
border-right: #FFF 1px solid;
}
#top-panel{
background:#FFF;
}
table{
background:none;
}
td, th{
border:1px solid #d9e6f0;
}
thead{
background:#f3f9ff;
}
#styleswitcher{
background:#FFFFFF;
}
#footer{
background:#FFF;
}
#box{
border:1px solid #d9e6f0;
}
#box h3{
background:#f3f9ff;
border-bottom:1px solid #d9e6f0;
color:#375b91;
}
/***************
Forms
***************/
form#form fieldset {
border:1px solid #d9e6f0;
}
form#form legend {
border:1px solid #d9e6f0;
background:#fff url(../img/form_blue.gif) repeat-x center left;
color:#375b91;
}
form#form input {
border:1px solid #d9e6f0;
background:#fff url(../img/form_blue.gif) repeat-x top left;
}
form#form textarea {
border:1px solid #d9e6f0;
background:#fff url(../img/form_blue.gif) repeat-x bottom left;
}
form#form option {
background:#FFF;
}
form#form optgroup {
background:#d9e6f0;
}
form#form optgroup option {
}
form#form #button1, form#form #button2 {
color:#375b91;
}
form#form #button1:hover, form#form #button2:hover {
color:#000;
}
/***************
Home
***************/
#infobox{
border:1px solid #d9e6f0;
}
#infobox h3{
background:#f3f9ff;
border-bottom:1px solid #d9e6f0;
color:#375b91;
}
#rightnow {
border:1px solid #d9e6f0;
}
#rightnow .reallynow {
background:#f3f9ff;
color:#375b91;
}
#rightnow h3{
background:#f3f9ff;
border-bottom:1px solid #d9e6f0;
}

View File

@ -0,0 +1,121 @@
body{
background:#f0f7e8 url(../img/bg_light_green.jpg) repeat-x top;
color: #202020;
}
a, a:visited{
color:#93ad7e;
}
input{
border:1px solid #e7eedf;
}
select{
border:1px solid #e7eedf;
}
#header h2{
color:#FFF;
}
#content{
background:#FFF;
}
#sidebar{
background:#FFF;
}
#sidebar h3{
background:#f0f7e8;
border-bottom:1px solid #e7eedf;
}
#topmenu a,#topmenu a:visited{
color:#93ad7e;
background:#e7eedc;
}
#topmenu a:hover{
color: #93ad7e;
}
#topmenu .current a, #topmenu .current a:hover, #topmenu .current a:visited{
color:#93ad7e;
background: #FFF url(../img/bg_menu_green.jpg) repeat-x top;
border-left: #FFF 1px solid;
border-right: #FFF 1px solid;
}
#top-panel{
background:#FFF;
}
table{
background:none;
}
td, th{
border:1px solid #e7eedf;
}
thead{
background:#f0f7e8;
}
#styleswitcher{
background:#FFFFFF;
}
#footer{
background:#FFF;
}
#box{
border:1px solid #e7eedf;
}
#box h3{
background:#f0f7e8;
border-bottom:1px solid #e7eedf;
color:#93ad7e;
}
/***************
Forms
***************/
form#form fieldset {
border:1px solid #e7eedf;
}
form#form legend {
border:1px solid #e7eedf;
background:#fff url(../img/form_green.gif) repeat-x center left;
color:#93ad7e;
}
form#form input {
border:1px solid #e7eedf;
background:#fff url(../img/form_green.gif) repeat-x top left;
}
form#form textarea {
border:1px solid #e7eedf;
background:#fff url(../img/form_green.gif) repeat-x bottom left;
}
form#form option {
background:#FFF;
}
form#form optgroup {
background:#e7eedf;
}
form#form optgroup option {
}
form#form #button1, form#form #button2 {
color:#93ad7e;
}
form#form #button1:hover, form#form #button2:hover {
color:#000;
}
/***************
Home
***************/
#infobox{
border:1px solid #e7eedf;
}
#infobox h3{
background:#f0f7e8;
border-bottom:1px solid #e7eedf;
color:#93ad7e;
}
#rightnow {
border:1px solid #e7eedf;
}
#rightnow .reallynow {
background:#f0f7e8;
color:#93ad7e;
}
#rightnow h3{
background:#f0f7e8;
border-bottom:1px solid #e7eedf;
}

View File

@ -0,0 +1,121 @@
body{
background:#f7f6f1 url(../img/bg_brown.jpg) repeat-x top;
color: #202020;
}
a, a:visited{
color:#654322;
}
input{
border:1px solid #e9e8e3;
}
select{
border:1px solid #e9e8e3;
}
#header h2{
color:#FFF;
}
#content{
background:#FFF;
}
#sidebar{
background:#FFF;
}
#sidebar h3{
background:#f7f6f1;
border-bottom:1px solid #e9e8e3;
}
#topmenu a,#topmenu a:visited{
color:#FFF;
background:#8f6831;
}
#topmenu a:hover{
color: #654322;
}
#topmenu .current a, #topmenu .current a:hover, #topmenu .current a:visited{
color:#654322;
background: #FFF url(../img/bg_menu_brown.jpg) repeat-x top;
border-left: #FFF 1px solid;
border-right: #FFF 1px solid;
}
#top-panel{
background:#FFF;
}
table{
background:none;
}
td, th{
border:1px solid #e9e8e3;
}
thead{
background:#f7f6f1;
}
#styleswitcher{
background:#FFFFFF;
}
#footer{
background:#FFF;
}
#box{
border:1px solid #e9e8e3;
}
#box h3{
background:#f7f6f1;
border-bottom:1px solid #e9e8e3;
color:#654322;
}
/***************
Forms
***************/
form#form fieldset {
border:1px solid #e9e8e3;
}
form#form legend {
border:1px solid #e9e8e3;
background:#fff url(../img/form_brown.gif) repeat-x center left;
color:#654322;
}
form#form input {
border:1px solid #e9e8e3;
background:#fff url(../img/form_brown.gif) repeat-x top left;
}
form#form textarea {
border:1px solid #e9e8e3;
background:#fff url(../img/form_brown.gif) repeat-x bottom left;
}
form#form option {
background:#FFF;
}
form#form optgroup {
background:#e9e8e3;
}
form#form optgroup option {
}
form#form #button1, form#form #button2 {
color:#654322;
}
form#form #button1:hover, form#form #button2:hover {
color:#000;
}
/***************
Home
***************/
#infobox{
border:1px solid #e9e8e3;
}
#infobox h3{
background:#f7f6f1;
border-bottom:1px solid #e9e8e3;
color:#654322;
}
#rightnow {
border:1px solid #e9e8e3;
}
#rightnow .reallynow {
background:#f7f6f1;
color:#654322;
}
#rightnow h3{
background:#f7f6f1;
border-bottom:1px solid #e9e8e3;
}

View File

@ -0,0 +1,122 @@
body{
background:#d9eaed url(../img/bg_mix.jpg) repeat-x top;
color: #202020;
}
a, a:visited{
color:#294145;
text-decoration:underline;
}
input{
border:1px solid #c3d7db;
}
select{
border:1px solid #c3d7db;
}
#header h2{
color:#FFF;
}
#content{
background:#FFF;
}
#sidebar{
background:#FFF;
}
#sidebar h3{
background:#d9eaed;
border-bottom:1px solid #c3d7db;
}
#topmenu a,#topmenu a:visited{
color:#FFF;
background:#5d99a3;
}
#topmenu a:hover{
color: #294145;
}
#topmenu .current a, #topmenu .current a:hover, #topmenu .current a:visited{
color:#294145;
background: #FFF url(../img/bg_menu_mix.jpg) repeat-x top;
border-left: #FFF 1px solid;
border-right: #FFF 1px solid;
}
#top-panel{
background:#FFF;
}
table{
background:none;
}
td, th{
border:1px solid #c3d7db;
}
thead{
background:#d9eaed;
}
#styleswitcher{
background:#FFFFFF;
}
#footer{
background:#FFF;
}
#box{
border:1px solid #c3d7db;
}
#box h3{
background:#d9eaed;
border-bottom:1px solid #c3d7db;
color:#294145;
}
/***************
Forms
***************/
form#form fieldset {
border:1px solid #c3d7db;
}
form#form legend {
border:1px solid #c3d7db;
background:#fff url(../img/form_mix.gif) repeat-x center left;
color:#294145;
}
form#form input {
border:1px solid #c3d7db;
background:#fff url(../img/form_mix.gif) repeat-x top left;
}
form#form textarea {
border:1px solid #c3d7db;
background:#fff url(../img/form_mix.gif) repeat-x bottom left;
}
form#form option {
background:#FFF;
}
form#form optgroup {
background:#c3d7db;
}
form#form optgroup option {
}
form#form #button1, form#form #button2 {
color:#294145;
}
form#form #button1:hover, form#form #button2:hover {
color:#000;
}
/***************
Home
***************/
#infobox{
border:1px solid #c3d7db;
}
#infobox h3{
background:#d9eaed;
border-bottom:1px solid #c3d7db;
color:#294145;
}
#rightnow {
border:1px solid #c3d7db;
}
#rightnow .reallynow {
background:#d9eaed;
color:#294145;
}
#rightnow h3{
background:#d9eaed;
border-bottom:1px solid #c3d7db;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

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