mirror of
https://github.com/slawkens/myaac.git
synced 2025-09-14 12:33:35 +02:00
Compare commits
318 Commits
feature/ne
...
feature/se
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0342293847 | ||
![]() |
c802d427eb | ||
![]() |
aacc120360 | ||
![]() |
757ec28028 | ||
![]() |
41fa695d8b | ||
![]() |
b12c30982d | ||
![]() |
fcb2fc3002 | ||
![]() |
cb6e777c69 | ||
![]() |
eca896954c | ||
![]() |
18bb23d969 | ||
![]() |
6890d531e5 | ||
![]() |
3317dc48e8 | ||
![]() |
8faa954a65 | ||
![]() |
bb0e621308 | ||
![]() |
53221a9fd1 | ||
![]() |
0f9b217567 | ||
![]() |
03ab4a5eef | ||
![]() |
c6ce60c5d1 | ||
![]() |
d3b15a0a3e | ||
![]() |
23047aa608 | ||
![]() |
20dd49b1c5 | ||
![]() |
3236f1aebb | ||
![]() |
beff3e3aa6 | ||
![]() |
4a629b4418 | ||
![]() |
4d61b0ef85 | ||
![]() |
b433615e68 | ||
![]() |
a2fcb21b4f | ||
![]() |
b05780529a | ||
![]() |
da19a34335 | ||
![]() |
ea21e27cdc | ||
![]() |
aad175548a | ||
![]() |
d82e3a21e5 | ||
![]() |
191137282b | ||
![]() |
d7e6545156 | ||
![]() |
957421a98c | ||
![]() |
f35aba10ed | ||
![]() |
3c3ddc4578 | ||
![]() |
81adeef01d | ||
![]() |
b92b642078 | ||
![]() |
baf9c9ea61 | ||
![]() |
0788dc8848 | ||
![]() |
5791d1e7f9 | ||
![]() |
a9cb017def | ||
![]() |
8490b3b2a8 | ||
![]() |
f93e478326 | ||
![]() |
d1a2ce25b2 | ||
![]() |
94f8e3602c | ||
![]() |
eaa9d6be43 | ||
![]() |
7588904372 | ||
![]() |
712ca30293 | ||
![]() |
5fa4890b70 | ||
![]() |
ca56b4f101 | ||
![]() |
159f59242f | ||
![]() |
0765d3b9db | ||
![]() |
a82672c015 | ||
![]() |
707aea18db | ||
![]() |
848c5c0887 | ||
![]() |
571602e79c | ||
![]() |
160ed3b237 | ||
![]() |
1543dd864e | ||
![]() |
399f263b42 | ||
![]() |
1b2fd39ea7 | ||
![]() |
ed7daf9482 | ||
![]() |
978090c8ae | ||
![]() |
ac3a6c36d5 | ||
![]() |
a8a2c72381 | ||
![]() |
55a5ccdd1e | ||
![]() |
a7b8ccaee2 | ||
![]() |
e14df529c0 | ||
![]() |
9f67cab503 | ||
![]() |
99c53c75f2 | ||
![]() |
df7c82c571 | ||
![]() |
ddb093ec48 | ||
![]() |
afa1adb90b | ||
![]() |
e83880653a | ||
![]() |
4af944a00b | ||
![]() |
48ceada956 | ||
![]() |
e7ef1679a0 | ||
![]() |
228b2d071b | ||
![]() |
1ea9a76ea9 | ||
![]() |
c7c8ff266b | ||
![]() |
b062c424d8 | ||
![]() |
714476bf29 | ||
![]() |
e49690b52b | ||
![]() |
f9d35b719b | ||
![]() |
c886384f2c | ||
![]() |
a61cd43c3c | ||
![]() |
6d1b3235d2 | ||
![]() |
e7e9d8e3b9 | ||
![]() |
8cf0e80019 | ||
![]() |
c392fa7272 | ||
![]() |
082884baa0 | ||
![]() |
3a31a0326c | ||
![]() |
2d561f267d | ||
![]() |
5eafff737a | ||
![]() |
8cf4d0cb0f | ||
![]() |
d1953470d9 | ||
![]() |
3a52f2c403 | ||
![]() |
ac40922957 | ||
![]() |
5aed9ee1a4 | ||
![]() |
8318169c39 | ||
![]() |
ad00cf3fc3 | ||
![]() |
3ff7b21287 | ||
![]() |
36fbae850d | ||
![]() |
24ff5684cd | ||
![]() |
aab62fb724 | ||
![]() |
a810890614 | ||
![]() |
a3bfdc1ec8 | ||
![]() |
a7dc719934 | ||
![]() |
74433303fb | ||
![]() |
30d62bda3b | ||
![]() |
cc7703766e | ||
![]() |
9d664d3577 | ||
![]() |
76bfab1303 | ||
![]() |
7d2fc48437 | ||
![]() |
171c114b0f | ||
![]() |
b1d2ac34a2 | ||
![]() |
c7ce87c4b6 | ||
![]() |
4e22c42b10 | ||
![]() |
eabe789bbb | ||
![]() |
aa1403480c | ||
![]() |
91c8f1f5bc | ||
![]() |
b421bf3931 | ||
![]() |
6e6f4679f4 | ||
![]() |
5bb3e57b7b | ||
![]() |
17221f5369 | ||
![]() |
98d4d3fcf0 | ||
![]() |
82092338d6 | ||
![]() |
9868b41a61 | ||
![]() |
c247789adf | ||
![]() |
48822b6561 | ||
![]() |
cd22f8def5 | ||
![]() |
0f30ebbcea | ||
![]() |
1a2e46f09b | ||
![]() |
52ac011556 | ||
![]() |
f34e5f2ac0 | ||
![]() |
ca8db22639 | ||
![]() |
1846bf5255 | ||
![]() |
dce0ac2f8f | ||
![]() |
9cc60983d0 | ||
![]() |
7c2c88f780 | ||
![]() |
7690811da3 | ||
![]() |
7dc2e404ed | ||
![]() |
080ab56ea9 | ||
![]() |
83915f080c | ||
![]() |
2841f17729 | ||
![]() |
0187ba4938 | ||
![]() |
bedfc0a2e0 | ||
![]() |
ea08c04963 | ||
![]() |
067f2af3e5 | ||
![]() |
8d98306f8e | ||
![]() |
09a045334c | ||
![]() |
bc8e5fc144 | ||
![]() |
77e0d28a9d | ||
![]() |
480a054f0c | ||
![]() |
26c895d475 | ||
![]() |
5cbb55cfb1 | ||
![]() |
dcb9506a1b | ||
![]() |
2acec4df12 | ||
![]() |
4bd761c726 | ||
![]() |
2f732b8411 | ||
![]() |
5aa02055bf | ||
![]() |
6ed15565c8 | ||
![]() |
77a2c55c87 | ||
![]() |
4a9fa01eb7 | ||
![]() |
bd031d8980 | ||
![]() |
b76a037a94 | ||
![]() |
e71daa2520 | ||
![]() |
f372aeb067 | ||
![]() |
ef37bbcb81 | ||
![]() |
944457463e | ||
![]() |
6f7f25bb46 | ||
![]() |
d60d7f2250 | ||
![]() |
2b8c4b3eca | ||
![]() |
7039bda359 | ||
![]() |
d346a8f73f | ||
![]() |
523f2dee7c | ||
![]() |
b33e39491b | ||
![]() |
317ebf4387 | ||
![]() |
31ba780099 | ||
![]() |
d1b30619e2 | ||
![]() |
3fab52296a | ||
![]() |
a6e109799a | ||
![]() |
80af2cd691 | ||
![]() |
d911b55e25 | ||
![]() |
eb73fc4538 | ||
![]() |
75f77ec7a3 | ||
![]() |
a1d969bbfd | ||
![]() |
11f1ad6d76 | ||
![]() |
7facf0adad | ||
![]() |
2b739c2b40 | ||
![]() |
269ae323e0 | ||
![]() |
0d0e5812dd | ||
![]() |
61c2661377 | ||
![]() |
de710dff94 | ||
![]() |
8c524171fb | ||
![]() |
946d24690c | ||
![]() |
250d89482e | ||
![]() |
2f8ee7a7eb | ||
![]() |
7aff4557a6 | ||
![]() |
481ba5a30f | ||
![]() |
52dc459704 | ||
![]() |
dc3477d68d | ||
![]() |
24ab125d28 | ||
![]() |
939508e799 | ||
![]() |
433ccff851 | ||
![]() |
7929967ddc | ||
![]() |
449fc2c1cf | ||
![]() |
bd0570ac30 | ||
![]() |
bf137189c5 | ||
![]() |
1fa6788310 | ||
![]() |
44d5d7ae64 | ||
![]() |
da4e18cb69 | ||
![]() |
7723f87bbf | ||
![]() |
85769c1439 | ||
![]() |
034c369ddb | ||
![]() |
4e5a0a6134 | ||
![]() |
3067b79363 | ||
![]() |
40c00a1434 | ||
![]() |
4d3ad4b6b9 | ||
![]() |
e900a62e75 | ||
![]() |
c3969364aa | ||
![]() |
e9df9f10dc | ||
![]() |
f78f5b5361 | ||
![]() |
c061438a35 | ||
![]() |
8441dbe007 | ||
![]() |
e21a741a78 | ||
![]() |
955f437e6c | ||
![]() |
fd419076c2 | ||
![]() |
7569536d56 | ||
![]() |
3a6102900f | ||
![]() |
6dbc694409 | ||
![]() |
7a3dcc4dc6 | ||
![]() |
23393b5d3e | ||
![]() |
863f3ad510 | ||
![]() |
e6d86ca280 | ||
![]() |
c22e25e3d2 | ||
![]() |
52ffb195ec | ||
![]() |
92a51af638 | ||
![]() |
d7a9158cf2 | ||
![]() |
f0f84090d2 | ||
![]() |
9d78a3b5cf | ||
![]() |
2fc163af5a | ||
![]() |
10be98e371 | ||
![]() |
e0eb083e44 | ||
![]() |
e17cd78153 | ||
![]() |
0015f511f8 | ||
![]() |
f0f71c9f85 | ||
![]() |
0002543cca | ||
![]() |
c1096415aa | ||
![]() |
6625768228 | ||
![]() |
a27f601fe8 | ||
![]() |
72a877d9ca | ||
![]() |
b7ba09a551 | ||
![]() |
a98cb66c53 | ||
![]() |
6785ecad1d | ||
![]() |
937af536b6 | ||
![]() |
5487314230 | ||
![]() |
51e9bb2a7f | ||
![]() |
376bb981ae | ||
![]() |
ed9d78d2f3 | ||
![]() |
3c4e50dbda | ||
![]() |
523f9dd95a | ||
![]() |
a43742c8b1 | ||
![]() |
c49e4fd63d | ||
![]() |
905cce7021 | ||
![]() |
7a49b5dedc | ||
![]() |
3a2870a6bb | ||
![]() |
9a475f2c57 | ||
![]() |
58598742e8 | ||
![]() |
d04e44f52f | ||
![]() |
c7ec1f44e9 | ||
![]() |
3ed9a5d3d8 | ||
![]() |
61285b6b8c | ||
![]() |
d17c547bca | ||
![]() |
7bc20b0993 | ||
![]() |
6c4b3dea96 | ||
![]() |
6ae1bf5814 | ||
![]() |
8503135ce0 | ||
![]() |
590fe0762d | ||
![]() |
d565b90736 | ||
![]() |
c88156802a | ||
![]() |
7d8dbcbde7 | ||
![]() |
66ec66b291 | ||
![]() |
fc0eb0e793 | ||
![]() |
ed7e9e1eae | ||
![]() |
8985917a96 | ||
![]() |
c72bc39aac | ||
![]() |
b29c5c6aa6 | ||
![]() |
07486762dc | ||
![]() |
50fe38d5fc | ||
![]() |
5d48a69649 | ||
![]() |
1345ad97d5 | ||
![]() |
1340b8e63e | ||
![]() |
3a3411c117 | ||
![]() |
1166ddfe87 | ||
![]() |
574e361f90 | ||
![]() |
f3745a2752 | ||
![]() |
4dbcad5ad5 | ||
![]() |
6035d05d65 | ||
![]() |
dfd78b9735 | ||
![]() |
6edc90c82c | ||
![]() |
084e191b28 | ||
![]() |
96068d003b | ||
![]() |
a6e20fa62c | ||
![]() |
df0ad6e277 | ||
![]() |
fa0de1c413 | ||
![]() |
909bfffb51 | ||
![]() |
7b1aed7a94 | ||
![]() |
78ba282a1b | ||
![]() |
5362c4970f | ||
![]() |
90cab6d3ee | ||
![]() |
e462348db0 | ||
![]() |
69bbb375e2 | ||
![]() |
d89d8cdf8d | ||
![]() |
cdef0796a7 | ||
![]() |
7469f13254 | ||
![]() |
89d82e5117 |
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -3,8 +3,12 @@
|
||||
.gitignore export-ignore
|
||||
.github export-ignore
|
||||
.editorconfig export-ignore
|
||||
.travis.yml export-ignore
|
||||
_config.yml export-ignore
|
||||
release.sh export-ignore
|
||||
|
||||
# cypress
|
||||
cypress export-ignore
|
||||
cypress.config.js export-ignore
|
||||
cypress.env.json
|
||||
|
||||
*.sh text eol=lf
|
||||
|
120
.github/workflows/cypress.yml
vendored
Normal file
120
.github/workflows/cypress.yml
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
name: Cypress
|
||||
on:
|
||||
pull_request:
|
||||
branches: [develop]
|
||||
push:
|
||||
branches: [develop]
|
||||
|
||||
jobs:
|
||||
cypress:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: myaac
|
||||
MYSQL_USER: myaac
|
||||
MYSQL_PASSWORD: myaac
|
||||
ports:
|
||||
- 3306/tcp
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: [ '7.4', '8.0', '8.1' ]
|
||||
name: MyAAC on PHP ${{ matrix.php-versions }}
|
||||
steps:
|
||||
- name: 📌 MySQL Start & init & show db
|
||||
run: |
|
||||
sudo /etc/init.d/mysql start
|
||||
mysql -e 'CREATE DATABASE myaac;' -uroot -proot
|
||||
mysql -e "SHOW DATABASES" -uroot -proot
|
||||
|
||||
- name: Checkout MyAAC
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: 0.9
|
||||
|
||||
- name: Checkout TFS
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: otland/forgottenserver
|
||||
ref: 1.4
|
||||
path: tfs
|
||||
|
||||
- name: Import TFS Schema
|
||||
run: |
|
||||
mysql -uroot -proot myaac < tfs/schema.sql
|
||||
|
||||
- name: Rename config.lua
|
||||
run: mv tfs/config.lua.dist tfs/config.lua
|
||||
|
||||
- name: Replace mysqlUser
|
||||
uses: jacobtomlinson/gha-find-replace@v2
|
||||
with:
|
||||
find: 'mysqlUser = "forgottenserver"'
|
||||
replace: 'mysqlUser = "root"'
|
||||
regex: false
|
||||
include: 'tfs/config.lua'
|
||||
|
||||
- name: Replace mysqlPass
|
||||
uses: jacobtomlinson/gha-find-replace@v2
|
||||
with:
|
||||
find: 'mysqlPass = ""'
|
||||
replace: 'mysqlPass = "root"'
|
||||
regex: false
|
||||
include: 'tfs/config.lua'
|
||||
|
||||
- name: Replace mysqlDatabase
|
||||
uses: jacobtomlinson/gha-find-replace@v2
|
||||
with:
|
||||
find: 'mysqlDatabase = "forgottenserver"'
|
||||
replace: 'mysqlDatabase = "myaac"'
|
||||
regex: false
|
||||
include: 'tfs/config.lua'
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: mbstring, dom, fileinfo, mysql, json, xml, pdo, pdo_mysql
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
# Use composer.json for key, if composer.lock is not committed.
|
||||
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: Run PHP server
|
||||
run: nohup php -S localhost:8080 > php.log 2>&1 &
|
||||
|
||||
- name: Cypress Run
|
||||
uses: cypress-io/github-action@v5
|
||||
env:
|
||||
CYPRESS_URL: http://localhost:8080
|
||||
CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/tfs
|
||||
|
||||
- name: Save screenshots
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: cypress-screenshots
|
||||
path: cypress/screenshots
|
||||
|
||||
- name: Upload Cypress Videos
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: cypress-videos
|
||||
path: cypress/videos
|
11
.github/workflows/phplint.yml
vendored
11
.github/workflows/phplint.yml
vendored
@@ -1,13 +1,16 @@
|
||||
name: PHP Linting
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, develop]
|
||||
branches: [develop]
|
||||
push:
|
||||
branches: [master]
|
||||
branches: [develop]
|
||||
|
||||
jobs:
|
||||
phplint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: michaelw90/PHP-Lint@master
|
||||
- uses: actions/checkout@v3
|
||||
- uses: overtrue/phplint@8.2
|
||||
with:
|
||||
path: .
|
||||
options: --exclude=*.log
|
||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@@ -2,6 +2,9 @@ Thumbs.db
|
||||
.DS_Store
|
||||
.idea
|
||||
|
||||
#
|
||||
/.htaccess
|
||||
|
||||
# composer
|
||||
composer.lock
|
||||
vendor
|
||||
@@ -9,6 +12,10 @@ vendor
|
||||
# npm
|
||||
node_modules
|
||||
|
||||
# cypress
|
||||
cypress.env.json
|
||||
cypress/e2e/2-advanced-examples
|
||||
|
||||
# created by release.sh
|
||||
releases
|
||||
tmp
|
||||
|
@@ -6,6 +6,10 @@
|
||||
Options -MultiViews
|
||||
</IfModule>
|
||||
|
||||
<FilesMatch "^(CHANGELOG\.md|README\.md|composer\.json|composer\.lock|package\.json|package-lock\.json|cypress\.env\.json)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
|
18
.travis.yml
18
.travis.yml
@@ -1,18 +0,0 @@
|
||||
|
||||
language: php
|
||||
php:
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- 7.4
|
||||
- 8.0
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
|
||||
before_script:
|
||||
- composer require php-parallel-lint/php-parallel-lint --no-suggest --no-progress --no-interaction --no-ansi --quiet --optimize-autoloader
|
||||
|
||||
script:
|
||||
- php vendor/bin/parallel-lint --no-progress --no-colors --exclude vendor --exclude "system/libs/pot/OTS_DB_PDOQuery.php" .
|
48
CHANGELOG.md
48
CHANGELOG.md
@@ -1,9 +1,55 @@
|
||||
# Changelog
|
||||
|
||||
## [0.9.0 - x.x.2020]
|
||||
## [0.9.0-alpha - 02.06.2023]
|
||||
|
||||
Minimum PHP version for this release is 7.2.5.
|
||||
|
||||
### Added
|
||||
* reworked Admin Panel (@Leesneaks, @gpedro, @slawkens)
|
||||
* updated to Bootstrap v4
|
||||
* new Menu
|
||||
* new Dashboard: statistics, server status
|
||||
* new Admin Bar showed on top when admin logged in
|
||||
* new page: Server Data, to reload server data
|
||||
* new pages: mass account & teleport tools
|
||||
* changelogs editor
|
||||
* revised Accounts & Players editors
|
||||
* option to add/modify menus with plugins
|
||||
* option to enable/disable plugins
|
||||
* better, updated TinyMCE editor (v6.x)
|
||||
* with option to upload images
|
||||
* list of open source libraries used in project
|
||||
* brand new charming installation page (by @fernandomatos)
|
||||
* using Bootstrap
|
||||
* new pages router: nikic/fast-route, allowing for better customisation
|
||||
* Guild Wars support (available as plugin)
|
||||
* support for login and create account only by email (configurable)
|
||||
* with no need for account name
|
||||
* Google ReCAPTCHA v3 support (available as plugin)
|
||||
* automatically load towns names from .OTBM file
|
||||
* support for Account Number
|
||||
* suggest account number option
|
||||
* many new functions, hooks and configurables
|
||||
* better Exception Handler (Whoops - https://github.com/filp/whoops)
|
||||
* add Cypress testing
|
||||
|
||||
### Changed
|
||||
* Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc.
|
||||
* mail support is disabled on fresh install, can be manually enabled by user
|
||||
* disable add php pages in admin panel for security. Option to disable plugins upload
|
||||
* visitors counter shows now user browser, and also if its bot
|
||||
* changes in required and optional PHP extensions
|
||||
* reworked Pages:
|
||||
* Bans
|
||||
* works now for TFS 1.x
|
||||
* Highscores
|
||||
* frags works for TFS 1.x
|
||||
* cached
|
||||
* creatures
|
||||
* moved pages to Twig:
|
||||
* experience stages
|
||||
* update player_deaths entries on name change
|
||||
* change_password email to be more informal
|
||||
|
||||
### Fixed
|
||||
* hundrets of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here
|
||||
|
2
CREDITS
2
CREDITS
@@ -1,3 +1,3 @@
|
||||
* Gesior.pl (2007 - 2008)
|
||||
* Slawkens (2009 - 2022)
|
||||
* Slawkens (2009 - 2023)
|
||||
* Contributors listed in CONTRIBUTORS.txt
|
||||
|
@@ -36,7 +36,7 @@ Official website: https://my-aac.org
|
||||
chmod 660 images/guilds
|
||||
chmod 660 images/houses
|
||||
chmod 660 images/gallery
|
||||
chmod -R 770 system/cache
|
||||
chmod -R 760 system/cache
|
||||
|
||||
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.
|
||||
|
||||
|
@@ -1 +1,2 @@
|
||||
<?php
|
||||
<?php
|
||||
// nothing yet here
|
35
admin/includes/settings_menus.php
Normal file
35
admin/includes/settings_menus.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
$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;
|
@@ -6,10 +6,6 @@ require '../common.php';
|
||||
const ADMIN_PANEL = true;
|
||||
const MYAAC_ADMIN = true;
|
||||
|
||||
if(file_exists(BASE . 'config.local.php')) {
|
||||
require_once BASE . 'config.local.php';
|
||||
}
|
||||
|
||||
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
|
||||
{
|
||||
header('Location: ' . BASE_URL . 'install/');
|
||||
@@ -29,10 +25,9 @@ define('PAGE', $page);
|
||||
require SYSTEM . 'functions.php';
|
||||
require SYSTEM . 'init.php';
|
||||
|
||||
if(config('env') === 'dev') {
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
// verify myaac tables exists in database
|
||||
if(!$db->hasTable('myaac_account_actions')) {
|
||||
throw new RuntimeException('Seems that the table <strong>myaac_account_actions</strong> of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting <a href="' . BASE_URL . 'install">this</a> url.');
|
||||
}
|
||||
|
||||
// event system
|
||||
@@ -42,7 +37,6 @@ $hooks->load();
|
||||
|
||||
require SYSTEM . 'status.php';
|
||||
require SYSTEM . 'login.php';
|
||||
require SYSTEM . 'migrate.php';
|
||||
require __DIR__ . '/includes/functions.php';
|
||||
|
||||
$twig->addGlobal('config', $config);
|
||||
@@ -70,7 +64,9 @@ if(!@file_exists($file)) {
|
||||
}
|
||||
|
||||
ob_start();
|
||||
include($file);
|
||||
if($hooks->trigger(HOOK_ADMIN_BEFORE_PAGE)) {
|
||||
require $file;
|
||||
}
|
||||
|
||||
$content .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
@@ -10,12 +10,17 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$title = 'Account editor';
|
||||
$admin_base = BASE_URL . 'admin/?p=accounts';
|
||||
$admin_base = ADMIN_URL . '?p=accounts';
|
||||
$use_datatable = true;
|
||||
|
||||
if ($config['account_country'])
|
||||
require SYSTEM . 'countries.conf.php';
|
||||
|
||||
$nameOrNumberColumn = 'name';
|
||||
if (USE_ACCOUNT_NUMBER) {
|
||||
$nameOrNumberColumn = 'number';
|
||||
}
|
||||
|
||||
$hasSecretColumn = $db->hasColumn('accounts', 'secret');
|
||||
$hasCoinsColumn = $db->hasColumn('accounts', 'coins');
|
||||
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
|
||||
@@ -32,7 +37,7 @@ if ($config['account_country']) {
|
||||
$countries[$code] = $c;
|
||||
}
|
||||
$web_acc = ACCOUNT_WEB_FLAGS;
|
||||
$acc_type = config('account_types');
|
||||
$acc_type = setting('core.account_types');
|
||||
?>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ >
|
||||
@@ -48,16 +53,16 @@ else if (isset($_REQUEST['search'])) {
|
||||
if (strlen($search_account) < 3 && !Validator::number($search_account)) {
|
||||
echo_error('Player name is too short.');
|
||||
} else {
|
||||
$query = $db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $db->quote($search_account));
|
||||
$query = $db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $db->quote($search_account));
|
||||
if ($query->rowCount() == 1) {
|
||||
$query = $query->fetch();
|
||||
$id = (int)$query['id'];
|
||||
} else {
|
||||
$query = $db->query('SELECT `id`, `name` FROM `accounts` WHERE `name` LIKE ' . $db->quote('%' . $search_account . '%'));
|
||||
$query = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` LIKE ' . $db->quote('%' . $search_account . '%'));
|
||||
if ($query->rowCount() > 0 && $query->rowCount() <= 10) {
|
||||
$str_construct = 'Do you mean?<ul class="mb-0">';
|
||||
foreach ($query as $row)
|
||||
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row['name'] . '</a></li>';
|
||||
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row[$nameOrNumberColumn] . '</a></li>';
|
||||
$str_construct .= '</ul>';
|
||||
echo_error($str_construct);
|
||||
} else if ($query->rowCount() > 10)
|
||||
@@ -145,7 +150,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
$web_lastlogin = strtotime($_POST['web_lastlogin']);
|
||||
verify_number($web_lastlogin, 'Web Last login', 11);
|
||||
|
||||
if (!$error) {
|
||||
if (!$error && $hooks->trigger(HOOK_ADMIN_ACCOUNTS_SAVE_POST, ['account_id' => $account->getId(), 'account_email' => $account->getEMail()])) {
|
||||
if (USE_ACCOUNT_NAME) {
|
||||
$account->setName($name);
|
||||
}
|
||||
@@ -203,7 +208,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
}
|
||||
}
|
||||
} else if ($id == 0) {
|
||||
$accounts_db = $db->query('SELECT `id`, `name`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC');
|
||||
$accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC');
|
||||
?>
|
||||
<div class="col-12 col-sm-12 col-lg-10">
|
||||
<div class="card card-info card-outline">
|
||||
@@ -215,7 +220,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th><?= ($nameOrNumberColumn == 'number' ? 'Number' : 'Name'); ?></th>
|
||||
<?php if($hasTypeColumn || $hasGroupColumn): ?>
|
||||
<th>Position</th>
|
||||
<?php endif; ?>
|
||||
@@ -226,7 +231,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
<?php foreach ($accounts_db as $account_lst): ?>
|
||||
<tr>
|
||||
<th><?php echo $account_lst['id']; ?></th>
|
||||
<td><?php echo $account_lst['name']; ?></a></td>
|
||||
<td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td>
|
||||
<?php if($hasTypeColumn || $hasGroupColumn): ?>
|
||||
<td>
|
||||
<?php if ($hasTypeColumn) {
|
||||
@@ -284,6 +289,11 @@ else if (isset($_REQUEST['search'])) {
|
||||
<label for="name">Account Name:</label>
|
||||
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getName(); ?>"/>
|
||||
</div>
|
||||
<?php elseif (USE_ACCOUNT_NUMBER): ?>
|
||||
<div class="col-12 col-sm-12 col-lg-4">
|
||||
<label for="name">Account Number:</label>
|
||||
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getNumber(); ?>"/>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="col-12 col-sm-12 col-lg-5">
|
||||
<div class="form-check">
|
||||
@@ -351,7 +361,7 @@ else if (isset($_REQUEST['search'])) {
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-12 col-sm-12 col-lg-6">
|
||||
<label for="email">Email:</label><?php echo (config('mail_enabled') ? ' (<a href="' . ADMIN_URL . '?p=mailer&mail_to=' . $account->getEMail() . '">Send Mail</a>)' : ''); ?>
|
||||
<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): ?>
|
||||
|
@@ -47,12 +47,11 @@ $tmp = '';
|
||||
if (fetchDatabaseConfig('site_closed_message', $tmp))
|
||||
$closed_message = $tmp;
|
||||
|
||||
$configAdminPanelModules = config('admin_panel_modules');
|
||||
if (isset($configAdminPanelModules)) {
|
||||
$settingAdminPanelModules = setting('core.admin_panel_modules');
|
||||
if (count($settingAdminPanelModules) > 0) {
|
||||
echo '<div class="row">';
|
||||
$configAdminPanelModules = explode(',', $configAdminPanelModules);
|
||||
$twig_loader->prependPath(__DIR__ . '/modules/templates');
|
||||
foreach ($configAdminPanelModules as $box) {
|
||||
foreach ($settingAdminPanelModules as $box) {
|
||||
$file = __DIR__ . '/modules/' . $box . '.php';
|
||||
if (file_exists($file)) {
|
||||
include($file);
|
||||
|
@@ -10,6 +10,12 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
$title = 'Login';
|
||||
|
||||
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',
|
||||
|
@@ -15,8 +15,8 @@ if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config('mail_enabled')) {
|
||||
echo 'Mail support disabled.';
|
||||
if (!setting('core.mail_enabled')) {
|
||||
echo 'Mail support disabled in config.';
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -46,6 +46,7 @@ if (isset($_REQUEST['template'])) {
|
||||
if ($cache->enabled()) {
|
||||
$cache->delete('template_menus');
|
||||
}
|
||||
|
||||
success('Saved at ' . date('H:i'));
|
||||
}
|
||||
|
||||
@@ -56,6 +57,7 @@ if (isset($_REQUEST['template'])) {
|
||||
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;
|
||||
@@ -91,15 +93,16 @@ if (isset($_REQUEST['template'])) {
|
||||
<ul class="sortable" id="sortable-<?php echo $id ?>">
|
||||
<?php
|
||||
if (isset($menus[$id])) {
|
||||
foreach ($menus[$id] as $i => $menu):
|
||||
$i = 0;
|
||||
foreach ($menus[$id] as $menu):
|
||||
?>
|
||||
<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 $menu['color'] ?>"/>
|
||||
<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo (empty($menu['color']) ? ($config['menu_default_color'] ?? '#ffffff') : $menu['color']); ?>"/>
|
||||
<a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li>
|
||||
<?php $last_id[$id] = $i;
|
||||
<?php $i++; $last_id[$id] = $i;
|
||||
endforeach;
|
||||
} ?>
|
||||
</ul>
|
||||
@@ -120,7 +123,8 @@ if (isset($_REQUEST['template'])) {
|
||||
<?php
|
||||
$twig->display('admin.menus.js.html.twig', array(
|
||||
'menus' => $menus,
|
||||
'last_id' => $last_id
|
||||
'last_id' => $last_id,
|
||||
'menu_default_color' => $config['menu_default_color'] ?? '#ffffff'
|
||||
));
|
||||
?>
|
||||
<?php
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$balance = ($db->hasColumn('players', 'balance') ? $db->query('SELECT `balance`, `id`, `name`,`level` FROM `players` ORDER BY `balance` DESC LIMIT 10;') : 0);
|
||||
|
||||
$twig->display('balance.html.twig', array(
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$coins = ($db->hasColumn('accounts', 'coins') ? $db->query('SELECT `coins`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `coins` DESC LIMIT 10;') : 0);
|
||||
|
||||
$twig->display('coins.html.twig', array(
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$players = ($db->hasColumn('accounts', 'created') ? $db->query('SELECT `created`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `created` DESC LIMIT 10;') : 0);
|
||||
|
||||
$twig->display('created.html.twig', array(
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$players = ($db->hasColumn('players', 'lastlogin') ? $db->query('SELECT name, level, lastlogin FROM players ORDER BY lastlogin DESC LIMIT 10;') : 0);
|
||||
$twig->display('lastlogin.html.twig', array(
|
||||
'players' => $players,
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$points = ($db->hasColumn('accounts', 'premium_points') ? $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;') : 0);
|
||||
|
||||
$twig->display('points.html.twig', array(
|
||||
|
@@ -76,18 +76,18 @@ if (!empty($action)) {
|
||||
$enable_tinymce = $_page['enable_tinymce'] == '1';
|
||||
$access = $_page['access'];
|
||||
} else {
|
||||
if(Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access)) {
|
||||
if(Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
|
||||
$action = $name = $p_title = $body = '';
|
||||
$player_id = 1;
|
||||
$access = 0;
|
||||
$php = false;
|
||||
$enable_tinymce = true;
|
||||
success("Updated successful.");
|
||||
success('Updated successful.');
|
||||
}
|
||||
}
|
||||
} else if ($action == 'hide') {
|
||||
Pages::toggleHidden($id, $errors, $status);
|
||||
success(($status == 1 ? 'Show' : 'Hide') . " successful.");
|
||||
success(($status == 1 ? 'Show' : 'Hide') . ' successful.');
|
||||
}
|
||||
|
||||
if (!empty($errors))
|
||||
@@ -152,6 +152,10 @@ class Pages
|
||||
$errors[] = 'Enable PHP is wrong.';
|
||||
return false;
|
||||
}
|
||||
if ($php == 1 && !getBoolean(setting('core.admin_pages_php_enable'))) {
|
||||
$errors[] = 'PHP pages disabled on this server. To enable go to Settings in Admin Panel and enable <strong>Enable PHP Pages</strong>.';
|
||||
return false;
|
||||
}
|
||||
if(!isset($enable_tinymce) || ($enable_tinymce != 0 && $enable_tinymce != 1)) {
|
||||
$errors[] = 'Enable TinyMCE is wrong.';
|
||||
return false;
|
||||
@@ -200,7 +204,7 @@ class Pages
|
||||
return !count($errors);
|
||||
}
|
||||
|
||||
static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access)
|
||||
static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors)
|
||||
{
|
||||
if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
|
||||
return false;
|
||||
@@ -254,5 +258,3 @@ class Pages
|
||||
return !count($errors);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@@ -16,4 +16,4 @@ if (!function_exists('phpinfo')) { ?>
|
||||
<?php return;
|
||||
}
|
||||
?>
|
||||
<iframe src="<?php echo BASE_URL; ?>admin/tools/phpinfo.php" width="1024" height="550"></iframe>
|
||||
<iframe src="<?php echo ADMIN_URL; ?>tools/phpinfo.php" width="1024" height="550"></iframe>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$title = 'Player editor';
|
||||
$player_base = BASE_URL . 'admin/?p=players';
|
||||
$player_base = ADMIN_URL . '?p=players';
|
||||
|
||||
$use_datatable = true;
|
||||
require_once LIBS . 'forum.php';
|
||||
@@ -663,7 +663,14 @@ else if (isset($_REQUEST['search'])) {
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-lg-6">
|
||||
<label for="lastip" class="control-label">Last IP:</label>
|
||||
<input type="text" class="form-control" id="lastip" name="lastip" autocomplete="off" maxlength="10" value="<?php echo longToIp($player->getLastIP()); ?>" readonly/>
|
||||
<input type="text" class="form-control" id="lastip" name="lastip" autocomplete="off" maxlength="10" value="<?php
|
||||
if (strlen($player->getLastIP()) > 11) {
|
||||
echo inet_ntop($player->getLastIP());
|
||||
}
|
||||
else {
|
||||
echo longToIp($player->getLastIP());
|
||||
}
|
||||
?>" readonly/>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($db->hasColumn('players', 'loss_experience')): ?>
|
||||
|
@@ -13,6 +13,10 @@ $use_datatable = true;
|
||||
|
||||
require_once LIBS . 'plugins.php';
|
||||
|
||||
if (!getBoolean(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 {
|
||||
$twig->display('admin.plugins.form.html.twig');
|
||||
|
||||
if (isset($_REQUEST['uninstall'])) {
|
||||
@@ -23,13 +27,27 @@ if (isset($_REQUEST['uninstall'])) {
|
||||
} else {
|
||||
error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError());
|
||||
}
|
||||
} else if (isset($_FILES["plugin"]["name"])) {
|
||||
$file = $_FILES["plugin"];
|
||||
$filename = $file["name"];
|
||||
$tmp_name = $file["tmp_name"];
|
||||
$type = $file["type"];
|
||||
} else if (isset($_REQUEST['enable'])) {
|
||||
$enable = $_REQUEST['enable'];
|
||||
if (Plugins::enable($enable)) {
|
||||
success('Successfully enabled plugin ' . $enable);
|
||||
} else {
|
||||
error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError());
|
||||
}
|
||||
} else if (isset($_REQUEST['disable'])) {
|
||||
$disable = $_REQUEST['disable'];
|
||||
if (Plugins::disable($disable)) {
|
||||
success('Successfully disabled plugin ' . $disable);
|
||||
} else {
|
||||
error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError());
|
||||
}
|
||||
} else if (isset($_FILES['plugin']['name'])) {
|
||||
$file = $_FILES['plugin'];
|
||||
$filename = $file['name'];
|
||||
$tmp_name = $file['tmp_name'];
|
||||
$type = $file['type'];
|
||||
|
||||
$name = explode(".", $filename);
|
||||
$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'])) {
|
||||
@@ -88,23 +106,26 @@ if (isset($_REQUEST['uninstall'])) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$plugins = array();
|
||||
foreach (get_plugins() as $plugin) {
|
||||
foreach (get_plugins(true) as $plugin) {
|
||||
$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json');
|
||||
$string = Plugins::removeComments($string);
|
||||
$plugin_info = json_decode($string, true);
|
||||
|
||||
if ($plugin_info == false) {
|
||||
if (!$plugin_info) {
|
||||
warning('Cannot load plugin info ' . $plugin . '.json');
|
||||
} else {
|
||||
$disabled = (strpos($plugin, 'disabled.') !== false);
|
||||
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
|
||||
$plugins[] = array(
|
||||
'name' => isset($plugin_info['name']) ? $plugin_info['name'] : '',
|
||||
'description' => isset($plugin_info['description']) ? $plugin_info['description'] : '',
|
||||
'version' => isset($plugin_info['version']) ? $plugin_info['version'] : '',
|
||||
'author' => isset($plugin_info['author']) ? $plugin_info['author'] : '',
|
||||
'contact' => isset($plugin_info['contact']) ? $plugin_info['contact'] : '',
|
||||
'file' => $plugin,
|
||||
'name' => $plugin_info['name'] ?? '',
|
||||
'description' => $plugin_info['description'] ?? '',
|
||||
'version' => $plugin_info['version'] ?? '',
|
||||
'author' => $plugin_info['author'] ?? '',
|
||||
'contact' => $plugin_info['contact'] ?? '',
|
||||
'file' => $pluginOriginal,
|
||||
'enabled' => !$disabled,
|
||||
'uninstall' => isset($plugin_info['uninstall'])
|
||||
);
|
||||
}
|
||||
|
56
admin/pages/settings.php
Normal file
56
admin/pages/settings.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Menus
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2019 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
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 - ' . $plugin);
|
||||
|
||||
$settingsParsed = Settings::display($settingsKeyName, $settingsFile['settings']);
|
||||
|
||||
$twig->display('admin.settings.html.twig', [
|
||||
'settingsParsed' => $settingsParsed['content'],
|
||||
'settings' => $settingsFile['settings'],
|
||||
'script' => $settingsParsed['script'],
|
||||
'settingsKeyName' => $settingsKeyName,
|
||||
]);
|
@@ -36,4 +36,3 @@ $twig->display('admin.statistics.html.twig', array(
|
||||
'account_type' => (USE_ACCOUNT_NAME ? 'name' : 'number'),
|
||||
'points' => $points
|
||||
));
|
||||
?>
|
@@ -47,4 +47,3 @@ function version_revert($version)
|
||||
$release = $version;
|
||||
return $major . '.' . $minor . '.' . $release;
|
||||
}*/
|
||||
?>
|
||||
|
@@ -8,10 +8,15 @@
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
use DeviceDetector\DeviceDetector;
|
||||
use DeviceDetector\Parser\Client\Browser;
|
||||
use DeviceDetector\Parser\OperatingSystem;
|
||||
|
||||
$title = 'Visitors';
|
||||
$use_datatable = true;
|
||||
|
||||
if (!$config['visitors_counter']): ?>
|
||||
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>
|
||||
@@ -20,18 +25,42 @@ if (!$config['visitors_counter']): ?>
|
||||
endif;
|
||||
|
||||
require SYSTEM . 'libs/visitors.php';
|
||||
$visitors = new Visitors($config['visitors_counter_ttl']);
|
||||
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
|
||||
|
||||
function compare($a, $b)
|
||||
{
|
||||
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' => $config['visitors_counter_ttl'],
|
||||
'config_visitors_counter_ttl' => setting('core.visitors_counter_ttl'),
|
||||
'visitors' => $tmp
|
||||
));
|
||||
?>
|
||||
|
@@ -1,7 +1,10 @@
|
||||
<?php
|
||||
|
||||
$menus = [
|
||||
return [
|
||||
['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],
|
||||
@@ -16,7 +19,7 @@ $menus = [
|
||||
['name' => 'Add', 'link' => 'changelog&action=new', 'icon' => 'plus', 'order' => 20],
|
||||
],
|
||||
],
|
||||
['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !config('mail_enabled')],
|
||||
['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],
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<?php $hooks->trigger(HOOK_ADMIN_HEAD_START); ?>
|
||||
<?php echo template_header(true); ?>
|
||||
<title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
@@ -16,8 +17,10 @@
|
||||
<script src="<?php echo BASE_URL; ?>tools/js/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
|
||||
<?php $hooks->trigger(HOOK_ADMIN_HEAD_END); ?>
|
||||
</head>
|
||||
<body class="sidebar-mini ">
|
||||
<?php $hooks->trigger(HOOK_ADMIN_BODY_START); ?>
|
||||
<?php if ($logged && admin()) { ?>
|
||||
<div class="wrapper">
|
||||
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
|
||||
@@ -65,7 +68,7 @@
|
||||
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(isset($menu['icon']) ? $menu['icon'] : 'link') ?>"></i>
|
||||
<i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i>
|
||||
<p><?php echo $menu['name'] ?></p>
|
||||
</a>
|
||||
</li>
|
||||
@@ -73,9 +76,9 @@
|
||||
} else if ($has_child) {
|
||||
$used_menu = null;
|
||||
$nav_construct = '';
|
||||
foreach ($menu['link'] as $category => $sub_menu) {
|
||||
foreach ($menu['link'] as $sub_category => $sub_menu) {
|
||||
$nav_construct .= '<li class="nav-item"><a href="?p=' . $sub_menu['link'] . '" class="nav-link';
|
||||
if ($page == $sub_menu['link']) {
|
||||
if ($_SERVER['QUERY_STRING'] == 'p=' . $sub_menu['link']) {
|
||||
$nav_construct .= ' active';
|
||||
$used_menu = true;
|
||||
}
|
||||
@@ -195,5 +198,6 @@ if ($logged && admin()) {
|
||||
<script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script>
|
||||
<?php } ?>
|
||||
<script src="<?php echo BASE_URL; ?>tools/js/adminlte.min.js"></script>
|
||||
<?php $hooks->trigger(HOOK_ADMIN_BODY_END); ?>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -13,4 +13,3 @@ if(!function_exists('phpinfo'))
|
||||
die('phpinfo() disabled on this web server.');
|
||||
|
||||
phpinfo();
|
||||
?>
|
||||
|
34
admin/tools/settings_save.php
Normal file
34
admin/tools/settings_save.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
const MYAAC_ADMIN = true;
|
||||
|
||||
require '../../common.php';
|
||||
require SYSTEM . 'functions.php';
|
||||
require SYSTEM . 'init.php';
|
||||
require SYSTEM . 'login.php';
|
||||
|
||||
if(!admin()) {
|
||||
http_response_code(500);
|
||||
die('Access denied.');
|
||||
}
|
||||
|
||||
if (!isset($_REQUEST['plugin'])) {
|
||||
http_response_code(500);
|
||||
die('Please enter plugin name.');
|
||||
}
|
||||
|
||||
if (!isset($_POST['settings'])) {
|
||||
http_response_code(500);
|
||||
die('Please enter settings.');
|
||||
}
|
||||
|
||||
$settings = Settings::getInstance();
|
||||
|
||||
$settings->save($_REQUEST['plugin'], $_POST['settings']);
|
||||
|
||||
$errors = $settings->getErrors();
|
||||
if (count($errors) > 0) {
|
||||
http_response_code(500);
|
||||
die(implode('<br/>', $errors));
|
||||
}
|
||||
|
||||
echo 'Saved at ' . date('H:i');
|
22
common.php
22
common.php
@@ -26,8 +26,8 @@
|
||||
if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.');
|
||||
|
||||
const MYAAC = true;
|
||||
const MYAAC_VERSION = '0.9.0-dev';
|
||||
const DATABASE_VERSION = 33;
|
||||
const MYAAC_VERSION = '0.10.0-dev';
|
||||
const DATABASE_VERSION = 36;
|
||||
const TABLE_PREFIX = 'myaac_';
|
||||
define('START_TIME', microtime(true));
|
||||
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
|
||||
@@ -138,11 +138,25 @@ if(!IS_CLI) {
|
||||
|
||||
define('SERVER_URL', 'http' . (isset($_SERVER['HTTPS'][0]) && strtolower($_SERVER['HTTPS']) === 'on' ? 's' : '') . '://' . $baseHost);
|
||||
define('BASE_URL', SERVER_URL . BASE_DIR . '/');
|
||||
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/');
|
||||
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/');
|
||||
|
||||
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
|
||||
}
|
||||
|
||||
require SYSTEM . 'exception.php';
|
||||
if (file_exists(BASE . 'config.local.php')) {
|
||||
require BASE . 'config.local.php';
|
||||
}
|
||||
|
||||
ini_set('log_errors', 1);
|
||||
if(@$config['env'] === 'dev') {
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
}
|
||||
else {
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('display_startup_errors', 0);
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
|
||||
}
|
||||
|
||||
$autoloadFile = VENDOR . 'autoload.php';
|
||||
|
@@ -10,6 +10,10 @@
|
||||
"composer/semver": "^3.2",
|
||||
"twig/twig": "^2.0",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"nikic/fast-route": "^1.3"
|
||||
"nikic/fast-route": "^1.3",
|
||||
"matomo/device-detector": "^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"filp/whoops": "^2.15"
|
||||
}
|
||||
}
|
||||
|
326
config.php
326
config.php
@@ -1,326 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This is MyAAC's Main Configuration file
|
||||
*
|
||||
* All the default values are kept here, you should not modify it but use
|
||||
* a config.local.php file instead to override the settings from here.
|
||||
*
|
||||
* This is a piece of PHP code so PHP syntax applies!
|
||||
* For boolean values please use true/false.
|
||||
*
|
||||
* Minimally 'server_path' directive have to be filled, other options are optional.
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2019 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
|
||||
$config = array(
|
||||
// directories & files
|
||||
'server_path' => '', // path to the server directory (same directory where config file is located)
|
||||
|
||||
/**
|
||||
* Environment Setting
|
||||
*
|
||||
* if you use this script on your live server - set to 'prod' (production)
|
||||
* if you want to test and debug the script locally, or develop plugins, set to 'dev' (development)
|
||||
* WARNING: on 'dev' cache is disabled, so site will be significantly slower !!!
|
||||
* WARNING2: on 'dev' all PHP errors/warnings are displayed
|
||||
* Recommended: 'prod' cause of speed (page load time is better)
|
||||
*/
|
||||
'env' => 'prod', // 'prod' for production and 'dev' for development
|
||||
|
||||
'template' => 'kathrine', // template used by website (kathrine, tibiacom)
|
||||
'template_allow_change' => true, // allow users to choose their own template while browsing website?
|
||||
|
||||
'vocations_amount' => 4, // how much basic vocations your server got (without promotion)
|
||||
|
||||
// what client version are you using on this OT?
|
||||
// used for the Downloads page and some templates aswell
|
||||
'client' => 1098, // 954 = client 9.54
|
||||
|
||||
'session_prefix' => 'myaac_', // must be unique for every site on your server
|
||||
'friendly_urls' => false, // mod_rewrite is required for this, it makes links looks more elegant to eye, and also are SEO friendly (example: https://my-aac.org/guilds/Testing instead of https://my-aac.org/?subtopic=guilds&name=Testing). Remember to rename .htaccess.dist to .htaccess
|
||||
'gzip_output' => false, // gzip page content before sending it to the browser, uses less bandwidth but more cpu cycles
|
||||
|
||||
// gesior backward support (templates & pages)
|
||||
// allows using gesior templates and pages with myaac
|
||||
// might bring some performance when disabled
|
||||
'backward_support' => true,
|
||||
|
||||
// head options (html)
|
||||
'meta_description' => 'Tibia is a free massive multiplayer online role playing game (MMORPG).', // description of the site
|
||||
'meta_keywords' => 'free online game, free multiplayer game, ots, open tibia server', // keywords list separated by commas
|
||||
|
||||
// footer
|
||||
'footer' => ''/*'<br/>Your Server © 2016. All rights reserved.'*/,
|
||||
|
||||
'language' => 'en', // default language (currently only 'en' available)
|
||||
'language_allow_change' => false,
|
||||
|
||||
'visitors_counter' => true,
|
||||
'visitors_counter_ttl' => 10, // how long visitor will be marked as online (in minutes)
|
||||
'views_counter' => true,
|
||||
|
||||
// cache system. by default file cache is used
|
||||
'cache_engine' => 'auto', // apc, apcu, eaccelerator, xcache, file, auto, or blank to disable.
|
||||
'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache)
|
||||
|
||||
// database details (leave blank for auto detect from config.lua)
|
||||
'database_host' => '',
|
||||
'database_port' => '', // leave blank to default 3306
|
||||
'database_user' => '',
|
||||
'database_password' => '',
|
||||
'database_name' => '',
|
||||
'database_log' => false, // should database queries be logged and saved into system/logs/database.log?
|
||||
'database_socket' => '', // set if you want to connect to database through socket (example: /var/run/mysqld/mysqld.sock)
|
||||
'database_persistent' => false, // use database permanent connection (like server), may speed up your site
|
||||
|
||||
// multiworld system (only TFS 0.3)
|
||||
'multiworld' => false, // use multiworld system?
|
||||
'worlds' => array( // list of worlds
|
||||
//'1' => 'Your World Name',
|
||||
//'2' => 'Your Second World Name'
|
||||
),
|
||||
|
||||
// images
|
||||
'outfit_images_url' => 'https://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit
|
||||
'outfit_images_wrong_looktypes' => [75, 126, 127, 266, 302], // this looktypes needs to have different margin-top and margin-left because they are wrong positioned
|
||||
'item_images_url' => 'https://item-images.ots.me/1092/', // set to images/items if you host your own items in images folder
|
||||
'item_images_extension' => '.gif',
|
||||
|
||||
// creatures
|
||||
'creatures_images_url' => 'images/monsters/', // set to images/monsters if you host your own creatures in images folder
|
||||
'creatures_images_extension' => '.gif',
|
||||
'creatures_images_preview' => false, // set to true to allow picture previews for creatures
|
||||
'creatures_items_url' => 'https://tibia.fandom.com/wiki/', // set to website which shows details about items.
|
||||
'creatures_loot_percentage' => true, // set to true to show the loot tooltip percent
|
||||
|
||||
// account
|
||||
'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager)
|
||||
'account_login_by_email' => false, // use email instead of Account Name like in latest Tibia
|
||||
'account_login_by_email_fallback' => false, // allow also additionally login by Account Name/Number (for users that might forget their email)
|
||||
'account_create_auto_login' => false, // auto login after creating account?
|
||||
'account_create_character_create' => true, // allow directly to create character on create account page?
|
||||
'account_mail_verify' => false, // force users to confirm their email addresses when registering
|
||||
'account_mail_confirmed_reward' => [ // reward users for confirming their E-Mails
|
||||
// account_mail_verify needs to be enabled too
|
||||
'premium_days' => 0,
|
||||
'premium_points' => 0,
|
||||
'coins' => 0,
|
||||
'message' => 'You received %d %s for confirming your E-Mail address.' // example: You received 20 premium points for confirming your E-Mail address.
|
||||
],
|
||||
'account_mail_unique' => true, // email addresses cannot be duplicated? (one account = one email)
|
||||
'account_mail_block_plus_sign' => true, // block email with '+' signs like test+box@gmail.com (help protect against spamming accounts)
|
||||
'account_premium_days' => 0, // default premium days on new account
|
||||
'account_premium_points' => 0, // default premium points on new account
|
||||
'account_welcome_mail' => true, // send welcome email when user registers
|
||||
'account_mail_change' => 2, // how many days user need to change email to account - block hackers
|
||||
'account_country' => true, // user will be able to set country of origin when registering account, this information will be viewable in others places aswell
|
||||
'account_country_recognize' => true, // should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io
|
||||
'account_change_character_name' => false, // can user change their character name for premium points?
|
||||
'account_change_character_name_points' => 30, // cost of name change
|
||||
'account_change_character_sex' => false, // can user change their character sex for premium points?
|
||||
'account_change_character_sex_points' => 30, // cost of sex change
|
||||
'characters_per_account' => 10, // max. number of characters per account
|
||||
|
||||
// mail
|
||||
'mail_enabled' => false, // is aac maker configured to send e-mails?
|
||||
'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:)
|
||||
'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent
|
||||
'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function
|
||||
'plain' => ""/*"--\nMy Server,\nhttp://www.myserver.com"*/,
|
||||
'html' => ''/*'<br/>My Server,\n<a href="http://www.myserver.com">myserver.com</a>'*/
|
||||
),
|
||||
'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function, set to true if you use GMail or Microsoft Outlook)
|
||||
'smtp_host' => '', // mail host. smtp.gmail.com for GMail / smtp-mail.outlook.com for Microsoft Outlook
|
||||
'smtp_port' => 25, // 25 (default) / 465 (ssl, GMail) / 587 (tls, Microsoft Outlook)
|
||||
'smtp_auth' => true, // need authorization?
|
||||
'smtp_user' => 'admin@example.org', // here your email username
|
||||
'smtp_pass' => '',
|
||||
'smtp_secure' => '', // What kind of encryption to use on the SMTP connection. Options: '', 'ssl' (GMail) or 'tls' (Microsoft Outlook)
|
||||
'smtp_debug' => false, // set true to debug (you will see more info in error.log)
|
||||
|
||||
// Google reCAPTCHA (prevent spam bots)
|
||||
'recaptcha_enabled' => false, // enable recaptcha verification code
|
||||
'recaptcha_type' => 'v3', // 'v2-checkbox', 'v2-invisible', 'v3'
|
||||
'recaptcha_site_key' => '', // get your own site and secret keys at https://www.google.com/recaptcha
|
||||
'recaptcha_secret_key' => '',
|
||||
// following option apply only for ReCaptcha v2-checkbox
|
||||
'recaptcha_v2_theme' => 'light', // light, dark
|
||||
// following option apply only for ReCaptcha v3
|
||||
// min score for validation, between 0 - 1.0
|
||||
// https://developers.google.com/recaptcha/docs/v3#interpreting_the_score
|
||||
'recaptcha_v3_min_score' => 0.5,
|
||||
|
||||
//
|
||||
'generate_new_reckey' => true, // let player generate new recovery key, he will receive e-mail with new rec key (not display on page, hacker can't generate rec key)
|
||||
'generate_new_reckey_price' => 20, // price for new recovery key
|
||||
'send_mail_when_change_password' => true, // send e-mail with new password when change password to account
|
||||
'send_mail_when_generate_reckey' => true, // send e-mail with rec key (key is displayed on page anyway when generate)
|
||||
|
||||
// you may need to adjust this for older tfs versions
|
||||
// by removing Community Manager
|
||||
'account_types' => [
|
||||
'None',
|
||||
'Normal',
|
||||
'Tutor',
|
||||
'Senior Tutor',
|
||||
'Gamemaster',
|
||||
'Community Manager',
|
||||
'God',
|
||||
],
|
||||
|
||||
// genders (aka sex)
|
||||
'genders' => array(
|
||||
0 => 'Female',
|
||||
1 => 'Male'
|
||||
),
|
||||
|
||||
// new character config
|
||||
'character_samples' => array( // vocations, format: ID_of_vocation => 'Name of Character to copy'
|
||||
//0 => 'Rook Sample',
|
||||
1 => 'Sorcerer Sample',
|
||||
2 => 'Druid Sample',
|
||||
3 => 'Paladin Sample',
|
||||
4 => 'Knight Sample'
|
||||
),
|
||||
|
||||
'use_character_sample_skills' => false,
|
||||
|
||||
// it must show limited number of players after using search in character page
|
||||
'characters_search_limit' => 15,
|
||||
|
||||
// town list used when creating character
|
||||
// won't be displayed if there is only one item (rookgaard for example)
|
||||
'character_towns' => array(1),
|
||||
|
||||
// characters length
|
||||
// This is the minimum and the maximum length that a player can create a character. It is highly recommend the maximum length to be 21.
|
||||
'character_name_min_length' => 4,
|
||||
'character_name_max_length' => 21,
|
||||
'character_name_npc_check' => true,
|
||||
|
||||
// list of towns
|
||||
// if you use TFS 1.3 with support for 'towns' table in database, then you can ignore this - it will be configured automatically (from MySQL database - Table - towns)
|
||||
// otherwise it will try to load from your .OTBM map file
|
||||
// if you don't see towns on website, then you need to fill this out
|
||||
'towns' => array(
|
||||
0 => 'No town',
|
||||
1 => 'Sample town'
|
||||
),
|
||||
|
||||
// guilds
|
||||
'guild_management' => true, // enable guild management system on the site?
|
||||
'guild_need_level' => 1, // min. level to form a guild
|
||||
'guild_need_premium' => true, // require premium account to form a guild?
|
||||
'guild_image_size_kb' => 80, // maximum size of the guild logo image in KB (kilobytes)
|
||||
'guild_description_default' => 'New guild. Leader must edit this text :)',
|
||||
'guild_description_chars_limit' => 1000, // limit of guild description
|
||||
'guild_description_lines_limit' => 6, // limit of lines, if description has more lines it will be showed as long text, without 'enters'
|
||||
'guild_motd_chars_limit' => 150, // limit of MOTD (message of the day) that is shown later in the game on the guild channel
|
||||
|
||||
// online page
|
||||
'online_record' => true, // display players record?
|
||||
'online_vocations' => false, // display vocation statistics?
|
||||
'online_vocations_images' => false, // display vocation images?
|
||||
'online_skulls' => false, // display skull images
|
||||
'online_outfit' => true,
|
||||
'online_afk' => false,
|
||||
|
||||
// support list page
|
||||
'team_style' => 2, // 1/2 (1 - normal table, 2 - in boxes, grouped by group id)
|
||||
'team_display_status' => true,
|
||||
'team_display_lastlogin' => true,
|
||||
'team_display_world' => false,
|
||||
'team_display_outfit' => true,
|
||||
|
||||
// bans page
|
||||
'bans_per_page' => 20,
|
||||
|
||||
// highscores page
|
||||
'highscores_vocation_box' => true, // show 'Choose a vocation' box on the highscores (allowing peoples to sort highscores by vocation)?
|
||||
'highscores_vocation' => true, // show player vocation under his nickname?
|
||||
'highscores_frags' => false, // show 'Frags' tab (best fraggers on the server)?
|
||||
'highscores_balance' => false, // show 'Balance' tab (richest players on the server)
|
||||
'highscores_outfit' => true, // show player outfit?
|
||||
'highscores_country_box' => false, // doesnt work yet! (not implemented)
|
||||
'highscores_groups_hidden' => 3, // this group id and higher won't be shown on the highscores
|
||||
'highscores_ids_hidden' => array(0), // this ids of players will be hidden on the highscores (should be ids of samples)
|
||||
'highscores_per_page' => 100, // how many records per page on highscores
|
||||
'highscores_cache_ttl' => 15, // how often to update highscores from database in minutes (default 15 minutes)
|
||||
|
||||
// characters page
|
||||
'characters' => array( // what things to display on character view page (true/false in each option)
|
||||
'level' => true,
|
||||
'experience' => false,
|
||||
'magic_level' => false,
|
||||
'balance' => false,
|
||||
'marriage_info' => true, // only 0.3
|
||||
'outfit' => true,
|
||||
'creation_date' => true,
|
||||
'quests' => true,
|
||||
'skills' => true,
|
||||
'equipment' => true,
|
||||
'frags' => false,
|
||||
'deleted' => false, // should deleted characters from same account be still listed on the list of characters? When enabled it will show that character is "[DELETED]"
|
||||
),
|
||||
'quests' => array(
|
||||
//'Some Quest' => 123,
|
||||
//'Some Quest Two' => 456,
|
||||
), // quests list (displayed in character view), name => storage
|
||||
'signature_enabled' => true,
|
||||
'signature_type' => 'tibian', // signature engine to use: tibian, mango, gesior
|
||||
'signature_cache_time' => 5, // how long to store cached file (in minutes), default 5 minutes
|
||||
'signature_browser_cache' => 60, // how long to cache by browser (in minutes), default 1 hour
|
||||
|
||||
// news page
|
||||
'news_limit' => 5, // limit of news on the latest news page
|
||||
'news_ticker_limit' => 5, // limit of news in tickers (mini news) (0 to disable)
|
||||
'news_date_format' => 'j.n.Y', // check php manual date() function for more info about this
|
||||
'news_author' => true, // show author of the news
|
||||
|
||||
// gifts/shop system
|
||||
'gifts_system' => false,
|
||||
|
||||
// support/system
|
||||
'bug_report' => true, // this configurable has no effect, its always enabled
|
||||
|
||||
// forum
|
||||
'forum' => 'site', // link to the server forum, set to "site" if you want to use build in forum system, otherwise leave empty if you aren't going to use any forum
|
||||
'forum_level_required' => 0, // level required to post, 0 to disable
|
||||
'forum_post_interval' => 30, // in seconds
|
||||
'forum_posts_per_page' => 20,
|
||||
'forum_threads_per_page' => 20,
|
||||
// uncomment to force use table for forum
|
||||
//'forum_table_prefix' => 'z_', // what forum mysql table to use, z_ (for gesior old forum) or myaac_ (for myaac)
|
||||
|
||||
// last kills
|
||||
'last_kills_limit' => 50, // max. number of deaths shown on the last kills page
|
||||
|
||||
// status, took automatically from config file if empty
|
||||
'status_enabled' => true, // you can disable status checking by settings this to "false"
|
||||
'status_ip' => '',
|
||||
'status_port' => '',
|
||||
'status_timeout' => 2.0, // how long to wait for the initial response from the server (default: 2 seconds)
|
||||
|
||||
// how often to connect to server and update status (default: every minute)
|
||||
// if your status timeout in config.lua is bigger, that it will be used instead
|
||||
// when server is offline, it will be checked every time web refreshes, ignoring this variable
|
||||
'status_interval' => 60,
|
||||
|
||||
// admin panel
|
||||
'admin_panel_modules' => 'statistics,web_status,server_status,lastlogin,created,points,coins,balance', // default - statistics,web_status,server_status,lastlogin,created,points,coins,balance
|
||||
|
||||
// other
|
||||
'anonymous_usage_statistics' => true,
|
||||
'email_lai_sec_interval' => 60, // time in seconds between e-mails to one account from lost account interface, block spam
|
||||
'google_analytics_id' => '', // e.g.: UA-XXXXXXX-X
|
||||
'experiencetable_columns' => 3, // how many columns to display in experience table page. * experiencetable_rows, 5 = 500 (will show up to 500 level)
|
||||
'experiencetable_rows' => 200, // till how many levels in one column
|
||||
'date_timezone' => 'Europe/Berlin', // more info at http://php.net/manual/en/timezones.php
|
||||
'footer_show_load_time' => true, // display load time of the page in the footer
|
||||
|
||||
'npc' => array()
|
||||
);
|
9
cypress.config.js
Normal file
9
cypress.config.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { defineConfig } = require("cypress");
|
||||
|
||||
module.exports = defineConfig({
|
||||
e2e: {
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
},
|
||||
},
|
||||
});
|
75
cypress/e2e/1-install.cy.js
Normal file
75
cypress/e2e/1-install.cy.js
Normal file
@@ -0,0 +1,75 @@
|
||||
describe('Install MyAAC', () => {
|
||||
beforeEach(() => {
|
||||
// Cypress starts out with a blank slate for each test
|
||||
// so we must tell it to visit our website with the `cy.visit()` command.
|
||||
// Since we want to visit the same URL at the start of all our tests,
|
||||
// we include it in our beforeEach function so that it runs before each test
|
||||
cy.visit(Cypress.env('URL'))
|
||||
})
|
||||
|
||||
it('Go through installer', () => {
|
||||
cy.visit(Cypress.env('URL') + '/install/?step=welcome')
|
||||
cy.wait(1000)
|
||||
|
||||
cy.screenshot('install-welcome')
|
||||
|
||||
// step 1 - Welcome
|
||||
cy.get('select[name="lang"]').select('en')
|
||||
|
||||
//cy.get('input[type=button]').contains('Next »').click()
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
// step 2 - License
|
||||
// just skip
|
||||
cy.contains('GNU/GPL License');
|
||||
cy.get('form').submit()
|
||||
|
||||
// step 3 - Requirements
|
||||
cy.contains('Requirements check');
|
||||
|
||||
cy.get('#step').then(elem => {
|
||||
elem.val('config');
|
||||
});
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
// step 4 - Configuration
|
||||
cy.contains('Basic configuration');
|
||||
|
||||
cy.get('#vars_server_path').click().clear().type(Cypress.env('SERVER_PATH'))
|
||||
cy.get('#vars_mail_admin').click().clear().type('noone@example.net')
|
||||
|
||||
cy.get('[type="checkbox"]').uncheck() // usage statistics uncheck
|
||||
|
||||
cy.wait(1000)
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
// check if there is any error
|
||||
|
||||
|
||||
// step 5 - Import Schema
|
||||
cy.contains('Import MySQL schema');
|
||||
|
||||
// AAC is not installed yet, this message should not come
|
||||
cy.contains('Seems AAC is already installed. Skipping importing MySQL schema..').should('not.exist')
|
||||
|
||||
cy.contains('[class="alert alert-success"]', 'Local configuration has been saved into file: config.local.php').should('be.visible')
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
// step 6 - Admin Account
|
||||
cy.get('#vars_email').click().clear().type('admin@my-aac.org')
|
||||
cy.get('#vars_account').click().clear().type('admin')
|
||||
cy.get('#vars_password').click().clear().type('test1234')
|
||||
cy.get('#vars_password_confirm').click().clear().type('test1234')
|
||||
cy.get('#vars_player_name').click().clear().type('Admin')
|
||||
|
||||
cy.get('form').submit()
|
||||
|
||||
cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 30000 }).should('be.visible')
|
||||
|
||||
cy.screenshot('install-finish')
|
||||
})
|
||||
})
|
33
cypress/e2e/2-create-account.cy.js
Normal file
33
cypress/e2e/2-create-account.cy.js
Normal file
@@ -0,0 +1,33 @@
|
||||
describe('Create Account Page', () => {
|
||||
beforeEach(() => {
|
||||
// Cypress starts out with a blank slate for each test
|
||||
// so we must tell it to visit our website with the `cy.visit()` command.
|
||||
// Since we want to visit the same URL at the start of all our tests,
|
||||
// we include it in our beforeEach function so that it runs before each test
|
||||
cy.visit(Cypress.env('URL') + '/index.php/account/create')
|
||||
})
|
||||
|
||||
it('Create Test Account', () => {
|
||||
cy.screenshot('create-account-page')
|
||||
|
||||
cy.get('#account_input').type('tester')
|
||||
cy.get('#email').type('tester@example.com')
|
||||
|
||||
cy.get('#password').type('test1234')
|
||||
cy.get('#password2').type('test1234')
|
||||
|
||||
cy.get('#character_name').type('Slaw')
|
||||
|
||||
cy.get('#sex1').check()
|
||||
cy.get('#vocation1').check()
|
||||
cy.get('#accept_rules').check()
|
||||
|
||||
cy.get('#createaccount').submit()
|
||||
|
||||
// no errors please
|
||||
cy.contains('The Following Errors Have Occurred:').should('not.exist')
|
||||
|
||||
// ss of post page
|
||||
cy.screenshot('create-account-page-post')
|
||||
})
|
||||
})
|
5
cypress/fixtures/example.json
Normal file
5
cypress/fixtures/example.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
25
cypress/support/commands.js
Normal file
25
cypress/support/commands.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
20
cypress/support/e2e.js
Normal file
20
cypress/support/e2e.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/e2e.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
37
index.php
37
index.php
@@ -56,22 +56,6 @@ if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|zip|rar|g
|
||||
exit;
|
||||
}
|
||||
|
||||
if(file_exists(BASE . 'config.local.php')) {
|
||||
require_once BASE . 'config.local.php';
|
||||
}
|
||||
|
||||
ini_set('log_errors', 1);
|
||||
if(config('env') === 'dev') {
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
}
|
||||
else {
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('display_startup_errors', 0);
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
|
||||
}
|
||||
|
||||
if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install'))
|
||||
{
|
||||
header('Location: ' . BASE_URL . 'install/');
|
||||
@@ -100,13 +84,11 @@ $twig->addGlobal('status', $status);
|
||||
|
||||
require_once SYSTEM . 'router.php';
|
||||
|
||||
require SYSTEM . 'migrate.php';
|
||||
|
||||
$hooks->trigger(HOOK_STARTUP);
|
||||
|
||||
// anonymous usage statistics
|
||||
// sent only when user agrees
|
||||
if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_statistics']) {
|
||||
if(setting('core.anonymous_usage_statistics')) {
|
||||
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days
|
||||
$should_report = true;
|
||||
|
||||
@@ -139,17 +121,16 @@ if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_stat
|
||||
}
|
||||
}
|
||||
|
||||
if($config['views_counter'])
|
||||
if(setting('core.views_counter'))
|
||||
require_once SYSTEM . 'counter.php';
|
||||
|
||||
if($config['visitors_counter'])
|
||||
{
|
||||
if(setting('core.visitors_counter')) {
|
||||
require_once SYSTEM . 'libs/visitors.php';
|
||||
$visitors = new Visitors($config['visitors_counter_ttl']);
|
||||
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
|
||||
}
|
||||
|
||||
// backward support for gesior
|
||||
if($config['backward_support']) {
|
||||
if(setting('core.backward_support')) {
|
||||
define('INITIALIZED', true);
|
||||
$SQL = $db;
|
||||
$layout_header = template_header();
|
||||
@@ -165,7 +146,8 @@ if($config['backward_support']) {
|
||||
|
||||
$config['site'] = &$config;
|
||||
$config['server'] = &$config['lua'];
|
||||
$config['site']['shop_system'] = $config['gifts_system'];
|
||||
$config['site']['shop_system'] = setting('core.gifts_system');
|
||||
$config['site']['gallery_page'] = true;
|
||||
|
||||
if(!isset($config['vdarkborder']))
|
||||
$config['vdarkborder'] = '#505050';
|
||||
@@ -178,8 +160,9 @@ if($config['backward_support']) {
|
||||
$config['site']['serverinfo_page'] = true;
|
||||
$config['site']['screenshot_page'] = true;
|
||||
|
||||
if($config['forum'] != '')
|
||||
$config['forum_link'] = (strtolower($config['forum']) === 'site' ? getLink('forum') : $config['forum']);
|
||||
$forumSetting = setting('core.forum');
|
||||
if($forumSetting != '')
|
||||
$config['forum_link'] = (strtolower($forumSetting) === 'site' ? getLink('forum') : $forumSetting);
|
||||
|
||||
foreach($status as $key => $value)
|
||||
$config['status']['serverStatus_' . $key] = $value;
|
||||
|
@@ -38,4 +38,3 @@ if(!isset($error) || !$error) {
|
||||
$error = true;
|
||||
}
|
||||
}
|
||||
?>
|
@@ -1,4 +1,4 @@
|
||||
SET @myaac_database_version = 33;
|
||||
SET @myaac_database_version = 36;
|
||||
|
||||
CREATE TABLE `myaac_account_actions`
|
||||
(
|
||||
@@ -203,6 +203,7 @@ CREATE TABLE `myaac_monsters` (
|
||||
`mana` int(11) NOT NULL DEFAULT 0,
|
||||
`exp` int(11) NOT NULL,
|
||||
`health` int(11) NOT NULL,
|
||||
`look` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`speed_lvl` int(11) NOT NULL default 1,
|
||||
`use_haste` tinyint(1) NOT NULL,
|
||||
`voices` text NOT NULL,
|
||||
@@ -302,6 +303,16 @@ CREATE TABLE `myaac_gallery`
|
||||
|
||||
INSERT INTO `myaac_gallery` (`id`, `ordering`, `comment`, `image`, `thumb`, `author`) VALUES (NULL, 1, 'Demon', 'images/gallery/demon.jpg', 'images/gallery/demon_thumb.gif', 'MyAAC');
|
||||
|
||||
CREATE TABLE `myaac_settings`
|
||||
(
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`key` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`value` TEXT NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `key` (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
|
||||
|
||||
CREATE TABLE `myaac_spells`
|
||||
(
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
@@ -330,6 +341,7 @@ CREATE TABLE `myaac_visitors`
|
||||
`ip` VARCHAR(45) NOT NULL,
|
||||
`lastvisit` INT(11) NOT NULL DEFAULT 0,
|
||||
`page` VARCHAR(2048) NOT NULL,
|
||||
`user_agent` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
UNIQUE (`ip`)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):<br/><br/><span class="console">chown -R www-data.www-data /var/www/*</span><br/><span class="console">chmod -R 660 system/cache</span>
|
||||
We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):<br/><br/><span class="console">chown -R www-data.www-data /var/www/*</span><br/><span class="console">chmod -R 760 system/cache</span>
|
||||
|
||||
<style type="text/css">
|
||||
.console {
|
||||
|
@@ -12,9 +12,7 @@ require SYSTEM . 'functions.php';
|
||||
require BASE . 'install/includes/functions.php';
|
||||
require BASE . 'install/includes/locale.php';
|
||||
require SYSTEM . 'clients.conf.php';
|
||||
|
||||
if(file_exists(BASE . 'config.local.php'))
|
||||
require BASE . 'config.local.php';
|
||||
require LIBS . 'settings.php';
|
||||
|
||||
// ignore undefined index from Twig autoloader
|
||||
$config['env'] = 'prod';
|
||||
@@ -26,13 +24,13 @@ $twig = new Twig_Environment($twig_loader, array(
|
||||
));
|
||||
|
||||
// load installation status
|
||||
$step = isset($_POST['step']) ? $_POST['step'] : 'welcome';
|
||||
$step = $_REQUEST['step'] ?? 'welcome';
|
||||
|
||||
$install_status = array();
|
||||
if(file_exists(CACHE . 'install.txt')) {
|
||||
$install_status = unserialize(file_get_contents(CACHE . 'install.txt'));
|
||||
|
||||
if(!isset($_POST['step'])) {
|
||||
if(!isset($_REQUEST['step'])) {
|
||||
$step = isset($install_status['step']) ? $install_status['step'] : '';
|
||||
}
|
||||
}
|
||||
@@ -70,7 +68,7 @@ if($step == 'database') {
|
||||
|
||||
$key = str_replace('var_', '', $key);
|
||||
|
||||
if(in_array($key, array('account', 'password', 'password_confirm', 'email', 'player_name'))) {
|
||||
if(in_array($key, array('account', 'account_id', 'password', 'password_confirm', 'email', 'player_name'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -91,10 +89,6 @@ if($step == 'database') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if($key == 'mail_admin' && !Validator::email($value)) {
|
||||
$errors[] = $locale['step_config_mail_admin_error'];
|
||||
break;
|
||||
}
|
||||
else if($key == 'timezone' && !in_array($value, DateTimeZone::listIdentifiers())) {
|
||||
$errors[] = $locale['step_config_timezone_error'];
|
||||
break;
|
||||
@@ -110,14 +104,12 @@ if($step == 'database') {
|
||||
}
|
||||
}
|
||||
else if($step == 'admin') {
|
||||
$config_failed = true;
|
||||
if(file_exists(BASE . 'config.local.php') && isset($config['installed']) && $config['installed'] && isset($_SESSION['saved'])) {
|
||||
$config_failed = false;
|
||||
}
|
||||
|
||||
if($config_failed) {
|
||||
if(!file_exists(BASE . 'config.local.php') || !isset($config['installed']) || !$config['installed']) {
|
||||
$step = 'database';
|
||||
}
|
||||
else {
|
||||
$_SESSION['saved'] = true;
|
||||
}
|
||||
}
|
||||
else if($step == 'finish') {
|
||||
$email = $_SESSION['var_email'];
|
||||
|
@@ -5,4 +5,3 @@ $twig->display('install.license.html.twig', array(
|
||||
'license' => file_get_contents(BASE . 'LICENSE'),
|
||||
'buttons' => next_buttons()
|
||||
));
|
||||
?>
|
||||
|
@@ -18,4 +18,3 @@ $twig->display('install.config.html.twig', array(
|
||||
'errors' => isset($errors) ? $errors : null,
|
||||
'buttons' => next_buttons()
|
||||
));
|
||||
?>
|
@@ -11,16 +11,12 @@ if(!isset($_SESSION['var_server_path'])) {
|
||||
}
|
||||
|
||||
if(!$error) {
|
||||
$content = "<?php";
|
||||
$content .= PHP_EOL;
|
||||
$content .= '// place for your configuration directives, so you can later easily update myaac';
|
||||
$content .= PHP_EOL;
|
||||
$content .= '$config[\'installed\'] = true;';
|
||||
$content .= PHP_EOL;
|
||||
$configToSave = [
|
||||
// by default, set env to prod
|
||||
// user can disable when he wants
|
||||
$content .= '$config[\'env\'] = \'prod\'; // dev or prod';
|
||||
$content .= PHP_EOL;
|
||||
'env' => 'prod',
|
||||
];
|
||||
|
||||
foreach($_SESSION as $key => $value)
|
||||
{
|
||||
if(strpos($key, 'var_') !== false)
|
||||
@@ -32,17 +28,14 @@ if(!$error) {
|
||||
$value .= '/';
|
||||
}
|
||||
|
||||
if($key === 'var_usage') {
|
||||
$content .= '$config[\'anonymous_usage_statistics\'] = ' . ((int)$value == 1 ? 'true' : 'false') . ';';
|
||||
$content .= PHP_EOL;
|
||||
}
|
||||
else if(!in_array($key, array('var_account', 'var_account_id', 'var_password', 'var_step', 'var_email', 'var_player_name'), true)) {
|
||||
$content .= '$config[\'' . str_replace('var_', '', $key) . '\'] = \'' . $value . '\';';
|
||||
$content .= PHP_EOL;
|
||||
if(!in_array($key, ['var_usage', 'var_date_timezone', 'var_client', 'var_account', 'var_account_id', 'var_password', 'var_password_confirm', 'var_step', 'var_email', 'var_player_name'], true)) {
|
||||
$configToSave[str_replace('var_', '', $key)] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true);
|
||||
|
||||
require BASE . 'install/includes/config.php';
|
||||
|
||||
if(!$error) {
|
||||
@@ -55,38 +48,42 @@ if(!$error) {
|
||||
error($database_error);
|
||||
}
|
||||
else {
|
||||
if(!$db->hasTable('accounts')) {
|
||||
$tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
|
||||
error($tmp);
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if(!$db->hasTable('players')) {
|
||||
$tmp = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
|
||||
error($tmp);
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if(!$db->hasTable('guilds')) {
|
||||
$tmp = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
|
||||
error($tmp);
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if(!$error) {
|
||||
$twig->display('install.installer.html.twig', array(
|
||||
'url' => 'tools/5-database.php',
|
||||
'message' => $locale['loading_spinner']
|
||||
));
|
||||
|
||||
if(!$error) {
|
||||
if(!Validator::email($_SESSION['var_mail_admin'])) {
|
||||
error($locale['step_config_mail_admin_error']);
|
||||
$error = true;
|
||||
}
|
||||
|
||||
$content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
|
||||
$content .= PHP_EOL;
|
||||
$content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
|
||||
|
||||
$saved = true;
|
||||
if(!$error) {
|
||||
$saved = file_put_contents(BASE . 'config.local.php', $content);
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content);
|
||||
if($saved) {
|
||||
success($locale['step_database_config_saved']);
|
||||
if(!$error) {
|
||||
$_SESSION['saved'] = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$_SESSION['config_content'] = $content;
|
||||
unset($_SESSION['saved']);
|
||||
|
||||
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
|
||||
warning($locale['step_database_error_file'] . '<br/>
|
||||
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.php</b>', $locale['step_database_error_file']);
|
||||
error($locale['step_database_error_file'] . '<br/>
|
||||
<textarea cols="70" rows="10">' . $content . '</textarea>');
|
||||
}
|
||||
}
|
||||
@@ -98,7 +95,7 @@ if(!$error) {
|
||||
<div class="text-center m-3">
|
||||
<form action="<?php echo BASE_URL; ?>install/" method="post">
|
||||
<input type="hidden" name="step" id="step" value="admin" />
|
||||
<?php echo next_buttons(true, $error ? false : true);
|
||||
<?php echo next_buttons(true, !$error);
|
||||
?>
|
||||
</form>
|
||||
</div>
|
@@ -8,7 +8,7 @@ if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['save
|
||||
else {
|
||||
require SYSTEM . 'init.php';
|
||||
if(!$error) {
|
||||
if(USE_ACCOUNT_NAME)
|
||||
if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER)
|
||||
$account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null;
|
||||
else
|
||||
$account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null;
|
||||
@@ -65,7 +65,6 @@ else {
|
||||
$new_account->setPassword(encrypt($password));
|
||||
$new_account->setEMail($email);
|
||||
|
||||
$new_account->unblock();
|
||||
$new_account->save();
|
||||
|
||||
$new_account->setCustomField('created', time());
|
||||
@@ -117,12 +116,30 @@ else {
|
||||
}
|
||||
}
|
||||
|
||||
$settings = Settings::getInstance();
|
||||
foreach($_SESSION as $key => $value) {
|
||||
if (in_array($key, ['var_usage', 'var_date_timezone', 'var_client'])) {
|
||||
if ($key == 'var_usage') {
|
||||
$key = 'anonymous_usage_statistics';
|
||||
$value = ((int)$value == 1 ? 'true' : 'false');
|
||||
} elseif ($key == 'var_date_timezone') {
|
||||
$key = 'date_timezone';
|
||||
} elseif ($key == 'var_client') {
|
||||
$key = 'client';
|
||||
}
|
||||
|
||||
$settings->updateInDatabase('core', $key, $value);
|
||||
}
|
||||
}
|
||||
success('Settings saved.');
|
||||
|
||||
$twig->display('install.installer.html.twig', array(
|
||||
'url' => 'tools/7-finish.php',
|
||||
'message' => $locale['importing_spinner']
|
||||
));
|
||||
|
||||
if(!isset($_SESSION['installed'])) {
|
||||
if (!array_key_exists('CI', getenv())) {
|
||||
$report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL);
|
||||
if (function_exists('curl_version'))
|
||||
{
|
||||
@@ -135,6 +152,8 @@ else {
|
||||
else if (ini_get('allow_url_fopen') ) {
|
||||
file_get_contents($report_url);
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION['installed'] = true;
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>MyAAC - <?php echo $locale['installation']; ?></title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
||||
<link rel="stylesheet" type="text/css" href="template/style.css" />
|
||||
<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/js/jquery.min.js"></script>
|
||||
</head>
|
||||
@@ -29,7 +29,7 @@
|
||||
$progress = ($i == 6) ? 100 : $i * 16;
|
||||
}
|
||||
|
||||
echo '<li' . ($step == $value ? ' class="list-group-item active"' : ' class="list-group-item"') . '>' . ++$i . '. ' . $locale['step_' . $value] . '</li>';
|
||||
echo '<li class="list-group-item' . ($step == $value ? ' active' : '') . '">' . ++$i . '. ' . $locale['step_' . $value] . '</li>';
|
||||
}
|
||||
|
||||
?>
|
||||
|
@@ -23,24 +23,6 @@ if(!$error) {
|
||||
}
|
||||
}
|
||||
|
||||
if(!$db->hasTable('accounts')) {
|
||||
$locale['step_database_error_table'] = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
|
||||
error($locale['step_database_error_table']);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$db->hasTable('players')) {
|
||||
$locale['step_database_error_table'] = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
|
||||
error($locale['step_database_error_table']);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$db->hasTable('guilds')) {
|
||||
$locale['step_database_error_table'] = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
|
||||
error($locale['step_database_error_table']);
|
||||
return;
|
||||
}
|
||||
|
||||
if($db->hasTable(TABLE_PREFIX . 'account_actions')) {
|
||||
$locale['step_database_error_table_exist'] = str_replace('$TABLE$', TABLE_PREFIX . 'account_actions', $locale['step_database_error_table_exist']);
|
||||
warning($locale['step_database_error_table_exist']);
|
||||
@@ -73,13 +55,8 @@ else {
|
||||
success($locale['step_database_adding_field'] . ' accounts.key...');
|
||||
}
|
||||
|
||||
if(!$db->hasColumn('accounts', 'blocked')) {
|
||||
if(query("ALTER TABLE `accounts` ADD `blocked` TINYINT(1) NOT NULL DEFAULT FALSE COMMENT 'internal usage' AFTER `key`;"))
|
||||
success($locale['step_database_adding_field'] . ' accounts.blocked...');
|
||||
}
|
||||
|
||||
if(!$db->hasColumn('accounts', 'created')) {
|
||||
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'blocked') . "`;"))
|
||||
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'key') . "`;"))
|
||||
success($locale['step_database_adding_field'] . ' accounts.created...');
|
||||
}
|
||||
|
||||
|
@@ -11,11 +11,11 @@ ini_set('max_execution_time', 300);
|
||||
ob_implicit_flush();
|
||||
ob_end_flush();
|
||||
header('X-Accel-Buffering: no');
|
||||
|
||||
/*
|
||||
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
|
||||
warning($locale['already_installed']);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
require SYSTEM . 'init.php';
|
||||
|
||||
@@ -51,13 +51,6 @@ DataLoader::load();
|
||||
|
||||
// update config.highscores_ids_hidden
|
||||
require_once SYSTEM . 'migrations/20.php';
|
||||
$database_migration_20 = true;
|
||||
$content = '';
|
||||
if(!databaseMigration20($content)) {
|
||||
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
|
||||
warning($locale['step_database_error_file'] . '<br/>
|
||||
<textarea cols="70" rows="10">' . $content . '</textarea>');
|
||||
}
|
||||
|
||||
// add z_polls tables
|
||||
require_once SYSTEM . 'migrations/22.php';
|
||||
|
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
require_once 'common.php';
|
||||
require_once 'config.php';
|
||||
require_once 'config.local.php';
|
||||
require_once SYSTEM . 'functions.php';
|
||||
require_once SYSTEM . 'init.php';
|
||||
require_once SYSTEM . 'status.php';
|
||||
|
@@ -7,6 +7,23 @@ server {
|
||||
# increase max file upload
|
||||
client_max_body_size 10M;
|
||||
|
||||
# this is very important, be sure its in your nginx conf - it prevents access to logs etc.
|
||||
location ~ /system {
|
||||
deny all;
|
||||
return 404;
|
||||
}
|
||||
|
||||
# block .htaccess
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# block git files and folders
|
||||
location ~ /\.git {
|
||||
return 404;
|
||||
deny all;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php;
|
||||
}
|
||||
@@ -15,15 +32,6 @@ server {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_read_timeout 240;
|
||||
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
# for ubuntu 22.04+ it will be php8.1-sock
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location /system {
|
||||
deny all;
|
||||
return 404;
|
||||
# for ubuntu 22.04+ it will be php8.1-fpm.sock
|
||||
}
|
||||
}
|
||||
|
1927
package-lock.json
generated
Normal file
1927
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
package.json
Normal file
5
package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"cypress": "^12.12.0"
|
||||
}
|
||||
}
|
@@ -1,11 +1,3 @@
|
||||
<IfModule mod_autoindex.c>
|
||||
Options -Indexes
|
||||
</IfModule>
|
||||
|
||||
<IfVersion < 2.4>
|
||||
order allow,deny
|
||||
deny from all
|
||||
</IfVersion>
|
||||
<IfVersion >= 2.4>
|
||||
Require all denied
|
||||
</IfVersion>
|
||||
|
@@ -1,3 +1,3 @@
|
||||
To play on {{ config.lua.serverName }} you need an account.
|
||||
All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if config.recaptcha_enabled %}, confirm reCAPTCHA{% endif %}{% if config.account_country %}, country{% endif %} and your email address.
|
||||
All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if config.account_country %}, country{% endif %} and your email address.
|
||||
Also you have to agree to the terms presented below. If you have done so, your account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %} will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.<br/><br/>
|
||||
|
@@ -39,5 +39,6 @@
|
||||
"redirect_from": "/redirectExample",
|
||||
"redirect_to": "account/manage"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": "plugins/your-plugin-folder/settings.php"
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ if [ $1 = "prepare" ]; then
|
||||
mkdir -p tmp
|
||||
|
||||
# get myaac from git archive
|
||||
git archive --format zip --output tmp/myaac.zip master
|
||||
git archive --format zip --output tmp/myaac.zip develop
|
||||
|
||||
cd tmp/ || exit
|
||||
|
||||
@@ -35,6 +35,11 @@ if [ $1 = "prepare" ]; then
|
||||
unzip -q myaac.zip -d $dir
|
||||
rm myaac.zip
|
||||
|
||||
cd $dir || exit
|
||||
|
||||
# dependencies
|
||||
composer install --no-dev
|
||||
|
||||
echo "Now you can make changes to $dir. When you are ready, type 'release.sh pack'"
|
||||
exit
|
||||
fi
|
||||
|
@@ -1,206 +0,0 @@
|
||||
<?php
|
||||
namespace MyAAC;
|
||||
|
||||
$loader = new \MyAAC\Psr4AutoloaderClass;
|
||||
|
||||
// register the autoloader
|
||||
$loader->register();
|
||||
|
||||
// register the base directories for the namespace prefix
|
||||
$loader->addNamespace('Composer\Semver', LIBS . 'semver');
|
||||
$loader->addNamespace('Twig', LIBS . 'Twig');
|
||||
/**
|
||||
* An example of a general-purpose implementation that includes the optional
|
||||
* functionality of allowing multiple base directories for a single namespace
|
||||
* prefix.
|
||||
*
|
||||
* Given a foo-bar package of classes in the file system at the following
|
||||
* paths ...
|
||||
*
|
||||
* /path/to/packages/foo-bar/
|
||||
* src/
|
||||
* Baz.php # Foo\Bar\Baz
|
||||
* Qux/
|
||||
* Quux.php # Foo\Bar\Qux\Quux
|
||||
* tests/
|
||||
* BazTest.php # Foo\Bar\BazTest
|
||||
* Qux/
|
||||
* QuuxTest.php # Foo\Bar\Qux\QuuxTest
|
||||
*
|
||||
* ... add the path to the class files for the \Foo\Bar\ namespace prefix
|
||||
* as follows:
|
||||
*
|
||||
* <?php
|
||||
* // instantiate the loader
|
||||
* $loader = new \Example\Psr4AutoloaderClass;
|
||||
*
|
||||
* // register the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // register the base directories for the namespace prefix
|
||||
* $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
|
||||
* $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
|
||||
*
|
||||
* The following line would cause the autoloader to attempt to load the
|
||||
* \Foo\Bar\Qux\Quux class from /path/to/packages/foo-bar/src/Qux/Quux.php:
|
||||
*
|
||||
* <?php
|
||||
* new \Foo\Bar\Qux\Quux;
|
||||
*
|
||||
* The following line would cause the autoloader to attempt to load the
|
||||
* \Foo\Bar\Qux\QuuxTest class from /path/to/packages/foo-bar/tests/Qux/QuuxTest.php:
|
||||
*
|
||||
* <?php
|
||||
* new \Foo\Bar\Qux\QuuxTest;
|
||||
*/
|
||||
class Psr4AutoloaderClass
|
||||
{
|
||||
/**
|
||||
* An associative array where the key is a namespace prefix and the value
|
||||
* is an array of base directories for classes in that namespace.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $prefixes = array();
|
||||
|
||||
/**
|
||||
* Register loader with SPL autoloader stack.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a base directory for a namespace prefix.
|
||||
*
|
||||
* @param string $prefix The namespace prefix.
|
||||
* @param string $base_dir A base directory for class files in the
|
||||
* namespace.
|
||||
* @param bool $prepend If true, prepend the base directory to the stack
|
||||
* instead of appending it; this causes it to be searched first rather
|
||||
* than last.
|
||||
* @return void
|
||||
*/
|
||||
public function addNamespace($prefix, $base_dir, $prepend = false)
|
||||
{
|
||||
// normalize namespace prefix
|
||||
$prefix = trim($prefix, '\\') . '\\';
|
||||
|
||||
// normalize the base directory with a trailing separator
|
||||
$base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';
|
||||
|
||||
// initialize the namespace prefix array
|
||||
if (isset($this->prefixes[$prefix]) === false) {
|
||||
$this->prefixes[$prefix] = array();
|
||||
}
|
||||
|
||||
// retain the base directory for the namespace prefix
|
||||
if ($prepend) {
|
||||
array_unshift($this->prefixes[$prefix], $base_dir);
|
||||
} else {
|
||||
array_push($this->prefixes[$prefix], $base_dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the class file for a given class name.
|
||||
*
|
||||
* @param string $class The fully-qualified class name.
|
||||
* @return mixed The mapped file name on success, or boolean false on
|
||||
* failure.
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if (0 === strpos($class, 'Twig_')) {
|
||||
$file = LIBS . 'Twig/' . str_replace(array('_', "\0"), array('/', ''), $class).'.php';
|
||||
|
||||
if((config('env') === 'dev') && !is_file($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
require $file;
|
||||
return false;
|
||||
}
|
||||
|
||||
// the current namespace prefix
|
||||
$prefix = $class;
|
||||
|
||||
// work backwards through the namespace names of the fully-qualified
|
||||
// class name to find a mapped file name
|
||||
while (false !== $pos = strrpos($prefix, '\\')) {
|
||||
|
||||
// retain the trailing namespace separator in the prefix
|
||||
$prefix = substr($class, 0, $pos + 1);
|
||||
|
||||
// the rest is the relative class name
|
||||
$relative_class = substr($class, $pos + 1);
|
||||
|
||||
// try to load a mapped file for the prefix and relative class
|
||||
$mapped_file = $this->loadMappedFile($prefix, $relative_class);
|
||||
if ($mapped_file) {
|
||||
return $mapped_file;
|
||||
}
|
||||
|
||||
// remove the trailing namespace separator for the next iteration
|
||||
// of strrpos()
|
||||
$prefix = rtrim($prefix, '\\');
|
||||
}
|
||||
|
||||
// never found a mapped file
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the mapped file for a namespace prefix and relative class.
|
||||
*
|
||||
* @param string $prefix The namespace prefix.
|
||||
* @param string $relative_class The relative class name.
|
||||
* @return mixed Boolean false if no mapped file can be loaded, or the
|
||||
* name of the mapped file that was loaded.
|
||||
*/
|
||||
protected function loadMappedFile($prefix, $relative_class)
|
||||
{
|
||||
// are there any base directories for this namespace prefix?
|
||||
if (isset($this->prefixes[$prefix]) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// look through base directories for this namespace prefix
|
||||
foreach ($this->prefixes[$prefix] as $base_dir) {
|
||||
|
||||
// replace the namespace prefix with the base directory,
|
||||
// replace namespace separators with directory separators
|
||||
// in the relative class name, append with .php
|
||||
$file = $base_dir
|
||||
. str_replace('\\', '/', $relative_class)
|
||||
. '.php';
|
||||
|
||||
// if the mapped file exists, require it
|
||||
if ($this->requireFile($file)) {
|
||||
// yes, we're done
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// never found it
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a file exists, require it from the file system.
|
||||
*
|
||||
* @param string $file The file to require.
|
||||
* @return bool True if the file exists, false if not.
|
||||
*/
|
||||
protected function requireFile($file)
|
||||
{
|
||||
if (config('env') !== 'dev' || file_exists($file)) {
|
||||
require $file;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -9,7 +9,30 @@
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
class Player extends OTS_Player {}
|
||||
class Guild extends OTS_Guild {}
|
||||
class Account extends OTS_Account {
|
||||
public function loadById($id) {
|
||||
$this->load($id);
|
||||
}
|
||||
public function loadByName($name) {
|
||||
$this->find($name);
|
||||
}
|
||||
}
|
||||
|
||||
class Player extends OTS_Player {
|
||||
public function loadById($id) {
|
||||
$this->load($id);
|
||||
}
|
||||
public function loadByName($name) {
|
||||
$this->find($name);
|
||||
}
|
||||
}
|
||||
class Guild extends OTS_Guild {
|
||||
public function loadById($id) {
|
||||
$this->load($id);
|
||||
}
|
||||
public function loadByName($name) {
|
||||
$this->find($name);
|
||||
}
|
||||
}
|
||||
class GuildRank extends OTS_GuildRank {}
|
||||
class House extends OTS_House {}
|
||||
|
103
system/compat/config.php
Normal file
103
system/compat/config.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
$deprecatedConfig = [
|
||||
'date_timezone',
|
||||
'genders',
|
||||
'template',
|
||||
'template_allow_change',
|
||||
'vocations_amount',
|
||||
'vocations',
|
||||
'client',
|
||||
'session_prefix',
|
||||
'friendly_urls',
|
||||
'backward_support',
|
||||
'charset',
|
||||
'meta_description',
|
||||
'meta_keywords',
|
||||
'footer',
|
||||
'database_encryption' => 'database_hash',
|
||||
//'language',
|
||||
'visitors_counter',
|
||||
'visitors_counter_ttl',
|
||||
'views_counter',
|
||||
'outfit_images_url',
|
||||
'outfit_images_wrong_looktypes',
|
||||
'item_images_url',
|
||||
'account_country',
|
||||
'towns',
|
||||
'quests',
|
||||
'character_samples',
|
||||
'character_towns',
|
||||
'characters_per_account',
|
||||
'characters_search_limit',
|
||||
'news_author',
|
||||
'news_limit',
|
||||
'news_ticker_limit',
|
||||
'news_date_format',
|
||||
'highscores_groups_hidden',
|
||||
'highscores_ids_hidden',
|
||||
'online_record',
|
||||
'online_vocations',
|
||||
'online_vocations_images',
|
||||
'online_skulls',
|
||||
'online_outfit',
|
||||
'online_afk',
|
||||
'team_display_outfit' => 'team_outfit',
|
||||
'team_display_status' => 'team_status',
|
||||
'team_display_world' => 'team_world',
|
||||
'team_display_lastlogin' => 'team_lastlogin',
|
||||
'last_kills_limit',
|
||||
'multiworld',
|
||||
'forum',
|
||||
'signature_enabled',
|
||||
'signature_type',
|
||||
'signature_cache_time',
|
||||
'signature_browser_cache',
|
||||
'gifts_system',
|
||||
'status_enabled',
|
||||
'status_ip',
|
||||
'status_port',
|
||||
'mail_enabled',
|
||||
'account_login_by_email',
|
||||
'account_login_by_email_fallback',
|
||||
'account_mail_verify',
|
||||
'account_create_character_create',
|
||||
'account_change_character_name',
|
||||
'account_change_character_name_points' => 'account_change_character_name_price',
|
||||
'account_change_character_sex',
|
||||
'account_change_character_sex_points' => 'account_change_character_name_price',
|
||||
];
|
||||
|
||||
foreach ($deprecatedConfig as $key => $value) {
|
||||
config(
|
||||
[
|
||||
(is_string($key) ? $key : $value),
|
||||
setting('core.'.$value)
|
||||
]
|
||||
);
|
||||
|
||||
//var_dump($settings['core.'.$value]['value']);
|
||||
}
|
||||
|
||||
$deprecatedConfigCharacters = [
|
||||
'level',
|
||||
'experience',
|
||||
'magic_level',
|
||||
'balance',
|
||||
'marriage_info' => 'marriage',
|
||||
'outfit',
|
||||
'creation_date',
|
||||
'quests',
|
||||
'skills',
|
||||
'equipment',
|
||||
'frags',
|
||||
'deleted',
|
||||
];
|
||||
|
||||
$tmp = [];
|
||||
foreach ($deprecatedConfigCharacters as $key => $value) {
|
||||
$tmp[(is_string($key) ? $key : $value)] = setting('core.characters_'.$value);
|
||||
}
|
||||
|
||||
config(['characters', $tmp]);
|
||||
unset($tmp);
|
@@ -10,6 +10,10 @@
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
switch($page)
|
||||
{
|
||||
case 'adminpanel':
|
||||
header('Location: ' . ADMIN_URL);
|
||||
die;
|
||||
|
||||
case 'createaccount':
|
||||
$page = 'account/create';
|
||||
break;
|
||||
@@ -30,6 +34,7 @@ switch($page)
|
||||
$page = 'news';
|
||||
break;
|
||||
|
||||
case 'archive':
|
||||
case 'newsarchive':
|
||||
$page = 'news/archive';
|
||||
break;
|
||||
|
@@ -51,4 +51,3 @@ else
|
||||
updateDatabaseConfig('views_counter', $views_counter); // update counter
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@@ -9,7 +9,11 @@
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
if(!isset($config['database_user'][0], $config['database_password'][0], $config['database_name'][0]))
|
||||
if (!isset($config['database_overwrite'])) {
|
||||
$config['database_overwrite'] = false;
|
||||
}
|
||||
|
||||
if(!$config['database_overwrite'] && !isset($config['database_user'][0], $config['database_password'][0], $config['database_name'][0]))
|
||||
{
|
||||
if(isset($config['lua']['sqlType'])) {// tfs 0.3
|
||||
if(isset($config['lua']['mysqlHost'])) {// tfs 0.2
|
||||
|
@@ -1,4 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception handler
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2023 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
|
||||
if (class_exists(\Whoops\Run::class)) {
|
||||
$whoops = new \Whoops\Run;
|
||||
if(IS_CLI) {
|
||||
$whoops->pushHandler(new \Whoops\Handler\PlainTextHandler);
|
||||
}
|
||||
else {
|
||||
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
|
||||
}
|
||||
|
||||
$whoops->register();
|
||||
return;
|
||||
}
|
||||
|
||||
require LIBS . 'SensitiveException.php';
|
||||
|
||||
@@ -23,6 +44,8 @@ function exception_handler($exception) {
|
||||
|
||||
$backtrace_formatted = nl2br($exception->getTraceAsString());
|
||||
|
||||
$message = $message . "<br/><br/>File: {$exception->getFile()}<br/>Line: {$exception->getLine()}";
|
||||
|
||||
// display basic error message without template
|
||||
// template is missing, why? probably someone deleted templates dir, or it wasn't downloaded right
|
||||
$template_file = SYSTEM . 'templates/exception.html.twig';
|
||||
|
@@ -7,12 +7,11 @@
|
||||
* @copyright 2019 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use Twig\Loader\ArrayLoader as Twig_ArrayLoader;
|
||||
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
function message($message, $type, $return)
|
||||
{
|
||||
if(IS_CLI) {
|
||||
@@ -45,43 +44,37 @@ function error($message, $return = false) {
|
||||
return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return);
|
||||
}
|
||||
|
||||
function longToIp($ip)
|
||||
function longToIp($ip): string
|
||||
{
|
||||
$exp = explode(".", long2ip($ip));
|
||||
return $exp[3].".".$exp[2].".".$exp[1].".".$exp[0];
|
||||
}
|
||||
|
||||
function generateLink($url, $name, $blank = false) {
|
||||
function generateLink($url, $name, $blank = false): string {
|
||||
return '<a href="' . $url . '"' . ($blank ? ' target="_blank"' : '') . '>' . $name . '</a>';
|
||||
}
|
||||
|
||||
function getFullLink($page, $name, $blank = false) {
|
||||
function getFullLink($page, $name, $blank = false): string {
|
||||
return generateLink(getLink($page), $name, $blank);
|
||||
}
|
||||
|
||||
function getLink($page, $action = null)
|
||||
{
|
||||
global $config;
|
||||
return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . $page . ($action ? '/' . $action : '');
|
||||
function getLink($page, $action = null): string {
|
||||
return BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . $page . ($action ? '/' . $action : '');
|
||||
}
|
||||
function internalLayoutLink($page, $action = null) {return getLink($page, $action);}
|
||||
|
||||
function getForumThreadLink($thread_id, $page = NULL)
|
||||
{
|
||||
global $config;
|
||||
return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'forum/thread/' . (int)$thread_id . (isset($page) ? '/' . $page : '');
|
||||
function internalLayoutLink($page, $action = null): string {
|
||||
return getLink($page, $action);
|
||||
}
|
||||
|
||||
function getForumBoardLink($board_id, $page = NULL)
|
||||
{
|
||||
global $config;
|
||||
return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'forum/board/' . (int)$board_id . (isset($page) ? '/' . $page : '');
|
||||
function getForumThreadLink($thread_id, $page = NULL): string {
|
||||
return BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'forum/thread/' . (int)$thread_id . (isset($page) ? '/' . $page : '');
|
||||
}
|
||||
|
||||
function getPlayerLink($name, $generate = true)
|
||||
{
|
||||
global $config;
|
||||
function getForumBoardLink($board_id, $page = NULL): string {
|
||||
return BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'forum/board/' . (int)$board_id . (isset($page) ? '/' . $page : '');
|
||||
}
|
||||
|
||||
function getPlayerLink($name, $generate = true): string
|
||||
{
|
||||
if(is_numeric($name))
|
||||
{
|
||||
$player = new OTS_Player();
|
||||
@@ -90,25 +83,23 @@ function getPlayerLink($name, $generate = true)
|
||||
$name = $player->getName();
|
||||
}
|
||||
|
||||
$url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'characters/' . urlencode($name);
|
||||
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'characters/' . urlencode($name);
|
||||
|
||||
if(!$generate) return $url;
|
||||
return generateLink($url, $name);
|
||||
}
|
||||
|
||||
function getMonsterLink($name, $generate = true)
|
||||
function getMonsterLink($name, $generate = true): string
|
||||
{
|
||||
global $config;
|
||||
|
||||
$url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'creatures/' . urlencode($name);
|
||||
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'creatures/' . urlencode($name);
|
||||
|
||||
if(!$generate) return $url;
|
||||
return generateLink($url, $name);
|
||||
}
|
||||
|
||||
function getHouseLink($name, $generate = true)
|
||||
function getHouseLink($name, $generate = true): string
|
||||
{
|
||||
global $db, $config;
|
||||
global $db;
|
||||
|
||||
if(is_numeric($name))
|
||||
{
|
||||
@@ -118,25 +109,22 @@ function getHouseLink($name, $generate = true)
|
||||
$name = $house->fetchColumn();
|
||||
}
|
||||
|
||||
$url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'houses/' . urlencode($name);
|
||||
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses/' . urlencode($name);
|
||||
|
||||
if(!$generate) return $url;
|
||||
return generateLink($url, $name);
|
||||
}
|
||||
|
||||
function getGuildLink($name, $generate = true)
|
||||
function getGuildLink($name, $generate = true): string
|
||||
{
|
||||
global $db, $config;
|
||||
|
||||
if(is_numeric($name))
|
||||
{
|
||||
$guild = $db->query(
|
||||
'SELECT `name` FROM `guilds` WHERE `id` = ' . (int)$name);
|
||||
if($guild->rowCount() > 0)
|
||||
$name = $guild->fetchColumn();
|
||||
if(is_numeric($name)) {
|
||||
$name = getGuildNameById($name);
|
||||
if ($name === false) {
|
||||
$name = 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
$url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'guilds/' . urlencode($name);
|
||||
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'guilds/' . urlencode($name);
|
||||
|
||||
if(!$generate) return $url;
|
||||
return generateLink($url, $name);
|
||||
@@ -182,7 +170,7 @@ function getItemRarity($chance) {
|
||||
return '';
|
||||
}
|
||||
|
||||
function getFlagImage($country)
|
||||
function getFlagImage($country): string
|
||||
{
|
||||
if(!isset($country[0]))
|
||||
return '';
|
||||
@@ -204,7 +192,7 @@ function getFlagImage($country)
|
||||
* @param mixed $v Variable to check.
|
||||
* @return bool Value boolean status.
|
||||
*/
|
||||
function getBoolean($v)
|
||||
function getBoolean($v): bool
|
||||
{
|
||||
if(is_bool($v)) {
|
||||
return $v;
|
||||
@@ -227,7 +215,7 @@ function getBoolean($v)
|
||||
* @param bool $special Should special characters by used?
|
||||
* @return string Generated string.
|
||||
*/
|
||||
function generateRandomString($length, $lowCase = true, $upCase = false, $numeric = false, $special = false)
|
||||
function generateRandomString($length, $lowCase = true, $upCase = false, $numeric = false, $special = false): string
|
||||
{
|
||||
$characters = '';
|
||||
if($lowCase)
|
||||
@@ -467,7 +455,7 @@ function tickers()
|
||||
* Types: head_start, head_end, body_start, body_end, center_top
|
||||
*
|
||||
*/
|
||||
function template_place_holder($type)
|
||||
function template_place_holder($type): string
|
||||
{
|
||||
global $twig, $template_place_holders;
|
||||
$ret = '';
|
||||
@@ -491,7 +479,7 @@ function template_place_holder($type)
|
||||
/**
|
||||
* Returns <head> content to be used by templates.
|
||||
*/
|
||||
function template_header($is_admin = false)
|
||||
function template_header($is_admin = false): string
|
||||
{
|
||||
global $title_full, $config, $twig;
|
||||
$charset = isset($config['charset']) ? $config['charset'] : 'utf-8';
|
||||
@@ -508,29 +496,32 @@ function template_header($is_admin = false)
|
||||
/**
|
||||
* Returns footer content to be used by templates.
|
||||
*/
|
||||
function template_footer()
|
||||
function template_footer(): string
|
||||
{
|
||||
global $config, $views_counter;
|
||||
global $views_counter;
|
||||
$ret = '';
|
||||
if(admin())
|
||||
if(admin()) {
|
||||
$ret .= generateLink(ADMIN_URL, 'Admin Panel', true);
|
||||
}
|
||||
|
||||
if($config['visitors_counter'])
|
||||
{
|
||||
if(setting('core.visitors_counter')) {
|
||||
global $visitors;
|
||||
$amount = $visitors->getAmountVisitors();
|
||||
$ret .= '<br/>Currently there ' . ($amount > 1 ? 'are' : 'is') . ' ' . $amount . ' visitor' . ($amount > 1 ? 's' : '') . '.';
|
||||
}
|
||||
|
||||
if($config['views_counter'])
|
||||
if(setting('core.views_counter')) {
|
||||
$ret .= '<br/>Page has been viewed ' . $views_counter . ' times.';
|
||||
}
|
||||
|
||||
if(config('footer_show_load_time')) {
|
||||
if(setting('core.footer_load_time')) {
|
||||
$ret .= '<br/>Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.';
|
||||
}
|
||||
|
||||
if(isset($config['footer'][0]))
|
||||
$ret .= '<br/>' . $config['footer'];
|
||||
$settingFooter = setting('core.footer');
|
||||
if(isset($settingFooter[0])) {
|
||||
$ret .= '<br/>' . $settingFooter;
|
||||
}
|
||||
|
||||
// please respect my work and help spreading the word, thanks!
|
||||
return $ret . '<br/>' . base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=');
|
||||
@@ -538,8 +529,8 @@ function template_footer()
|
||||
|
||||
function template_ga_code()
|
||||
{
|
||||
global $config, $twig;
|
||||
if(!isset($config['google_analytics_id'][0]))
|
||||
global $twig;
|
||||
if(!isset(setting('core.google_analytics_id')[0]))
|
||||
return '';
|
||||
|
||||
return $twig->render('google_analytics.html.twig');
|
||||
@@ -756,10 +747,10 @@ function get_browser_languages()
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
$acceptLang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
||||
if(!isset($acceptLang[0]))
|
||||
if(empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
|
||||
return $ret;
|
||||
|
||||
$acceptLang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
||||
$languages = strtolower($acceptLang);
|
||||
// $languages = 'pl,en-us;q=0.7,en;q=0.3 ';
|
||||
// need to remove spaces from strings to avoid error
|
||||
@@ -792,16 +783,21 @@ function get_templates()
|
||||
* Generates list of installed plugins
|
||||
* @return array $plugins
|
||||
*/
|
||||
function get_plugins()
|
||||
function get_plugins($disabled = false): array
|
||||
{
|
||||
$ret = array();
|
||||
$ret = [];
|
||||
|
||||
$path = PLUGINS;
|
||||
foreach(scandir($path, 0) as $file) {
|
||||
foreach(scandir($path, SCANDIR_SORT_ASCENDING) as $file) {
|
||||
$file_ext = pathinfo($file, PATHINFO_EXTENSION);
|
||||
$file_name = pathinfo($file, PATHINFO_FILENAME);
|
||||
if ($file === '.' || $file === '..' || $file === 'disabled' || $file === 'example.json' || $file_ext !== 'json' || is_dir($path . $file))
|
||||
if ($file === '.' || $file === '..' || $file === 'example.json' || $file_ext !== 'json' || is_dir($path . $file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$disabled && strpos($file, 'disabled.') !== false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ret[] = str_replace('.json', '', $file_name);
|
||||
}
|
||||
@@ -819,7 +815,7 @@ function getWorldName($id)
|
||||
|
||||
/**
|
||||
* Mailing users.
|
||||
* $config['mail_enabled'] have to be enabled.
|
||||
* Mailing has to be enabled in settings (in Admin Panel).
|
||||
*
|
||||
* @param string $to Recipient email address.
|
||||
* @param string $subject Subject of the message.
|
||||
@@ -831,8 +827,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
|
||||
{
|
||||
global $mailer, $config;
|
||||
|
||||
if (!config('mail_enabled')) {
|
||||
log_append('mailer-error.log', '_mail() function has been used, but config.mail_enabled is disabled.');
|
||||
if (!setting('core.mail_enabled')) {
|
||||
log_append('mailer-error.log', '_mail() function has been used, but Mail Support is disabled.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$mailer)
|
||||
@@ -844,47 +841,60 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
|
||||
$mailer->clearAllRecipients();
|
||||
}
|
||||
|
||||
$signature_html = '';
|
||||
if(isset($config['mail_signature']['html']))
|
||||
$signature_html = $config['mail_signature']['html'];
|
||||
|
||||
$signature_html = setting('core.mail_signature_html');
|
||||
if($add_html_tags && isset($body[0]))
|
||||
$tmp_body = '<html><head></head><body>' . $body . '<br/><br/>' . $signature_html . '</body></html>';
|
||||
else
|
||||
$tmp_body = $body . '<br/><br/>' . $signature_html;
|
||||
|
||||
if($config['smtp_enabled'])
|
||||
define('MAIL_MAIL', 0);
|
||||
define('MAIL_SMTP', 1);
|
||||
|
||||
$mailOption = setting('core.mail_option');
|
||||
if($mailOption == MAIL_SMTP)
|
||||
{
|
||||
$mailer->isSMTP();
|
||||
$mailer->Host = $config['smtp_host'];
|
||||
$mailer->Port = (int)$config['smtp_port'];
|
||||
$mailer->SMTPAuth = $config['smtp_auth'];
|
||||
$mailer->Username = $config['smtp_user'];
|
||||
$mailer->Password = $config['smtp_pass'];
|
||||
$mailer->SMTPSecure = isset($config['smtp_secure']) ? $config['smtp_secure'] : '';
|
||||
$mailer->Host = setting('core.smtp_host');
|
||||
$mailer->Port = setting('core.smtp_port');
|
||||
$mailer->SMTPAuth = setting('core.smtp_auth');
|
||||
$mailer->Username = setting('core.smtp_user');
|
||||
$mailer->Password = setting('core.smtp_pass');
|
||||
|
||||
define('SMTP_SECURITY_NONE', 0);
|
||||
define('SMTP_SECURITY_SSL', 1);
|
||||
define('SMTP_SECURITY_TLS', 2);
|
||||
|
||||
$security = setting('core.smtp_security');
|
||||
|
||||
$tmp = '';
|
||||
if ($security === SMTP_SECURITY_SSL) {
|
||||
$tmp = 'ssl';
|
||||
}
|
||||
else if ($security == SMTP_SECURITY_TLS) {
|
||||
$tmp = 'tls';
|
||||
}
|
||||
|
||||
$mailer->SMTPSecure = $tmp;
|
||||
}
|
||||
else {
|
||||
$mailer->isMail();
|
||||
}
|
||||
|
||||
$mailer->isHTML(isset($body[0]) > 0);
|
||||
$mailer->From = $config['mail_address'];
|
||||
$mailer->Sender = $config['mail_address'];
|
||||
$mailer->From = setting('core.mail_address');
|
||||
$mailer->Sender = setting('core.mail_address');
|
||||
$mailer->CharSet = 'utf-8';
|
||||
$mailer->FromName = $config['lua']['serverName'];
|
||||
$mailer->Subject = $subject;
|
||||
$mailer->addAddress($to);
|
||||
$mailer->Body = $tmp_body;
|
||||
|
||||
if(config('smtp_debug')) {
|
||||
if(setting('core.smtp_debug')) {
|
||||
$mailer->SMTPDebug = 2;
|
||||
$mailer->Debugoutput = 'echo';
|
||||
}
|
||||
|
||||
$signature_plain = '';
|
||||
if(isset($config['mail_signature']['plain']))
|
||||
$signature_plain = $config['mail_signature']['plain'];
|
||||
|
||||
$signature_plain = setting('core.mail_signature_plain');
|
||||
if(isset($altBody[0])) {
|
||||
$mailer->AltBody = $altBody . $signature_plain;
|
||||
}
|
||||
@@ -926,8 +936,8 @@ function load_config_lua($filename)
|
||||
$config_file = $filename;
|
||||
if(!@file_exists($config_file))
|
||||
{
|
||||
log_append('error.log', '[load_config_file] Fatal error: Cannot load config.lua (' . $filename . '). Error: ' . print_r(error_get_last(), true));
|
||||
throw new RuntimeException('ERROR: Cannot find ' . $filename . ' file. More info in system/logs/error.log');
|
||||
log_append('error.log', '[load_config_file] Fatal error: Cannot load config.lua (' . $filename . ').');
|
||||
throw new RuntimeException('ERROR: Cannot find ' . $filename . ' file.');
|
||||
}
|
||||
|
||||
$result = array();
|
||||
@@ -1044,7 +1054,7 @@ function getTopPlayers($limit = 5) {
|
||||
$deleted = 'deletion';
|
||||
|
||||
$is_tfs10 = $db->hasTable('players_online');
|
||||
$players = $db->query('SELECT `id`, `name`, `level`, `vocation`, `experience`, `looktype`' . ($db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `lookhead`, `lookbody`, `looklegs`, `lookfeet`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . config('highscores_groups_hidden') . ' AND `id` NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll();
|
||||
$players = $db->query('SELECT `id`, `name`, `level`, `vocation`, `experience`, `looktype`' . ($db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `lookhead`, `lookbody`, `looklegs`, `lookfeet`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . setting('core.highscores_groups_hidden') . ' AND `id` NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll();
|
||||
|
||||
if($is_tfs10) {
|
||||
foreach($players as &$player) {
|
||||
@@ -1097,6 +1107,9 @@ function deleteDirectory($dir, $ignore = array(), $contentOnly = false) {
|
||||
function config($key) {
|
||||
global $config;
|
||||
if (is_array($key)) {
|
||||
if (is_null($key[1])) {
|
||||
unset($config[$key[0]]);
|
||||
}
|
||||
return $config[$key[0]] = $key[1];
|
||||
}
|
||||
|
||||
@@ -1112,6 +1125,21 @@ function configLua($key) {
|
||||
return @$config['lua'][$key];
|
||||
}
|
||||
|
||||
function setting($key)
|
||||
{
|
||||
$settings = Settings::getInstance();
|
||||
|
||||
if (is_array($key)) {
|
||||
if (is_null($key[1])) {
|
||||
unset($settings[$key[0]]);
|
||||
}
|
||||
|
||||
return $settings[$key[0]] = $key[1];
|
||||
}
|
||||
|
||||
return $settings[$key]['value'];
|
||||
}
|
||||
|
||||
function clearCache()
|
||||
{
|
||||
require_once LIBS . 'news.php';
|
||||
@@ -1189,7 +1217,7 @@ function getCustomPageInfo($page)
|
||||
|
||||
return null;
|
||||
}
|
||||
function getCustomPage($page, &$success)
|
||||
function getCustomPage($page, &$success): string
|
||||
{
|
||||
global $db, $twig, $title, $ignore, $logged_access;
|
||||
|
||||
@@ -1480,8 +1508,8 @@ function right($str, $length) {
|
||||
}
|
||||
|
||||
function getCreatureImgPath($creature){
|
||||
$creature_path = config('creatures_images_url');
|
||||
$creature_gfx_name = trim(strtolower($creature)) . config('creatures_images_extension');
|
||||
$creature_path = config('monsters_images_url');
|
||||
$creature_gfx_name = trim(strtolower($creature)) . config('monsters_images_extension');
|
||||
if (!file_exists($creature_path . $creature_gfx_name)) {
|
||||
$creature_gfx_name = str_replace(" ", "", $creature_gfx_name);
|
||||
if (file_exists($creature_path . $creature_gfx_name)) {
|
||||
@@ -1544,6 +1572,47 @@ function escapeHtml($html) {
|
||||
return htmlentities($html, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
}
|
||||
|
||||
function getGuildNameById($id)
|
||||
{
|
||||
global $db;
|
||||
|
||||
$guild = $db->query('SELECT `name` FROM `guilds` WHERE `id` = ' . (int)$id);
|
||||
|
||||
if($guild->rowCount() > 0) {
|
||||
return $guild->fetchColumn();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getGuildLogoById($id)
|
||||
{
|
||||
global $db;
|
||||
|
||||
$logo = 'default.gif';
|
||||
|
||||
$query = $db->query('SELECT `logo_name` FROM `guilds` WHERE `id` = ' . (int)$id);
|
||||
if ($query->rowCount() == 1) {
|
||||
|
||||
$query = $query->fetch(PDO::FETCH_ASSOC);
|
||||
$guildLogo = $query['logo_name'];
|
||||
|
||||
if (!empty($guildLogo) && file_exists(GUILD_IMAGES_DIR . $guildLogo)) {
|
||||
$logo = $guildLogo;
|
||||
}
|
||||
}
|
||||
|
||||
return BASE_URL . GUILD_IMAGES_DIR . $logo;
|
||||
}
|
||||
|
||||
function displayErrorBoxWithBackButton($errors, $action = null) {
|
||||
global $twig;
|
||||
$twig->display('error_box.html.twig', ['errors' => $errors]);
|
||||
$twig->display('account.back_button.html.twig', [
|
||||
'action' => $action ?: getLink('')
|
||||
]);
|
||||
}
|
||||
|
||||
// validator functions
|
||||
require_once LIBS . 'validator.php';
|
||||
require_once SYSTEM . 'compat/base.php';
|
||||
|
@@ -30,6 +30,7 @@ define('HOOK_CHARACTERS_AFTER_CHARACTERS', ++$i);
|
||||
define('HOOK_LOGIN', ++$i);
|
||||
define('HOOK_LOGIN_ATTEMPT', ++$i);
|
||||
define('HOOK_LOGOUT', ++$i);
|
||||
define('HOOK_ACCOUNT_CHANGE_PASSWORD_POST', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BEFORE_FORM', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BEFORE_BOXES', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1', ++$i);
|
||||
@@ -39,8 +40,8 @@ define('HOOK_ACCOUNT_CREATE_BEFORE_ACCOUNT', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_ACCOUNT', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_EMAIL', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_COUNTRY', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_PASSWORD', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_PASSWORDS', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_RECAPTCHA', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BEFORE_CHARACTER_NAME', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_CHARACTER_NAME', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_SEX', ++$i);
|
||||
@@ -48,11 +49,34 @@ define('HOOK_ACCOUNT_CREATE_AFTER_VOCATION', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_TOWNS', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_BEFORE_SUBMIT_BUTTON', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_FORM', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_AFTER_SUBMIT', ++$i);
|
||||
define('HOOK_ACCOUNT_CREATE_POST', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_BEFORE_PAGE', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_BEFORE_ACCOUNT', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_AFTER_ACCOUNT', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_BEFORE_PASSWORD', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_AFTER_PASSWORD', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_AFTER_REMEMBER_ME', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_AFTER_PAGE', ++$i);
|
||||
define('HOOK_ACCOUNT_LOGIN_POST', ++$i);
|
||||
define('HOOK_ADMIN_HEAD_END', ++$i);
|
||||
define('HOOK_ADMIN_HEAD_START', ++$i);
|
||||
define('HOOK_ADMIN_BODY_START', ++$i);
|
||||
define('HOOK_ADMIN_BODY_END', ++$i);
|
||||
define('HOOK_ADMIN_BEFORE_PAGE', ++$i);
|
||||
define('HOOK_ADMIN_MENU', ++$i);
|
||||
define('HOOK_ADMIN_LOGIN_AFTER_ACCOUNT', ++$i);
|
||||
define('HOOK_ADMIN_LOGIN_AFTER_PASSWORD', ++$i);
|
||||
define('HOOK_ADMIN_LOGIN_AFTER_SIGN_IN', ++$i);
|
||||
define('HOOK_ADMIN_ACCOUNTS_SAVE_POST', ++$i);
|
||||
define('HOOK_EMAIL_CONFIRMED', ++$i);
|
||||
define('HOOK_FIRST', HOOK_STARTUP);
|
||||
define('HOOK_LAST', HOOK_EMAIL_CONFIRMED);
|
||||
define('HOOK_GUILDS_BEFORE_GUILD_HEADER', ++$i);
|
||||
define('HOOK_GUILDS_AFTER_GUILD_HEADER', ++$i);
|
||||
define('HOOK_GUILDS_AFTER_GUILD_INFORMATION', ++$i);
|
||||
define('HOOK_GUILDS_AFTER_GUILD_MEMBERS', ++$i);
|
||||
define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i);
|
||||
|
||||
const HOOK_FIRST = HOOK_STARTUP;
|
||||
define('HOOK_LAST', $i);
|
||||
|
||||
require_once LIBS . 'plugins.php';
|
||||
class Hook
|
||||
|
@@ -9,22 +9,24 @@
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
// load configuration
|
||||
require_once BASE . 'config.php';
|
||||
if(file_exists(BASE . 'config.local.php')) // user customizations
|
||||
require BASE . 'config.local.php';
|
||||
|
||||
if(!isset($config['installed']) || !$config['installed']) {
|
||||
throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.');
|
||||
}
|
||||
|
||||
date_default_timezone_set($config['date_timezone']);
|
||||
if(config('env') === 'dev') {
|
||||
require SYSTEM . 'exception.php';
|
||||
}
|
||||
|
||||
if(empty($config['server_path'])) {
|
||||
throw new RuntimeException('Server Path has been not set. Go to config.php and set it.');
|
||||
}
|
||||
|
||||
// take care of trailing slash at the end
|
||||
if($config['server_path'][strlen($config['server_path']) - 1] !== '/')
|
||||
$config['server_path'] .= '/';
|
||||
|
||||
// enable gzip compression if supported by the browser
|
||||
if($config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && function_exists('ob_gzhandler'))
|
||||
if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && function_exists('ob_gzhandler'))
|
||||
ob_start('ob_gzhandler');
|
||||
|
||||
// cache
|
||||
@@ -92,9 +94,6 @@ if(isset($config['lua']['servername']))
|
||||
if(isset($config['lua']['houserentperiod']))
|
||||
$config['lua']['houseRentPeriod'] = $config['lua']['houserentperiod'];
|
||||
|
||||
if($config['item_images_url'][strlen($config['item_images_url']) - 1] !== '/')
|
||||
$config['item_images_url'] .= '/';
|
||||
|
||||
// localize data/ directory based on data directory set in config.lua
|
||||
foreach(array('dataDirectory', 'data_directory', 'datadir') as $key) {
|
||||
if(!isset($config['lua'][$key][0])) {
|
||||
@@ -118,51 +117,34 @@ if(!isset($foundValue)) {
|
||||
$config['data_path'] = $foundValue;
|
||||
unset($foundValue);
|
||||
|
||||
// new config values for compability
|
||||
if(!isset($config['highscores_ids_hidden']) || count($config['highscores_ids_hidden']) == 0) {
|
||||
$config['highscores_ids_hidden'] = array(0);
|
||||
}
|
||||
|
||||
$config['account_create_character_create'] = config('account_create_character_create') && (!config('mail_enabled') || !config('account_mail_verify'));
|
||||
|
||||
// POT
|
||||
require_once SYSTEM . 'libs/pot/OTS.php';
|
||||
$ots = POT::getInstance();
|
||||
require_once SYSTEM . 'database.php';
|
||||
|
||||
// execute migrations
|
||||
require SYSTEM . 'migrate.php';
|
||||
|
||||
// settings
|
||||
require_once LIBS . 'Settings.php';
|
||||
$settings = Settings::getInstance();
|
||||
$settings->load();
|
||||
|
||||
// deprecated config values
|
||||
require_once SYSTEM . 'compat/config.php';
|
||||
|
||||
date_default_timezone_set(setting('core.date_timezone'));
|
||||
|
||||
$config['account_create_character_create'] = config('account_create_character_create') && (!setting('core.mail_enabled') || !config('account_mail_verify'));
|
||||
|
||||
$settingsItemImagesURL = setting('core.item_images_url');
|
||||
if($settingsItemImagesURL[strlen($settingsItemImagesURL) - 1] !== '/') {
|
||||
setting(['core.item_images_url', $settingsItemImagesURL . '/']);
|
||||
}
|
||||
|
||||
define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name'));
|
||||
define('USE_ACCOUNT_NUMBER', $db->hasColumn('accounts', 'number'));
|
||||
define('USE_ACCOUNT_SALT', $db->hasColumn('accounts', 'salt'));
|
||||
|
||||
// load vocation names
|
||||
$tmp = '';
|
||||
if($cache->enabled() && $cache->fetch('vocations', $tmp)) {
|
||||
$config['vocations'] = unserialize($tmp);
|
||||
}
|
||||
else {
|
||||
if(!class_exists('DOMDocument')) {
|
||||
throw new RuntimeException('Please install PHP xml extension. MyAAC will not work without it.');
|
||||
}
|
||||
|
||||
$vocations = new DOMDocument();
|
||||
$file = $config['data_path'] . 'XML/vocations.xml';
|
||||
if(!@file_exists($file))
|
||||
$file = $config['data_path'] . 'vocations.xml';
|
||||
|
||||
if(!$vocations->load($file))
|
||||
throw new RuntimeException('ERROR: Cannot load <i>vocations.xml</i> - the file is malformed. Check the file with xml syntax validator.');
|
||||
|
||||
$config['vocations'] = array();
|
||||
foreach($vocations->getElementsByTagName('vocation') as $vocation) {
|
||||
$id = $vocation->getAttribute('id');
|
||||
$config['vocations'][$id] = $vocation->getAttribute('name');
|
||||
}
|
||||
|
||||
if($cache->enabled()) {
|
||||
$cache->set('vocations', serialize($config['vocations']), 120);
|
||||
}
|
||||
}
|
||||
unset($tmp, $id, $vocation);
|
||||
|
||||
require LIBS . 'Towns.php';
|
||||
Towns::load();
|
||||
|
@@ -58,4 +58,3 @@ function outputItem($id = 100, $count = 1)
|
||||
$file_name = Items_Images::$outputDir . $file_name . '.gif';
|
||||
readfile($file_name);
|
||||
}
|
||||
?>
|
||||
|
@@ -18,8 +18,8 @@ class CreateCharacter
|
||||
*/
|
||||
public function checkName($name, &$errors)
|
||||
{
|
||||
$minLength = config('character_name_min_length');
|
||||
$maxLength = config('character_name_max_length');
|
||||
$minLength = setting('core.create_character_name_min_length');
|
||||
$maxLength = setting('core.create_character_name_max_length');
|
||||
|
||||
if(empty($name)) {
|
||||
$errors['name'] = 'Please enter a name for your character!';
|
||||
@@ -138,7 +138,7 @@ class CreateCharacter
|
||||
|
||||
if(empty($errors))
|
||||
{
|
||||
$number_of_players_on_account = $account->getPlayersList(false)->count();
|
||||
$number_of_players_on_account = $account->getPlayersList(true)->count();
|
||||
if($number_of_players_on_account >= config('characters_per_account'))
|
||||
$errors[] = 'You have too many characters on your account <b>('.$number_of_players_on_account.'/'.config('characters_per_account').')</b>!';
|
||||
}
|
||||
@@ -149,7 +149,7 @@ class CreateCharacter
|
||||
$char_to_copy = new OTS_Player();
|
||||
$char_to_copy->find($char_to_copy_name);
|
||||
if(!$char_to_copy->isLoaded())
|
||||
$errors[] = 'Wrong characters configuration. Try again or contact with admin. ADMIN: Edit file config.php and set valid characters to copy names. Character to copy: <b>'.$char_to_copy_name.'</b> doesn\'t exist.';
|
||||
$errors[] = 'Wrong characters configuration. Try again or contact with admin. ADMIN: Go to Admin Panel -> Settings -> Create Character and set valid characters to copy names. Character to copy: <b>'.$char_to_copy_name.'</b> doesn\'t exist.';
|
||||
}
|
||||
|
||||
if(!empty($errors)) {
|
||||
@@ -195,7 +195,7 @@ class CreateCharacter
|
||||
|
||||
for($skill = POT::SKILL_FIRST; $skill <= POT::SKILL_LAST; $skill++) {
|
||||
$value = 10;
|
||||
if (config('use_character_sample_skills')) {
|
||||
if (setting('core.use_character_sample_skills')) {
|
||||
$value = $char_to_copy->getSkill($skill);
|
||||
}
|
||||
|
||||
@@ -239,23 +239,25 @@ class CreateCharacter
|
||||
}
|
||||
|
||||
if($db->hasTable('player_skills')) {
|
||||
for($i=0; $i<7; $i++) {
|
||||
for($skill = POT::SKILL_FIRST; $skill <= POT::SKILL_LAST; $skill++) {
|
||||
$value = 10;
|
||||
if (config('use_character_sample_skills')) {
|
||||
$value = $char_to_copy->getSkill($i);
|
||||
if (setting('core.use_character_sample_skills')) {
|
||||
$value = $char_to_copy->getSkill($skill);
|
||||
}
|
||||
$skillExists = $db->query('SELECT `skillid` FROM `player_skills` WHERE `player_id` = ' . $player->getId() . ' AND `skillid` = ' . $i);
|
||||
$skillExists = $db->query('SELECT `skillid` FROM `player_skills` WHERE `player_id` = ' . $player->getId() . ' AND `skillid` = ' . $skill);
|
||||
if($skillExists->rowCount() <= 0) {
|
||||
$db->query('INSERT INTO `player_skills` (`player_id`, `skillid`, `value`, `count`) VALUES ('.$player->getId().', '.$i.', ' . $value . ', 0)');
|
||||
$db->query('INSERT INTO `player_skills` (`player_id`, `skillid`, `value`, `count`) VALUES ('.$player->getId().', '.$skill.', ' . $value . ', 0)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($db->hasTable('player_items') && $db->hasColumn('player_items', 'pid') && $db->hasColumn('player_items', 'sid') && $db->hasColumn('player_items', 'itemtype')) {
|
||||
$loaded_items_to_copy = $db->query("SELECT * FROM player_items WHERE player_id = ".$char_to_copy->getId()."");
|
||||
foreach($loaded_items_to_copy as $save_item) {
|
||||
$blob = $db->quote($save_item['attributes']);
|
||||
$db->query("INSERT INTO `player_items` (`player_id` ,`pid` ,`sid` ,`itemtype`, `count`, `attributes`) VALUES ('".$player->getId()."', '".$save_item['pid']."', '".$save_item['sid']."', '".$save_item['itemtype']."', '".$save_item['count']."', $blob);");
|
||||
}
|
||||
}
|
||||
|
||||
global $twig;
|
||||
$twig->display('success.html.twig', array(
|
||||
|
@@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
class GoogleReCAPTCHA
|
||||
{
|
||||
private static $errorMessage = '';
|
||||
private static $errorType;
|
||||
|
||||
const ERROR_MISSING_RESPONSE = 1;
|
||||
const ERROR_INVALID_ACTION = 2;
|
||||
const ERROR_LOW_SCORE = 3;
|
||||
const ERROR_NO_SUCCESS = 4;
|
||||
|
||||
public static function verify($action = '')
|
||||
{
|
||||
if (!isset($_POST['g-recaptcha-response']) || empty($_POST['g-recaptcha-response'])) {
|
||||
self::$errorType = self::ERROR_MISSING_RESPONSE;
|
||||
self::$errorMessage = "Please confirm that you're not a robot.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$recaptchaApiUrl = 'https://www.google.com/recaptcha/api/siteverify';
|
||||
$secretKey = config('recaptcha_secret_key');
|
||||
|
||||
$recaptchaResponse = $_POST['g-recaptcha-response'];
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$params = 'secret='.$secretKey.'&response='.$recaptchaResponse.'&remoteip='.$ip;
|
||||
|
||||
if (function_exists('curl_version')) {
|
||||
$curl_connection = curl_init($recaptchaApiUrl);
|
||||
|
||||
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 0);
|
||||
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $params);
|
||||
|
||||
$response = curl_exec($curl_connection);
|
||||
curl_close($curl_connection);
|
||||
} else {
|
||||
$response = file_get_contents($recaptchaApiUrl . '?' . $params);
|
||||
}
|
||||
|
||||
$json = json_decode($response);
|
||||
|
||||
$recaptchaType = config('recaptcha_type');
|
||||
if ($recaptchaType === 'v3') { // score based
|
||||
//log_append('recaptcha.log', 'recaptcha_score: ' . $json->score . ', action:' . $json->action);
|
||||
|
||||
if (!isset($json->action) || $json->action !== $action) {
|
||||
self::$errorType = self::ERROR_INVALID_ACTION;
|
||||
self::$errorMessage = 'Google ReCaptcha returned invalid action.';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($json->score) || $json->score < config('recaptcha_v3_min_score')) {
|
||||
self::$errorType = self::ERROR_LOW_SCORE;
|
||||
self::$errorMessage = 'Your Google ReCaptcha score was too low.';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($json->success) || !$json->success) {
|
||||
self::$errorType = self::ERROR_NO_SUCCESS;
|
||||
self::$errorMessage = "Please confirm that you're not a robot.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getErrorMessage() {
|
||||
return self::$errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public static function getErrorType() {
|
||||
return self::$errorType;
|
||||
}
|
||||
}
|
598
system/libs/Settings.php
Normal file
598
system/libs/Settings.php
Normal file
@@ -0,0 +1,598 @@
|
||||
<?php
|
||||
/**
|
||||
* CreateCharacter
|
||||
*
|
||||
* @package MyAAC
|
||||
* @author Slawkens <slawkens@gmail.com>
|
||||
* @copyright 2020 MyAAC
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
|
||||
class Settings implements ArrayAccess
|
||||
{
|
||||
static private $instance;
|
||||
private $settingsFile = [];
|
||||
private $settingsDatabase = [];
|
||||
private $cache = [];
|
||||
private $valuesAsked = [];
|
||||
private $errors = [];
|
||||
|
||||
/**
|
||||
* @return Settings
|
||||
*/
|
||||
public static function getInstance(): Settings
|
||||
{
|
||||
if (!self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function load()
|
||||
{
|
||||
$cache = Cache::getInstance();
|
||||
if ($cache->enabled()) {
|
||||
$tmp = '';
|
||||
if ($cache->fetch('settings', $tmp)) {
|
||||
$this->settingsDatabase = unserialize($tmp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
global $db;
|
||||
$settings = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'settings`');
|
||||
|
||||
if($settings->rowCount() > 0) {
|
||||
foreach ($settings->fetchAll(PDO::FETCH_ASSOC) as $setting) {
|
||||
$this->settingsDatabase[$setting['name']][$setting['key']] = $setting['value'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($cache->enabled()) {
|
||||
$cache->set('settings', serialize($this->settingsDatabase), 600);
|
||||
}
|
||||
}
|
||||
|
||||
public function save($pluginName, $values) {
|
||||
global $db;
|
||||
|
||||
if (!isset($this->settingsFile[$pluginName])) {
|
||||
throw new RuntimeException('Error on save settings: plugin does not exist');
|
||||
}
|
||||
|
||||
$settings = $this->settingsFile[$pluginName];
|
||||
if (isset($settings['callbacks']['beforeSave'])) {
|
||||
if (!$settings['callbacks']['beforeSave']($settings, $values)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->errors = [];
|
||||
$db->query('DELETE FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($pluginName) . ';');
|
||||
foreach ($values as $key => $value) {
|
||||
$errorMessage = '';
|
||||
if (isset($settings['settings'][$key]['callbacks']['beforeSave']) && !$settings['settings'][$key]['callbacks']['beforeSave']($key, $value, $errorMessage)) {
|
||||
$this->errors[] = $errorMessage;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$db->insert(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key, 'value' => $value]);
|
||||
} catch (PDOException $error) {
|
||||
$this->errors[] = 'Error while saving setting (' . $pluginName . ' - ' . $key . '): ' . $error->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$cache = Cache::getInstance();
|
||||
if ($cache->enabled()) {
|
||||
$cache->delete('settings');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updateInDatabase($pluginName, $key, $value)
|
||||
{
|
||||
global $db;
|
||||
$db->update(TABLE_PREFIX . 'settings', ['value' => $value], ['name' => $pluginName, 'key' => $key]);
|
||||
}
|
||||
|
||||
public function deleteFromDatabase($pluginName, $key = null)
|
||||
{
|
||||
global $db;
|
||||
|
||||
if (!isset($key)) {
|
||||
$db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName], -1);
|
||||
}
|
||||
else {
|
||||
$db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function display($plugin, $settings): array
|
||||
{
|
||||
global $db;
|
||||
|
||||
$query = 'SELECT `key`, `value` FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($plugin) . ';';
|
||||
$query = $db->query($query);
|
||||
|
||||
$settingsDb = [];
|
||||
if($query->rowCount() > 0) {
|
||||
foreach($query->fetchAll(PDO::FETCH_ASSOC) as $value) {
|
||||
$settingsDb[$value['key']] = $value['value'];
|
||||
}
|
||||
}
|
||||
|
||||
$config = [];
|
||||
require BASE . 'config.local.php';
|
||||
|
||||
foreach ($config as $key => $value) {
|
||||
if (is_bool($value)) {
|
||||
$settingsDb[$key] = $value ? 'true' : 'false';
|
||||
}
|
||||
else {
|
||||
$settingsDb[$key] = (string)$value;
|
||||
}
|
||||
}
|
||||
|
||||
$javascript = '';
|
||||
ob_start();
|
||||
?>
|
||||
<ul class="nav nav-tabs" id="myTab">
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach($settings as $setting) {
|
||||
if (isset($setting['script'])) {
|
||||
$javascript .= $setting['script'] . PHP_EOL;
|
||||
}
|
||||
|
||||
if ($setting['type'] === 'category') {
|
||||
?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link<?= ($i === 0 ? ' active' : ''); ?>" id="home-tab-<?= $i++; ?>" data-toggle="tab" href="#tab-<?= str_replace(' ', '', $setting['title']); ?>" type="button"><?= $setting['title']; ?></a>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
<div class="tab-content" id="tab-content">
|
||||
<?php
|
||||
|
||||
$checkbox = function ($key, $type, $value) {
|
||||
echo '<label><input type="radio" id="' . $key . '_' . ($type ? 'yes' : 'no') . '" name="settings[' . $key . ']" value="' . ($type ? 'true' : 'false') . '" ' . ($value === $type ? 'checked' : '') . '/>' . ($type ? 'Yes' : 'No') . '</label> ';
|
||||
};
|
||||
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
foreach($settings as $key => $setting) {
|
||||
if ($setting['type'] === 'category') {
|
||||
if ($j++ !== 0) { // close previous category
|
||||
echo '</tbody></table></div>';
|
||||
}
|
||||
?>
|
||||
<div class="tab-pane fade show<?= ($j === 1 ? ' active' : ''); ?>" id="tab-<?= str_replace(' ', '', $setting['title']); ?>">
|
||||
<?php
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($setting['type'] === 'section') {
|
||||
if ($i++ !== 0) { // close previous section
|
||||
echo '</tbody></table>';
|
||||
}
|
||||
?>
|
||||
<h3 id="row_<?= $key ?>" style="text-align: center"><strong><?= $setting['title']; ?></strong></h3>
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 13%">Name</th>
|
||||
<th style="width: 30%">Value</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($setting['hidden']) || !$setting['hidden']) {
|
||||
?>
|
||||
<tr id="row_<?= $key ?>">
|
||||
<td><label for="<?= $key ?>" class="control-label"><?= $setting['name'] ?></label></td>
|
||||
<td>
|
||||
<?php
|
||||
}
|
||||
if (isset($setting['hidden']) && $setting['hidden']) {
|
||||
$value = '';
|
||||
if ($setting['type'] === 'boolean') {
|
||||
$value = ($setting['default'] ? 'true' : 'false');
|
||||
}
|
||||
else if (in_array($setting['type'], ['text', 'number', 'email', 'password', 'textarea'])) {
|
||||
$value = $setting['default'];
|
||||
}
|
||||
else if ($setting['type'] === 'options') {
|
||||
$value = $setting['options'][$setting['default']];
|
||||
}
|
||||
|
||||
echo '<input type="hidden" name="settings[' . $key . ']" value="' . $value . '" id="' . $key . '"';
|
||||
}
|
||||
else if ($setting['type'] === 'boolean') {
|
||||
if(isset($settingsDb[$key])) {
|
||||
if($settingsDb[$key] === 'true') {
|
||||
$value = true;
|
||||
}
|
||||
else {
|
||||
$value = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$value = ($setting['default'] ?? false);
|
||||
}
|
||||
|
||||
$checkbox($key, true, $value);
|
||||
$checkbox($key, false, $value);
|
||||
}
|
||||
|
||||
else if (in_array($setting['type'], ['text', 'number', 'email', 'password'])) {
|
||||
if ($setting['type'] === 'number') {
|
||||
$min = (isset($setting['min']) ? ' min="' . $setting['min'] . '"' : '');
|
||||
$max = (isset($setting['max']) ? ' max="' . $setting['max'] . '"' : '');
|
||||
$step = (isset($setting['step']) ? ' step="' . $setting['step'] . '"' : '');
|
||||
}
|
||||
else {
|
||||
$min = $max = $step = '';
|
||||
}
|
||||
|
||||
echo '<input class="form-control" type="' . $setting['type'] . '" name="settings[' . $key . ']" value="' . ($settingsDb[$key] ?? ($setting['default'] ?? '')) . '" id="' . $key . '"' . $min . $max . $step . '/>';
|
||||
}
|
||||
|
||||
else if($setting['type'] === 'textarea') {
|
||||
$value = ($settingsDb[$key] ?? ($setting['default'] ?? ''));
|
||||
$valueWithSpaces = array_map('trim', preg_split('/\r\n|\r|\n/', trim($value)));
|
||||
$rows = count($valueWithSpaces);
|
||||
if ($rows < 2) {
|
||||
$rows = 2; // always min 2 rows for textarea
|
||||
}
|
||||
echo '<textarea class="form-control" rows="' . $rows . '" name="settings[' . $key . ']" id="' . $key . '">' . $value . '</textarea>';
|
||||
}
|
||||
|
||||
else if ($setting['type'] === 'options') {
|
||||
if ($setting['options'] === '$templates') {
|
||||
$templates = [];
|
||||
foreach (get_templates() as $value) {
|
||||
$templates[$value] = $value;
|
||||
}
|
||||
|
||||
$setting['options'] = $templates;
|
||||
}
|
||||
|
||||
else if($setting['options'] === '$clients') {
|
||||
$clients = [];
|
||||
foreach((array)config('clients') as $client) {
|
||||
|
||||
$client_version = (string)($client / 100);
|
||||
if(strpos($client_version, '.') === false)
|
||||
$client_version .= '.0';
|
||||
|
||||
$clients[$client] = $client_version;
|
||||
}
|
||||
|
||||
$setting['options'] = $clients;
|
||||
}
|
||||
else if ($setting['options'] == '$timezones') {
|
||||
$timezones = [];
|
||||
foreach (DateTimeZone::listIdentifiers() as $value) {
|
||||
$timezones[$value] = $value;
|
||||
}
|
||||
|
||||
$setting['options'] = $timezones;
|
||||
}
|
||||
|
||||
else {
|
||||
if (is_string($setting['options'])) {
|
||||
$setting['options'] = explode(',', $setting['options']);
|
||||
foreach ($setting['options'] as &$option) {
|
||||
$option = trim($option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo '<select class="form-control" name="settings[' . $key . ']" id="' . $key . '">';
|
||||
foreach ($setting['options'] as $value => $option) {
|
||||
$compareTo = ($settingsDb[$key] ?? ($setting['default'] ?? ''));
|
||||
if($value === 'true') {
|
||||
$selected = $compareTo === true;
|
||||
}
|
||||
else if($value === 'false') {
|
||||
$selected = $compareTo === false;
|
||||
}
|
||||
else {
|
||||
$selected = $compareTo == $value;
|
||||
}
|
||||
|
||||
echo '<option value="' . $value . '" ' . ($selected ? 'selected' : '') . '>' . $option . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
if (!isset($setting['hidden']) || !$setting['hidden']) {
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<div class="well setting-default"><?php
|
||||
echo ($setting['desc'] ?? '');
|
||||
echo '<br/>';
|
||||
echo '<strong>Default:</strong> ';
|
||||
|
||||
if ($setting['type'] === 'boolean') {
|
||||
echo ($setting['default'] ? 'Yes' : 'No');
|
||||
}
|
||||
else if (in_array($setting['type'], ['text', 'number', 'email', 'password', 'textarea'])) {
|
||||
echo $setting['default'];
|
||||
}
|
||||
else if ($setting['type'] === 'options') {
|
||||
if (!empty($setting['default'])) {
|
||||
echo $setting['options'][$setting['default']];
|
||||
}
|
||||
}
|
||||
?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button name="save" type="submit" class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
return ['content' => ob_get_clean(), 'script' => $javascript];
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (is_null($offset)) {
|
||||
throw new \RuntimeException("Settings: You cannot set empty offset with value: $value!");
|
||||
}
|
||||
|
||||
$this->loadPlugin($offset);
|
||||
|
||||
$pluginKeyName = $this->valuesAsked['pluginKeyName'];
|
||||
$key = $this->valuesAsked['key'];
|
||||
|
||||
// remove whole plugin settings
|
||||
if (!isset($value)) {
|
||||
$this->offsetUnset($offset);
|
||||
$this->deleteFromDatabase($pluginKeyName, $key);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->settingsDatabase[$pluginKeyName][$key] = $value;
|
||||
$this->updateInDatabase($pluginKeyName, $key, $value);
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
$this->loadPlugin($offset);
|
||||
|
||||
$pluginKeyName = $this->valuesAsked['pluginKeyName'];
|
||||
$key = $this->valuesAsked['key'];
|
||||
|
||||
// remove specified plugin settings (all)
|
||||
if(is_null($key)) {
|
||||
return isset($this->settingsDatabase[$offset]);
|
||||
}
|
||||
|
||||
return isset($this->settingsDatabase[$pluginKeyName][$key]);
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->loadPlugin($offset);
|
||||
|
||||
$pluginKeyName = $this->valuesAsked['pluginKeyName'];
|
||||
$key = $this->valuesAsked['key'];
|
||||
|
||||
if (isset($this->cache[$offset])) {
|
||||
unset($this->cache[$offset]);
|
||||
}
|
||||
|
||||
// remove specified plugin settings (all)
|
||||
if(!isset($key)) {
|
||||
unset($this->settingsFile[$pluginKeyName]);
|
||||
unset($this->settingsDatabase[$pluginKeyName]);
|
||||
$this->deleteFromDatabase($pluginKeyName);
|
||||
return;
|
||||
}
|
||||
|
||||
unset($this->settingsFile[$pluginKeyName]['settings'][$key]);
|
||||
unset($this->settingsDatabase[$pluginKeyName][$key]);
|
||||
$this->deleteFromDatabase($pluginKeyName, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings
|
||||
* Usage: $setting['plugin_name.key']
|
||||
* Example: $settings['shop_system.paypal_email']
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return array|mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
// try cache hit
|
||||
if(isset($this->cache[$offset])) {
|
||||
return $this->cache[$offset];
|
||||
}
|
||||
|
||||
$this->loadPlugin($offset);
|
||||
|
||||
$pluginKeyName = $this->valuesAsked['pluginKeyName'];
|
||||
$key = $this->valuesAsked['key'];
|
||||
|
||||
// return specified plugin settings (all)
|
||||
if(!isset($key)) {
|
||||
if (!isset($this->settingsFile[$pluginKeyName]['settings'])) {
|
||||
throw new RuntimeException('Unknown plugin settings: ' . $pluginKeyName);
|
||||
}
|
||||
return $this->settingsFile[$pluginKeyName]['settings'];
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
if(isset($this->settingsFile[$pluginKeyName]['settings'][$key])) {
|
||||
$ret = $this->settingsFile[$pluginKeyName]['settings'][$key];
|
||||
}
|
||||
|
||||
if(isset($this->settingsDatabase[$pluginKeyName][$key])) {
|
||||
$value = $this->settingsDatabase[$pluginKeyName][$key];
|
||||
|
||||
$ret['value'] = $value;
|
||||
}
|
||||
else {
|
||||
$ret['value'] = $this->settingsFile[$pluginKeyName]['settings'][$key]['default'];
|
||||
}
|
||||
|
||||
if(isset($ret['type'])) {
|
||||
switch($ret['type']) {
|
||||
case 'boolean':
|
||||
$ret['value'] = getBoolean($ret['value']);
|
||||
break;
|
||||
|
||||
case 'number':
|
||||
if (!isset($ret['step']) || (int)$ret['step'] == 1) {
|
||||
$ret['value'] = (int)$ret['value'];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($ret['callbacks']['get'])) {
|
||||
$ret['value'] = $ret['callbacks']['get']($ret['value']);
|
||||
}
|
||||
|
||||
$this->cache[$offset] = $ret;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private function updateValuesAsked($offset)
|
||||
{
|
||||
$pluginKeyName = $offset;
|
||||
if (strpos($offset, '.')) {
|
||||
$explode = explode('.', $offset, 2);
|
||||
|
||||
$pluginKeyName = $explode[0];
|
||||
$key = $explode[1];
|
||||
|
||||
$this->valuesAsked = ['pluginKeyName' => $pluginKeyName, 'key' => $key];
|
||||
}
|
||||
else {
|
||||
$this->valuesAsked = ['pluginKeyName' => $pluginKeyName, 'key' => null];
|
||||
}
|
||||
}
|
||||
|
||||
private function loadPlugin($offset)
|
||||
{
|
||||
$this->updateValuesAsked($offset);
|
||||
|
||||
$pluginKeyName = $this->valuesAsked['pluginKeyName'];
|
||||
$key = $this->valuesAsked['key'];
|
||||
|
||||
if (!isset($this->settingsFile[$pluginKeyName])) {
|
||||
if ($pluginKeyName === 'core') {
|
||||
$settingsFilePath = SYSTEM . 'settings.php';
|
||||
} else {
|
||||
//$pluginSettings = Plugins::getPluginSettings($pluginKeyName);
|
||||
$settings = Plugins::getAllPluginsSettings();
|
||||
if (!isset($settings[$pluginKeyName])) {
|
||||
warning("Setting $pluginKeyName does not exist or does not have settings defined.");
|
||||
return;
|
||||
}
|
||||
|
||||
$settingsFilePath = BASE . $settings[$pluginKeyName]['settingsFilename'];
|
||||
}
|
||||
|
||||
if (!file_exists($settingsFilePath)) {
|
||||
throw new \RuntimeException('Failed to load settings file for plugin: ' . $pluginKeyName);
|
||||
}
|
||||
|
||||
$this->settingsFile[$pluginKeyName] = require $settingsFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
public static function saveConfig($config, $filename, &$content = '')
|
||||
{
|
||||
$content = "<?php" . PHP_EOL .
|
||||
"\$config['installed'] = true;" . PHP_EOL;
|
||||
|
||||
foreach ($config as $key => $value) {
|
||||
$content .= "\$config['$key'] = ";
|
||||
$content .= var_export($value, true);
|
||||
$content .= ';' . PHP_EOL;
|
||||
}
|
||||
|
||||
$success = file_put_contents($filename, $content);
|
||||
|
||||
// we saved new config.php, need to revalidate cache (only if opcache is enabled)
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate($filename);
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
public static function testDatabaseConnection($config): bool
|
||||
{
|
||||
$user = null;
|
||||
$password = null;
|
||||
$dns = [];
|
||||
|
||||
if( isset($config['database_name']) ) {
|
||||
$dns[] = 'dbname=' . $config['database_name'];
|
||||
}
|
||||
|
||||
if( isset($config['database_user']) ) {
|
||||
$user = $config['database_user'];
|
||||
}
|
||||
|
||||
if( isset($config['database_password']) ) {
|
||||
$password = $config['database_password'];
|
||||
}
|
||||
|
||||
if( isset($config['database_host']) ) {
|
||||
$dns[] = 'host=' . $config['database_host'];
|
||||
}
|
||||
|
||||
if( isset($config['database_port']) ) {
|
||||
$dns[] = 'port=' . $config['database_port'];
|
||||
}
|
||||
|
||||
try {
|
||||
$connectionTest = new PDO('mysql:' . implode(';', $dns), $user, $password);
|
||||
$connectionTest->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
catch(PDOException $error) {
|
||||
error('MySQL connection failed. Settings has been reverted.');
|
||||
error($error->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getErrors() {
|
||||
return $this->errors;
|
||||
}
|
||||
}
|
@@ -110,4 +110,21 @@ class Cache
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled() {return false;}
|
||||
|
||||
public static function remember($key, $ttl, $callback)
|
||||
{
|
||||
$cache = self::getInstance();
|
||||
if(!$cache->enabled()) {
|
||||
return $callback();
|
||||
}
|
||||
|
||||
$value = null;
|
||||
if ($cache->fetch($key, $value)) {
|
||||
return unserialize($value);
|
||||
}
|
||||
|
||||
$value = $callback();
|
||||
$cache->set($key, serialize($value),$ttl);
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
@@ -82,6 +82,9 @@ class Creatures {
|
||||
$armor = $monster->getArmor();
|
||||
$defensev = $monster->getDefense();
|
||||
|
||||
//load look
|
||||
$look = $monster->getLook();
|
||||
|
||||
//load monster flags
|
||||
$flags = $monster->getFlags();
|
||||
if(!isset($flags['summonable']))
|
||||
@@ -147,6 +150,7 @@ class Creatures {
|
||||
'armor' => $armor,
|
||||
'race' => $race,
|
||||
'loot' => json_encode($loot),
|
||||
'look' => json_encode($look),
|
||||
'summons' => json_encode($summons)
|
||||
));
|
||||
|
||||
|
@@ -41,4 +41,3 @@ class Data
|
||||
return $db->update($this->table, $data, $where);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
$configForumTablePrefix = config('forum_table_prefix');
|
||||
$configForumTablePrefix = setting('core.forum_table_prefix');
|
||||
if(null !== $configForumTablePrefix && !empty(trim($configForumTablePrefix))) {
|
||||
if(!in_array($configForumTablePrefix, array('myaac_', 'z_'))) {
|
||||
throw new RuntimeException('Invalid value for forum_table_prefix in config.php. Can be only: "myaac_" or "z_".');
|
||||
@@ -47,7 +47,7 @@ class Forum
|
||||
return
|
||||
$db->query(
|
||||
'SELECT `id` FROM `players` WHERE `account_id` = ' . $db->quote($account->getId()) .
|
||||
' AND `level` >= ' . $db->quote($config['forum_level_required']) .
|
||||
' AND `level` >= ' . $db->quote(setting('core.forum_level_required')) .
|
||||
' LIMIT 1')->rowCount() > 0;
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
defined('MYAAC') or die('Direct access not allowed!');
|
||||
|
||||
function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) {
|
||||
function is_sub_dir($path = NULL, $parent_folder = BASE) {
|
||||
|
||||
//Get directory path minus last folder
|
||||
$dir = dirname($path);
|
||||
@@ -41,9 +41,9 @@ function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) {
|
||||
use Composer\Semver\Semver;
|
||||
|
||||
class Plugins {
|
||||
private static $warnings = array();
|
||||
private static $warnings = [];
|
||||
private static $error = null;
|
||||
private static $plugin_json = array();
|
||||
private static $plugin_json = [];
|
||||
|
||||
public static function getRoutes()
|
||||
{
|
||||
@@ -56,22 +56,8 @@ class Plugins {
|
||||
}
|
||||
|
||||
$routes = [];
|
||||
foreach(get_plugins() as $filename) {
|
||||
$string = file_get_contents(PLUGINS . $filename . '.json');
|
||||
$string = self::removeComments($string);
|
||||
$plugin = json_decode($string, true);
|
||||
self::$plugin_json = $plugin;
|
||||
if ($plugin == null) {
|
||||
self::$warnings[] = 'Cannot load ' . $filename . '.json. File might be not a valid json code.';
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isset($plugin['enabled']) && !getBoolean($plugin['enabled'])) {
|
||||
self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.';
|
||||
continue;
|
||||
}
|
||||
|
||||
$warningPreTitle = 'Plugin: ' . $filename . ' - ';
|
||||
foreach(self::getAllPluginsJson() as $plugin) {
|
||||
$warningPreTitle = 'Plugin: ' . $plugin['name'] . ' - ';
|
||||
|
||||
if (isset($plugin['routes'])) {
|
||||
foreach ($plugin['routes'] as $_name => $info) {
|
||||
@@ -80,7 +66,8 @@ class Plugins {
|
||||
if ($method !== '*') {
|
||||
$methods = is_string($method) ? explode(',', $info['method']) : $method;
|
||||
foreach ($methods as $method) {
|
||||
if (!in_array($method, ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'])) {
|
||||
$method = strtolower($method);
|
||||
if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'head'])) {
|
||||
self::$warnings[] = $warningPreTitle . 'Not allowed method ' . $method . '... Disabling this route...';
|
||||
}
|
||||
}
|
||||
@@ -161,28 +148,14 @@ class Plugins {
|
||||
}
|
||||
|
||||
$hooks = [];
|
||||
foreach(get_plugins() as $filename) {
|
||||
$string = file_get_contents(PLUGINS . $filename . '.json');
|
||||
$string = self::removeComments($string);
|
||||
$plugin = json_decode($string, true);
|
||||
self::$plugin_json = $plugin;
|
||||
if ($plugin == null) {
|
||||
self::$warnings[] = 'Cannot load ' . $filename . '.json. File might be not a valid json code.';
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isset($plugin['enabled']) && !getBoolean($plugin['enabled'])) {
|
||||
self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.';
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach(self::getAllPluginsJson() as $plugin) {
|
||||
if (isset($plugin['hooks'])) {
|
||||
foreach ($plugin['hooks'] as $_name => $info) {
|
||||
if (defined('HOOK_'. $info['type'])) {
|
||||
$hook = constant('HOOK_'. $info['type']);
|
||||
$hooks[] = ['name' => $_name, 'type' => $hook, 'file' => $info['file']];
|
||||
} else {
|
||||
self::$warnings[] = 'Plugin: ' . $filename . '. Unknown event type: ' . $info['type'];
|
||||
self::$warnings[] = 'Plugin: ' . $plugin['name'] . '. Unknown event type: ' . $info['type'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,7 +168,108 @@ class Plugins {
|
||||
return $hooks;
|
||||
}
|
||||
|
||||
public static function install($file) {
|
||||
public static function getAllPluginsSettings()
|
||||
{
|
||||
$cache = Cache::getInstance();
|
||||
if ($cache->enabled()) {
|
||||
$tmp = '';
|
||||
if ($cache->fetch('plugins_settings', $tmp)) {
|
||||
return unserialize($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
$settings = [];
|
||||
foreach (self::getAllPluginsJson() as $plugin) {
|
||||
if (isset($plugin['settings'])) {
|
||||
$settingsFile = require BASE . $plugin['settings'];
|
||||
if (!isset($settingsFile['key'])) {
|
||||
warning("Settings file for plugin - {$plugin['name']} does not contain 'key' field");
|
||||
continue;
|
||||
}
|
||||
|
||||
$settings[$settingsFile['key']] = ['pluginFilename' => $plugin['filename'], 'settingsFilename' => $plugin['settings']];
|
||||
}
|
||||
}
|
||||
|
||||
if ($cache->enabled()) {
|
||||
$cache->set('plugins_settings', serialize($settings), 600); // cache for 10 minutes
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public static function getAllPluginsJson($disabled = false)
|
||||
{
|
||||
$cache = Cache::getInstance();
|
||||
if ($cache->enabled()) {
|
||||
$tmp = '';
|
||||
if ($cache->fetch('plugins', $tmp)) {
|
||||
return unserialize($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
$plugins = [];
|
||||
foreach (get_plugins($disabled) as $filename) {
|
||||
$plugin = self::getPluginJson($filename);
|
||||
|
||||
if (!$plugin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$plugin['filename'] = $filename;
|
||||
$plugins[] = $plugin;
|
||||
}
|
||||
|
||||
if ($cache->enabled()) {
|
||||
$cache->set('plugins', serialize($plugins), 600); // cache for 10 minutes
|
||||
}
|
||||
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
public static function getPluginSettings($filename)
|
||||
{
|
||||
$plugin_json = self::getPluginJson($filename);
|
||||
if (!$plugin_json) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($plugin_json['settings']) || !file_exists(BASE . $plugin_json['settings'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $plugin_json['settings'];
|
||||
}
|
||||
|
||||
public static function getPluginJson($filename = null)
|
||||
{
|
||||
if(!isset($filename)) {
|
||||
return self::$plugin_json;
|
||||
}
|
||||
|
||||
$pathToPlugin = PLUGINS . $filename . '.json';
|
||||
if (!file_exists($pathToPlugin)) {
|
||||
self::$warnings[] = "Cannot load $filename.json. File doesn't exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$string = file_get_contents($pathToPlugin);
|
||||
$plugin_json = json_decode($string, true);
|
||||
if ($plugin_json == null) {
|
||||
self::$warnings[] = "Cannot load $filename.json. File might be not a valid json code.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($plugin_json['enabled']) && !getBoolean($plugin_json['enabled'])) {
|
||||
self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.';
|
||||
return false;
|
||||
}
|
||||
|
||||
return $plugin_json;
|
||||
}
|
||||
|
||||
public static function install($file): bool
|
||||
{
|
||||
global $db;
|
||||
|
||||
if(!\class_exists('ZipArchive')) {
|
||||
@@ -234,8 +308,13 @@ class Plugins {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pluginFilename = str_replace('.json', '', basename($json_file));
|
||||
if (self::existDisabled($pluginFilename)) {
|
||||
success('The plugin already existed, but was disabled. It has been enabled again and will be now reinstalled.');
|
||||
self::enable($pluginFilename);
|
||||
}
|
||||
|
||||
$string = file_get_contents($file_name);
|
||||
$string = self::removeComments($string);
|
||||
$plugin_json = json_decode($string, true);
|
||||
self::$plugin_json = $plugin_json;
|
||||
if ($plugin_json == null) {
|
||||
@@ -435,7 +514,45 @@ class Plugins {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function uninstall($plugin_name)
|
||||
public static function isEnabled($pluginFileName): bool
|
||||
{
|
||||
$filenameJson = $pluginFileName . '.json';
|
||||
return !is_file(PLUGINS . 'disabled.' . $filenameJson) && is_file(PLUGINS . $filenameJson);
|
||||
}
|
||||
|
||||
public static function existDisabled($pluginFileName): bool
|
||||
{
|
||||
$filenameJson = $pluginFileName . '.json';
|
||||
return is_file(PLUGINS . 'disabled.' . $filenameJson);
|
||||
}
|
||||
|
||||
public static function enable($pluginFileName): bool {
|
||||
return self::enableDisable($pluginFileName, true);
|
||||
}
|
||||
|
||||
public static function disable($pluginFileName): bool {
|
||||
return self::enableDisable($pluginFileName, false);
|
||||
}
|
||||
|
||||
private static function enableDisable($pluginFileName, $enable): bool
|
||||
{
|
||||
$filenameJson = $pluginFileName . '.json';
|
||||
$fileExist = is_file(PLUGINS . ($enable ? 'disabled.' : '') . $filenameJson);
|
||||
if (!$fileExist) {
|
||||
self::$error = 'Cannot ' . ($enable ? 'enable' : 'disable') . ' plugin: ' . $pluginFileName . '. File does not exist.';
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = rename(PLUGINS . ($enable ? 'disabled.' : '') . $filenameJson, PLUGINS . ($enable ? '' : 'disabled.') . $filenameJson);
|
||||
if (!$result) {
|
||||
self::$error = 'Cannot ' . ($enable ? 'enable' : 'disable') . ' plugin: ' . $pluginFileName . '. Permission problem.';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function uninstall($plugin_name): bool
|
||||
{
|
||||
$filename = BASE . 'plugins/' . $plugin_name . '.json';
|
||||
if(!file_exists($filename)) {
|
||||
@@ -443,9 +560,8 @@ class Plugins {
|
||||
return false;
|
||||
}
|
||||
$string = file_get_contents($filename);
|
||||
$string = self::removeComments($string);
|
||||
$plugin_info = json_decode($string, true);
|
||||
if($plugin_info == false) {
|
||||
if(!$plugin_info) {
|
||||
self::$error = 'Cannot load plugin info ' . $plugin_name . '.json';
|
||||
return false;
|
||||
}
|
||||
@@ -492,7 +608,8 @@ class Plugins {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function is_installed($plugin_name, $version) {
|
||||
public static function is_installed($plugin_name, $version): bool
|
||||
{
|
||||
$filename = BASE . 'plugins/' . $plugin_name . '.json';
|
||||
if(!file_exists($filename)) {
|
||||
return false;
|
||||
@@ -500,7 +617,7 @@ class Plugins {
|
||||
|
||||
$string = file_get_contents($filename);
|
||||
$plugin_info = json_decode($string, true);
|
||||
if($plugin_info == false) {
|
||||
if(!$plugin_info) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -523,26 +640,6 @@ class Plugins {
|
||||
return self::$error;
|
||||
}
|
||||
|
||||
public static function getPluginJson() {
|
||||
return self::$plugin_json;
|
||||
}
|
||||
|
||||
public static function removeComments($string) {
|
||||
$string = preg_replace('!/\*.*?\*/!s', '', $string);
|
||||
$string = preg_replace('/\n\s*\n/', "\n", $string);
|
||||
// Removes multi-line comments and does not create
|
||||
// a blank line, also treats white spaces/tabs
|
||||
$string = preg_replace('!^[ \t]*/\*.*?\*/[ \t]*[\r\n]!s', '', $string);
|
||||
|
||||
// Removes single line '//' comments, treats blank characters
|
||||
$string = preg_replace('![ \t]*//.*[ \t]*[\r\n]!', '', $string);
|
||||
|
||||
// Strip blank lines
|
||||
$string = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $string);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install menus
|
||||
* Helper function for plugins
|
||||
|
@@ -32,5 +32,3 @@ class E_OTS_ErrorCode extends Exception
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -36,5 +36,3 @@ class E_OTS_Generic extends E_OTS_ErrorCode
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -22,5 +22,3 @@ class E_OTS_NotAContainer extends Exception
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -32,5 +32,3 @@ class E_OTS_OTBMError extends E_OTS_ErrorCode
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -22,5 +22,3 @@ class E_OTS_ReadOnly extends Exception
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -37,5 +37,3 @@ interface IOTS_Cipher
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -89,5 +89,3 @@ interface IOTS_DataDisplay
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -96,5 +96,3 @@ interface IOTS_Display
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -67,5 +67,3 @@ interface IOTS_GuildAction
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -21,7 +21,6 @@
|
||||
* @property string $password Password.
|
||||
* @property string $eMail Email address.
|
||||
* @property int $premiumEnd Timestamp of PACC end.
|
||||
* @property bool $blocked Blocked flag state.
|
||||
* @property bool $deleted Deleted flag state.
|
||||
* @property bool $warned Warned flag state.
|
||||
* @property bool $banned Ban state.
|
||||
@@ -39,7 +38,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
* @var array
|
||||
* @version 0.1.5
|
||||
*/
|
||||
private $data = array('email' => '', 'blocked' => false, 'rlname' => '','location' => '', 'country' => '','web_flags' => 0, 'lastday' => 0, 'premdays' => 0, 'created' => 0);
|
||||
private $data = array('email' => '', 'rlname' => '','location' => '', 'country' => '','web_flags' => 0, 'lastday' => 0, 'premdays' => 0, 'created' => 0);
|
||||
|
||||
public static $cache = array();
|
||||
|
||||
@@ -231,26 +230,22 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
* @param int $id Account number.
|
||||
* @throws PDOException On PDO operation error.
|
||||
*/
|
||||
public function load($id, $fresh = false, $searchOnlyById = false)
|
||||
public function load($id, $fresh = false)
|
||||
{
|
||||
if(!$fresh && isset(self::$cache[$id])) {
|
||||
$this->data = self::$cache[$id];
|
||||
return;
|
||||
}
|
||||
|
||||
$numberColumn = 'id';
|
||||
$nameOrNumber = '';
|
||||
if (!$searchOnlyById) {
|
||||
if (USE_ACCOUNT_NAME) {
|
||||
$nameOrNumber = '`name`,';
|
||||
} else if (USE_ACCOUNT_NUMBER) {
|
||||
$nameOrNumber = '`number`,';
|
||||
$numberColumn = 'number';
|
||||
}
|
||||
}
|
||||
|
||||
// SELECT query on database
|
||||
$this->data = $this->db->query('SELECT `id`, ' . $nameOrNumber . '`password`, `email`, `blocked`, `rlname`, `location`, `country`, `web_flags`, ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays`, ' : '') . ($this->db->hasColumn('accounts', 'lastday') ? '`lastday`, ' : ($this->db->hasColumn('accounts', 'premend') ? '`premend`,' : ($this->db->hasColumn('accounts', 'premium_ends_at') ? '`premium_ends_at`,' : ''))) . '`created` FROM `accounts` WHERE `' . $numberColumn . '` = ' . (int) $id)->fetch();
|
||||
$this->data = $this->db->query('SELECT `id`, ' . $nameOrNumber . '`password`, `email`, `rlname`, `location`, `country`, `web_flags`, ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays`, ' : '') . ($this->db->hasColumn('accounts', 'lastday') ? '`lastday`, ' : ($this->db->hasColumn('accounts', 'premend') ? '`premend`,' : ($this->db->hasColumn('accounts', 'premium_ends_at') ? '`premium_ends_at`,' : ''))) . '`created` FROM `accounts` WHERE `id` = ' . (int) $id)->fetch();
|
||||
self::$cache[$id] = $this->data;
|
||||
}
|
||||
|
||||
@@ -268,8 +263,13 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
*/
|
||||
public function find($name)
|
||||
{
|
||||
$nameOrNumberColumn = 'name';
|
||||
if (USE_ACCOUNT_NUMBER) {
|
||||
$nameOrNumberColumn = 'number';
|
||||
}
|
||||
|
||||
// finds player's ID
|
||||
$id = $this->db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $this->db->quote($name) )->fetch();
|
||||
$id = $this->db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $this->db->quote($name) )->fetch();
|
||||
|
||||
// if anything was found
|
||||
if( isset($id['id']) )
|
||||
@@ -345,7 +345,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
}
|
||||
|
||||
// UPDATE query on database
|
||||
$this->db->exec('UPDATE `accounts` SET ' . ($this->db->hasColumn('accounts', 'name') ? '`name` = ' . $this->db->quote($this->data['name']) . ',' : '') . '`password` = ' . $this->db->quote($this->data['password']) . ', `email` = ' . $this->db->quote($this->data['email']) . ', `blocked` = ' . (int) $this->data['blocked'] . ', `rlname` = ' . $this->db->quote($this->data['rlname']) . ', `location` = ' . $this->db->quote($this->data['location']) . ', `country` = ' . $this->db->quote($this->data['country']) . ', `web_flags` = ' . (int) $this->data['web_flags'] . ', ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays` = ' . (int) $this->data['premdays'] . ',' : '') . '`' . $field . '` = ' . (int) $this->data[$field] . ' WHERE `id` = ' . $this->data['id']);
|
||||
$this->db->exec('UPDATE `accounts` SET ' . ($this->db->hasColumn('accounts', 'name') ? '`name` = ' . $this->db->quote($this->data['name']) . ',' : '') . '`password` = ' . $this->db->quote($this->data['password']) . ', `email` = ' . $this->db->quote($this->data['email']) . ', `rlname` = ' . $this->db->quote($this->data['rlname']) . ', `location` = ' . $this->db->quote($this->data['location']) . ', `country` = ' . $this->db->quote($this->data['country']) . ', `web_flags` = ' . (int) $this->data['web_flags'] . ', ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays` = ' . (int) $this->data['premdays'] . ',' : '') . '`' . $field . '` = ' . (int) $this->data[$field] . ' WHERE `id` = ' . $this->data['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -650,53 +650,6 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
$this->data['email'] = (string) $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if account is blocked.
|
||||
*
|
||||
* <p>
|
||||
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded} exception instead of triggering E_USER_WARNING.
|
||||
* </p>
|
||||
*
|
||||
* @version 0.0.3
|
||||
* @return bool Blocked state.
|
||||
* @throws E_OTS_NotLoaded If account is not loaded.
|
||||
*/
|
||||
public function isBlocked()
|
||||
{
|
||||
if( !isset($this->data['blocked']) )
|
||||
{
|
||||
throw new E_OTS_NotLoaded();
|
||||
}
|
||||
|
||||
return $this->data['blocked'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unblocks account.
|
||||
*
|
||||
* <p>
|
||||
* This method only updates object state. To save changes in database you need to use {@link OTS_Account::save() save() method} to flush changed to database.
|
||||
* </p>
|
||||
*/
|
||||
public function unblock()
|
||||
{
|
||||
$this->data['blocked'] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks account.
|
||||
*
|
||||
* <p>
|
||||
* This method only updates object state. To save changes in databaseed to use {@link OTS_Account::save() save() method} to flush changed to database.
|
||||
* </p>
|
||||
*/
|
||||
public function block()
|
||||
{
|
||||
$this->data['blocked'] = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reads custom field.
|
||||
*
|
||||
@@ -1041,7 +994,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
$access = 0;
|
||||
|
||||
// finds ranks of all characters
|
||||
foreach($this->getPlayersList() as $player)
|
||||
foreach($this->getPlayersList(false) as $player)
|
||||
{
|
||||
$rank = $player->getRank();
|
||||
|
||||
@@ -1147,9 +1100,6 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
case 'playersList':
|
||||
return $this->getPlayersList();
|
||||
|
||||
case 'blocked':
|
||||
return $this->isBlocked();
|
||||
|
||||
case 'deleted':
|
||||
return $this->isDeleted();
|
||||
|
||||
@@ -1195,17 +1145,6 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
$this->setPremiumEnd($value);
|
||||
break;
|
||||
|
||||
case 'blocked':
|
||||
if($value)
|
||||
{
|
||||
$this->block();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->unblock();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'deleted':
|
||||
if($value)
|
||||
{
|
||||
@@ -1259,5 +1198,3 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -34,5 +34,3 @@ class OTS_AccountBans_List extends OTS_Bans_List
|
||||
$this->setFilter($filter);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@@ -735,5 +735,3 @@ class OTS_Admin
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -100,5 +100,3 @@ class OTS_Bans_List extends OTS_Base_List
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@@ -265,5 +265,3 @@ abstract class OTS_Base_DB extends PDO implements IOTS_DB
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -146,5 +146,3 @@ class OTS_BinaryTools
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -149,5 +149,3 @@ class OTS_Container extends OTS_Item implements IteratorAggregate
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -357,5 +357,3 @@ class OTS_FileLoader
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
@@ -671,5 +671,3 @@ class OTS_Group extends OTS_Row_DAO implements IteratorAggregate, Countable
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
|
||||
?>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user