Compare commits

..

101 Commits

Author SHA1 Message Date
slawkens
0342293847 Merge branch 'develop' into feature/settings 2023-08-05 20:52:35 +02:00
slawkens
cb6e777c69 Move rest of config to settings
Remove config.php completely
Add new settings category: Game
Fix account_login_by_email
Min textarea size = 2 + adjusted automatically
2023-08-05 09:38:26 +02:00
slawkens
eca896954c Every setting needs to have default 2023-08-04 15:47:32 +02:00
slawkens
18bb23d969 Move create character blocked names down 2023-08-04 15:47:14 +02:00
slawkens
6890d531e5 add last_kills_limit to compat config 2023-07-30 14:39:56 +02:00
slawkens
3317dc48e8 Add database_hash setting 2023-07-30 14:39:37 +02:00
slawkens
8faa954a65 Merge branch 'develop' into feature/settings 2023-07-29 07:27:58 +02:00
slawkens
0f9b217567 Fix default value displaying 2023-07-22 15:01:00 +02:00
slawkens
03ab4a5eef Move database settings to separate category 2023-07-22 14:55:10 +02:00
slawkens
c6ce60c5d1 Merge branch 'develop' into feature/settings 2023-07-22 14:46:38 +02:00
slawkens
20dd49b1c5 Add new possibility: to deny saving setting if condition is not met 2023-07-22 14:37:57 +02:00
slawkens
3236f1aebb Merge branch 'develop' into feature/settings 2023-07-22 14:05:15 +02:00
slawkens
4d61b0ef85 Add super fancy No Refresh saving with a toast 2023-07-22 13:58:20 +02:00
slawkens
b433615e68 New setting: donate_column + move donate config to settings 2023-07-22 13:03:43 +02:00
slawkens
a2fcb21b4f Improve character npc name check 2023-07-22 11:35:05 +02:00
slawkens
b05780529a fixes 2023-07-22 11:17:58 +02:00
slawkens
da19a34335 New create character checks configurable: block monsters & spells names 2023-07-22 11:10:07 +02:00
slawkens
ea21e27cdc Fix for install warning - min/max length 2023-07-22 11:03:59 +02:00
slawkens
aad175548a create character name config moved to settings 2023-07-22 10:57:42 +02:00
slawkens
d82e3a21e5 Fix google_analytics 2023-07-22 10:43:23 +02:00
slawkens
191137282b Create character blocked words (by @gpedro), just moved to settings 2023-07-22 10:33:20 +02:00
slawkens
d7e6545156 add mail_lost_account_interval 2023-07-22 10:32:31 +02:00
slawkens
957421a98c google_analytics_id 2023-07-22 10:31:41 +02:00
slawkens
f35aba10ed Merge branch 'develop' into feature/settings 2023-07-22 09:58:38 +02:00
slawkens
81adeef01d add last_kills_limit + move shop 2023-07-22 09:52:06 +02:00
slawkens
b92b642078 Reword email settings + move two new settings 2023-07-22 09:48:44 +02:00
slawkens
baf9c9ea61 Enable script option 2023-07-22 09:35:54 +02:00
slawkens
8490b3b2a8 Update template.php 2023-07-21 21:22:06 +02:00
slawkens
f93e478326 Fix menu highlighting & opening 2023-07-21 21:21:59 +02:00
slawkens
d1a2ce25b2 Update 5-database.php 2023-07-21 20:43:45 +02:00
slawkens
94f8e3602c Merge branch 'develop' into feature/settings 2023-07-21 16:53:28 +02:00
slawkens
159f59242f Add more info into comment 2023-07-21 12:48:17 +02:00
slawkens
0765d3b9db Add more deprecated configs 2023-07-21 12:47:41 +02:00
slawkens
a82672c015 Merge branch 'develop' into feature/settings 2023-07-21 11:59:01 +02:00
slawkens
571602e79c Fix create account, if account_create_character_create is enabled 2023-07-21 11:52:34 +02:00
slawkens
160ed3b237 Remove configs from previous commit 2023-07-21 11:39:25 +02:00
slawkens
1543dd864e Save config.php in Settings
Egg and hen problem solved :)
* Test database connection on save settings -> prevents from making website unusable if connection is wrong
* Test server_path -> same
There is no config.php anymore, just config.local.php, which can be edited manually and also from admin panel
2023-07-21 11:38:52 +02:00
slawkens
399f263b42 Rename variable 2023-07-21 06:05:33 +02:00
slawkens
1b2fd39ea7 Move news config to settings 2023-07-20 21:01:33 +02:00
slawkens
ed7daf9482 Move signature config to settings 2023-07-20 20:52:08 +02:00
slawkens
978090c8ae More config to settings: account_types, genders, highscores, admin 2023-07-20 20:24:07 +02:00
slawkens
ac3a6c36d5 Remove whitespaces 2023-07-20 18:13:06 +02:00
slawkens
a8a2c72381 Move status config to settings 2023-07-20 18:12:22 +02:00
slawkens
55a5ccdd1e Move forum config to settings 2023-07-20 16:36:59 +02:00
slawkens
a7b8ccaee2 Merge branch 'develop' into feature/settings 2023-07-20 14:24:46 +02:00
slawkens
afa1adb90b Add settings.callbacks.get 2023-07-13 16:47:09 +02:00
slawkens
e83880653a Extract Settings:save function 2023-07-13 15:29:19 +02:00
slawkens
4af944a00b Change variable name 2023-07-13 15:20:13 +02:00
slawkens
48ceada956 Rename team_* variables + add to deprecated 2023-07-13 15:13:15 +02:00
slawkens
e7ef1679a0 nothing important 2023-07-13 13:04:31 +02:00
slawkens
228b2d071b Add: show_if - account_mail_verify 2023-07-13 13:04:22 +02:00
slawkens
1ea9a76ea9 Fix: check on page load if radio button is checked 2023-07-13 13:03:52 +02:00
slawkens
c7c8ff266b Hide section title on show_if 2023-07-13 12:10:07 +02:00
slawkens
b062c424d8 Merge branch 'develop' into feature/settings 2023-07-13 11:08:48 +02:00
slawkens
c886384f2c Merge branch 'develop' into feature/settings 2023-07-08 19:16:22 +02:00
slawkens
250d89482e guild_management: show_if 2023-05-17 06:12:10 +02:00
slawkens
2f8ee7a7eb Add new function: only_if, to hide fields when they are not enabled [WIP]
Not fully finished yet
2023-05-17 06:07:52 +02:00
slawkens
7aff4557a6 Lets call it settings.name instead 2023-05-16 14:17:21 +02:00
slawkens
481ba5a30f More detailed error message in settings 2023-05-16 12:47:58 +02:00
slawkens
52dc459704 Better boolean detection 2023-05-16 12:46:45 +02:00
slawkens
dc3477d68d Nothing important 2023-05-16 12:46:02 +02:00
slawkens
24ab125d28 Add Settings menu, including all plugins with settings
One change included in previous commit, due to missclick
2023-05-16 11:44:13 +02:00
slawkens
939508e799 Re-enable plugin if disabled and already installed 2023-05-16 11:41:44 +02:00
slawkens
433ccff851 Add min, max, step to number field option 2023-05-16 11:37:38 +02:00
slawkens
7929967ddc [WIP] More work on settings
Move more config to settings (mainly mail_* + some other)
Remove mail_admin, wasnt used anywhere
Add return type to some functions
Add Twig settings(key) function
Possibility to save setting to db
2023-05-15 23:14:13 +02:00
slawkens
449fc2c1cf Fix path 2023-05-15 17:05:30 +02:00
slawkens
bd0570ac30 Rename 2023-05-15 17:00:41 +02:00
slawkens
1fa6788310 [WIP] Some work on settings
Add hidden settings
New method: parse, to parse settings from array
Move base html to twig template
Remove vocation loading from .xml, instead use predefined voc names
2023-05-15 00:22:27 +02:00
slawkens
44d5d7ae64 Merge branch 'develop' into feature/settings 2023-05-13 12:57:11 +02:00
slawkens
7723f87bbf Merge branch 'develop' into feature/settings 2023-05-13 12:06:36 +02:00
slawkens
034c369ddb Update plugins.php 2023-05-09 21:54:00 +02:00
slawkens
4e5a0a6134 Execute migrations just after db connect 2023-05-09 21:53:55 +02:00
slawkens
3067b79363 Add 36th migration for settings table 2023-05-09 21:53:12 +02:00
slawkens
40c00a1434 Merge branch 'develop' into feature/settings 2023-05-08 13:05:22 +02:00
slawkens
c72bc39aac Update .gitignore 2023-02-14 16:36:25 +01:00
slawkens
b29c5c6aa6 fix typo 2023-02-14 16:10:06 +01:00
slawkens
07486762dc Add categories in tabs, move more settings, revert back getPluginSettings
Categories and sections are now not numbered
Remove example settings plugin
2023-02-14 16:03:22 +01:00
slawkens
50fe38d5fc add missing hook 2023-02-08 15:22:14 +01:00
slawkens
5d48a69649 php 8 compatibility 2023-02-08 15:22:03 +01:00
slawkens
1345ad97d5 add settings migration 2023-02-08 15:03:40 +01:00
slawkens
1340b8e63e Merge branch 'develop' into feature/settings 2023-02-08 15:02:56 +01:00
slawkens
4dbcad5ad5 Merge branch 'develop' into feature/settings 2021-06-08 22:06:21 +02:00
slawkens
6035d05d65 Update 33.php 2021-03-08 14:44:09 +01:00
slawkens
dfd78b9735 Merge branch 'develop' into feature/settings 2021-03-05 10:10:51 +01:00
slawkens
6edc90c82c Add email + password fields as type 2020-06-20 08:48:31 +02:00
slawkens
084e191b28 Add Sections + Add setting($key) function
Reorganisation
2020-06-09 23:48:31 +02:00
slawkens
96068d003b Add Settings menu 2020-06-09 01:44:13 +02:00
slawkens
a6e20fa62c Change name to settings 2020-06-09 01:43:07 +02:00
slawkens
df0ad6e277 Change options.php to settings.php 2020-06-09 01:40:28 +02:00
slawkens
fa0de1c413 Settings [WIP]
New Settings class
New Plugins::load() method
Move config.php to settings.php
MyAAC Settings will have plugin_name = 'core'
Add compat_config.php
2020-06-09 01:39:55 +02:00
slawkens
909bfffb51 Move $menus to menus.php
Also fix active link when menu item has subpage
2020-06-09 01:36:07 +02:00
slawkens
7b1aed7a94 Remove useless title_separator from config 2020-06-09 00:48:19 +02:00
slawkens
78ba282a1b Add $member var annotation 2020-06-06 17:10:34 +02:00
slawkens
5362c4970f Add $limit parameter to $db->select method 2020-06-06 17:08:41 +02:00
slawkens
90cab6d3ee New myaac_settings table 2020-06-06 09:26:17 +02:00
slawkens
e462348db0 Merge branch 'develop' into feature/settings 2020-06-06 09:17:23 +02:00
slawkens
69bbb375e2 Merge branch 'develop' into plugin-options 2020-06-06 08:00:05 +02:00
slawkens
d89d8cdf8d Add Settings Class 2020-06-06 07:55:26 +02:00
slawkens
cdef0796a7 Rename to settings.php 2020-06-06 07:52:31 +02:00
slawkens
7469f13254 Forgot the plugin example of options 2020-05-15 00:06:03 +02:00
slawkens
89d82e5117 New admin panel Pages: Options + Config [WIP] 2020-05-14 23:59:37 +02:00
408 changed files with 9353 additions and 7813 deletions

View File

@@ -15,5 +15,5 @@ trim_trailing_whitespace = false
[{composer.json,package.json}] [{composer.json,package.json}]
indent_style = space indent_style = space
[{package.json, *.yml}] [package.json]
indent_size = 2 indent_size = 2

1
.gitattributes vendored
View File

@@ -9,5 +9,6 @@ release.sh export-ignore
# cypress # cypress
cypress export-ignore cypress export-ignore
cypress.config.js export-ignore cypress.config.js export-ignore
cypress.env.json
*.sh text eol=lf *.sh text eol=lf

View File

@@ -22,9 +22,8 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
php-versions: [ '8.1', '8.2', '8.3' ] php-versions: [ '7.4', '8.0', '8.1' ]
ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration) name: MyAAC on PHP ${{ matrix.php-versions }}
name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }})
steps: steps:
- name: 📌 MySQL Start & init & show db - name: 📌 MySQL Start & init & show db
run: | run: |
@@ -33,81 +32,47 @@ jobs:
mysql -e "SHOW DATABASES" -uroot -proot mysql -e "SHOW DATABASES" -uroot -proot
- name: Checkout MyAAC - name: Checkout MyAAC
uses: actions/checkout@v4 uses: actions/checkout@v3
with: with:
ref: develop ref: 0.9
- uses: actions/setup-node@v4
with:
node-version: 18
- run: npm ci
- name: Checkout TFS - name: Checkout TFS
uses: actions/checkout@v4 uses: actions/checkout@v3
if: matrix.ots == 'tfs-1.4'
with: with:
repository: otland/forgottenserver repository: otland/forgottenserver
ref: 1.4 ref: 1.4
path: ots path: tfs
- name: Checkout TFS - name: Import TFS Schema
uses: actions/checkout@v4
if: matrix.ots == 'tfs-master'
with:
repository: otland/forgottenserver
ref: master
path: ots
- name: Checkout Canary
uses: actions/checkout@v4
if: matrix.ots == 'canary-3.1.2'
with:
repository: opentibiabr/canary
ref: v3.1.2
path: ots
- name: Import OTS Schema
run: | run: |
mysql -uroot -proot myaac < ots/schema.sql mysql -uroot -proot myaac < tfs/schema.sql
- name: Rename config.lua - name: Rename config.lua
run: mv ots/config.lua.dist ots/config.lua run: mv tfs/config.lua.dist tfs/config.lua
- name: Replace mysqlUser (TFS 1.4) - name: Replace mysqlUser
uses: jacobtomlinson/gha-find-replace@v3 uses: jacobtomlinson/gha-find-replace@v2
if: matrix.ots == 'tfs-1.4'
with: with:
find: 'mysqlUser = "forgottenserver"' find: 'mysqlUser = "forgottenserver"'
replace: 'mysqlUser = "root"' replace: 'mysqlUser = "root"'
regex: false regex: false
include: 'ots/config.lua' include: 'tfs/config.lua'
- name: Replace mysqlPass (TFS 1.4) - name: Replace mysqlPass
uses: jacobtomlinson/gha-find-replace@v3 uses: jacobtomlinson/gha-find-replace@v2
if: matrix.ots == 'tfs-1.4'
with: with:
find: 'mysqlPass = ""' find: 'mysqlPass = ""'
replace: 'mysqlPass = "root"' replace: 'mysqlPass = "root"'
regex: false regex: false
include: 'ots/config.lua' include: 'tfs/config.lua'
- name: Replace mysqlDatabase (TFS 1.4) - name: Replace mysqlDatabase
uses: jacobtomlinson/gha-find-replace@v3 uses: jacobtomlinson/gha-find-replace@v2
if: matrix.ots == 'tfs-1.4'
with: with:
find: 'mysqlDatabase = "forgottenserver"' find: 'mysqlDatabase = "forgottenserver"'
replace: 'mysqlDatabase = "myaac"' replace: 'mysqlDatabase = "myaac"'
regex: false regex: false
include: 'ots/config.lua' include: 'tfs/config.lua'
- name: Replace mysqlDatabase (Canary)
uses: jacobtomlinson/gha-find-replace@v3
if: matrix.ots == 'canary-3.1.2'
with:
find: 'mysqlDatabase = "otservbr-global"'
replace: 'mysqlDatabase = "myaac"'
regex: false
include: 'ots/config.lua'
- name: Setup PHP - name: Setup PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@@ -120,13 +85,13 @@ jobs:
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer dependencies - name: Cache composer dependencies
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: ${{ steps.composer-cache.outputs.dir }} path: ${{ steps.composer-cache.outputs.dir }}
# Use composer.json for key, if composer.lock is not committed. # Use composer.json for key, if composer.lock is not committed.
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
#key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer-
- name: Install Composer dependencies - name: Install Composer dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader run: composer install --no-progress --prefer-dist --optimize-autoloader
@@ -135,28 +100,21 @@ jobs:
run: nohup php -S localhost:8080 > php.log 2>&1 & run: nohup php -S localhost:8080 > php.log 2>&1 &
- name: Cypress Run - name: Cypress Run
uses: cypress-io/github-action@v6 uses: cypress-io/github-action@v5
env: env:
CYPRESS_URL: http://localhost:8080 CYPRESS_URL: http://localhost:8080
CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/ots CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/tfs
- name: Save screenshots - name: Save screenshots
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
if: always() if: always()
with: with:
name: cypress-screenshots-${{ matrix.php-versions }}-${{ matrix.ots }} name: cypress-screenshots
path: cypress/screenshots path: cypress/screenshots
- name: Upload Cypress Videos - name: Upload Cypress Videos
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
if: always() if: always()
with: with:
name: cypress-videos-${{ matrix.php-versions }}-${{ matrix.ots }} name: cypress-videos
path: cypress/videos path: cypress/videos
- name: Upload PHP Logs
uses: actions/upload-artifact@v4
if: always()
with:
name: php-log-${{ matrix.php-versions }}-${{ matrix.ots }}
path: php.log

View File

@@ -1,47 +0,0 @@
name: "PHPStan"
on:
pull_request:
branches: [develop]
push:
branches: [develop]
jobs:
tests:
name: PhpStan on PHP ${{ matrix.php-versions }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-versions: [ '8.1', '8.2', '8.3' ]
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
extensions: "intl, zip"
ini-values: "memory_limit=-1"
php-version: "${{ matrix.php-version }}"
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
# Use composer.json for key, if composer.lock is not committed.
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
#key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
- name: "Install composer dependencies"
run: "composer install"
- name: "Run PHPStan"
run: "/usr/bin/php vendor/bin/phpstan analyse"

10
.gitignore vendored
View File

@@ -6,18 +6,15 @@ Thumbs.db
/.htaccess /.htaccess
# composer # composer
composer.phar
composer.lock composer.lock
vendor vendor
# npm # npm
node_modules node_modules
tools/ext
# cypress # cypress
cypress.env.json cypress.env.json
cypress/e2e/2-advanced-examples cypress/e2e/2-advanced-examples
cypress/screenshots
# created by release.sh # created by release.sh
releases releases
@@ -38,19 +35,12 @@ images/guilds/*
images/editor/* images/editor/*
!images/editor/index.html !images/editor/index.html
# gallery images
images/gallery/*
!images/gallery/index.html
!images/gallery/demon.jpg
!images/gallery/demon_thumb.gif
# cache # cache
system/cache/* system/cache/*
!system/cache/index.html !system/cache/index.html
!system/cache/twig/index.html !system/cache/twig/index.html
!system/cache/signatures/index.html !system/cache/signatures/index.html
!system/cache/plugins/index.html !system/cache/plugins/index.html
!system/cache/persistent/index.html
# logs # logs
system/logs/* system/logs/*

View File

@@ -1,8 +1,8 @@
# Changelog # Changelog
## [1.0-beta - 02.02.2024] ## [0.9.0-alpha - 02.06.2023]
Minimum PHP version for this release is 8.1. Minimum PHP version for this release is 7.2.5.
### Added ### Added
* reworked Admin Panel (@Leesneaks, @gpedro, @slawkens) * reworked Admin Panel (@Leesneaks, @gpedro, @slawkens)
@@ -11,26 +11,17 @@ Minimum PHP version for this release is 8.1.
* new Dashboard: statistics, server status * new Dashboard: statistics, server status
* new Admin Bar showed on top when admin logged in * new Admin Bar showed on top when admin logged in
* new page: Server Data, to reload server data * new page: Server Data, to reload server data
* Towns, NPCs & Items are stored in permanent cache
* new pages: mass account & teleport tools * new pages: mass account & teleport tools
* changelogs editor * changelogs editor
* revised Accounts & Players editors * revised Accounts & Players editors
* option to add/modify admin menus with plugins * option to add/modify menus with plugins
* option to enable/disable plugins * option to enable/disable plugins
* better, updated TinyMCE editor (v6.x) * better, updated TinyMCE editor (v6.x)
* with option to upload images * with option to upload images
* list of open source libraries used in project page * list of open source libraries used in project
* auto-loading of themes, commands & pages from plugins/ folder. You need just to place them in correct folder and they will be loaded automatically - this allows better customization, without interfering with core AAC folders. This will allow in the future automatic updates for plugins as well the AAC as whole.
* config.php moved to Admin Panel -> Settings page
* new console script: aac (comes from MyAAC) - using symfony/console
* usage: `php aac` (will list all commands by default)
* example: `php aac cache:clear`
* example: `php aac plugin:install theme-example.zip`
* replace POT Query Builder to Eloquent ORM. Not 100% yet - in some places there is still old $db approach used (@gpedro) (https://github.com/slawkens/myaac/pull/230)
* brand new charming installation page (by @fernandomatos) * brand new charming installation page (by @fernandomatos)
* using Bootstrap * using Bootstrap
* new pages router: nikic/fast-route, allowing for better customisation * new pages router: nikic/fast-route, allowing for better customisation
* Plugin cronjobs: central control of the cronjobs
* Guild Wars support (available as plugin) * Guild Wars support (available as plugin)
* support for login and create account only by email (configurable) * support for login and create account only by email (configurable)
* with no need for account name * with no need for account name
@@ -40,10 +31,7 @@ Minimum PHP version for this release is 8.1.
* suggest account number option * suggest account number option
* many new functions, hooks and configurables * many new functions, hooks and configurables
* better Exception Handler (Whoops - https://github.com/filp/whoops) * better Exception Handler (Whoops - https://github.com/filp/whoops)
* automated website tests (using Cypress) * add Cypress testing
* csrf protection (https://github.com/slawkens/myaac/pull/235)
* option to restrict Page view to specified group of users (Not-Logged in, logged-in players, tutors, gamemasters etc.)
* phpdebug bar (http://phpdebugbar.com/). Activated if env == 'dev', can be also activated in production by enabling "enable_debugbar" in local config
### Changed ### Changed
* Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc. * Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc.
@@ -57,7 +45,7 @@ Minimum PHP version for this release is 8.1.
* Highscores * Highscores
* frags works for TFS 1.x * frags works for TFS 1.x
* cached * cached
* Monsters * creatures
* moved pages to Twig: * moved pages to Twig:
* experience stages * experience stages
* update player_deaths entries on name change * update player_deaths entries on name change

View File

@@ -8,11 +8,7 @@ Fernando Matos <fernando@pixele.com.br>
Lee <42119604+Leesneaks@users.noreply.github.com> Lee <42119604+Leesneaks@users.noreply.github.com>
caio <caio.zucoli@gmail.com> caio <caio.zucoli@gmail.com>
slawkens <slawkens@gmail.com> slawkens <slawkens@gmail.com>
tobi132 <tobi132@gmx.net> tobi132 <52947952+tobi132@users.noreply.github.com>
vankk <nwtr.otland@hotmail.com> vankk <nwtr.otland@hotmail.com>
whiteblXK <krzys16001@gmail.com> whiteblXK <krzys16001@gmail.com>
xitobuh <jonas.hockert92@gmail.com> xitobuh <jonas.hockert92@gmail.com>
Danilo Pucci <dnlps@hotmail.com>
gpedro <gpedro831@gmail.com>
Matheus Collier <matheuscollier@gmail.com>
SRNT-GG <95472530+SRNT-GG@users.noreply.github.com>

View File

@@ -1,29 +1,24 @@
# [MyAAC](https://my-aac.org) # [MyAAC](https://my-aac.org)
[![Build Status Master](https://img.shields.io/travis/slawkens/myaac/master)](https://travis-ci.org/github/slawkens/myaac)
[![License: GPL-3.0](https://img.shields.io/github/license/slawkens/myaac)](https://opensource.org/licenses/gpl-license)
[![Downloads Count](https://img.shields.io/github/downloads/slawkens/myaac/total)](https://github.com/slawkens/myaac/releases)
[![PHP Versions](https://img.shields.io/travis/php-v/slawkens/myaac/master)](https://github.com/slawkens/myaac/blob/d8b3b4135827ee17e3c6d41f08a925e718c587ed/.travis.yml#L3)
[![OpenTibia Discord](https://img.shields.io/discord/288399552581468162)](https://discord.gg/2J39Wus)
[![Closed Issues](https://img.shields.io/github/issues-closed-raw/slawkens/myaac)](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed)
MyAAC is a free and open-source Automatic Account Creator (AAC) written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases. MyAAC is a free and open-source Automatic Account Creator (AAC) written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases.
Official website: https://my-aac.org Official website: https://my-aac.org
[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/slawkens/myaac/cypress.yml)](https://github.com/slawkens/myaac/actions)
[![License: GPL-3.0](https://img.shields.io/github/license/slawkens/myaac)](https://opensource.org/licenses/gpl-license)
[![Downloads Count](https://img.shields.io/github/downloads/slawkens/myaac/total)](https://github.com/slawkens/myaac/releases)
[![OpenTibia Discord](https://img.shields.io/discord/288399552581468162)](https://discord.gg/2J39Wus)
[![Closed Issues](https://img.shields.io/github/issues-closed-raw/slawkens/myaac)](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed)
| Version | Status | Branch | Requirements |
|:--------|:-----------------------|:--------|:---------------|
| **1.x** | **Active development** | develop | **PHP >= 8.1** |
| 0.9.x | Not developed anymore | 0.9 | PHP >= 7.2.5 |
| 0.8.x | Active support | master | PHP >= 7.2.5 |
| 0.7.x | End Of Life | 0.7 | PHP >= 5.3.3 |
### Requirements ### Requirements
- PHP 5.6 or later
- MySQL database - MySQL database
- PHP Extensions: pdo, xml, json - PDO PHP Extension
- (optional) apache2 mod_rewrite (to use friendly_urls) - XML PHP Extension
- (optional) zip PHP Extension (to install plugins) - ZIP PHP Extension
- (optional) gd PHP Extension (for generating signature images) - (optional) mod_rewrite to use friendly_urls
### Installation ### Installation
@@ -47,8 +42,7 @@ Official website: https://my-aac.org
### Configuration ### Configuration
Check *config.php* to get more informations. (Notice: MyAAC 1.0+ doesn't use config.php anymore, it has been moved to Admin Panel - Settings page). Check *config.php* to get more informations.
Use *config.local.php* for your local configuration changes. Use *config.local.php* for your local configuration changes.
### Branches ### Branches
@@ -77,13 +71,7 @@ Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our w
### Other Notes ### Other Notes
If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org
## Project supported by JetBrains
Many thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects.
[![JetBrains](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://www.jetbrains.com/?from=https://github.com/slawkens)
### License ### License

40
aac
View File

@@ -1,40 +0,0 @@
#!/usr/bin/env php
<?php
require_once __DIR__ . '/common.php';
if(!IS_CLI) {
echo 'This script can be run only in command line mode.';
exit(1);
}
require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php';
define('SELF_NAME', basename(__FILE__));
use MyAAC\Plugins;
use Symfony\Component\Console\Application;
$application = new Application();
$commandsGlob = glob(SYSTEM . 'src/Commands/*.php');
foreach ($commandsGlob as $item) {
$name = pathinfo($item, PATHINFO_FILENAME);
if ($name == 'Command') { // ignore base Command class
continue;
}
$commandPre = '\\MyAAC\Commands\\';
$application->add(new ($commandPre . $name));
}
$pluginCommands = Plugins::getCommands();
foreach ($pluginCommands as $item) {
$application->add(require $item);
}
$application->setName('MyAAC');
$application->setVersion(MYAAC_VERSION);
$application->run();

View File

@@ -1,22 +0,0 @@
<?php
$hooks->register('debugbar_admin_head_end', HOOK_ADMIN_HEAD_END, function ($params) {
global $debugBar;
if (!isset($debugBar)) {
return;
}
$debugBarRenderer = $debugBar->getJavascriptRenderer();
echo $debugBarRenderer->renderHead();
});
$hooks->register('debugbar_admin_body_end', HOOK_ADMIN_BODY_END, function ($params) {
global $debugBar;
if (!isset($debugBar)) {
return;
}
$debugBarRenderer = $debugBar->getJavascriptRenderer();
echo $debugBarRenderer->render();
});

View File

@@ -1,7 +1,5 @@
<?php <?php
use MyAAC\Plugins;
$order = 10; $order = 10;
$settingsMenu = []; $settingsMenu = [];

View File

@@ -25,7 +25,16 @@ define('PAGE', $page);
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';
require __DIR__ . '/includes/debugbar.php'; // verify myaac tables exists in database
if(!$db->hasTable('myaac_account_actions')) {
throw new RuntimeException('Seems that the table <strong>myaac_account_actions</strong> of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting <a href="' . BASE_URL . 'install">this</a> url.');
}
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
require SYSTEM . 'status.php'; require SYSTEM . 'status.php';
require SYSTEM . 'login.php'; require SYSTEM . 'login.php';
require __DIR__ . '/includes/functions.php'; require __DIR__ . '/includes/functions.php';
@@ -45,7 +54,7 @@ if(!$logged || !admin()) {
// include our page // include our page
$file = __DIR__ . '/pages/' . $page . '.php'; $file = __DIR__ . '/pages/' . $page . '.php';
if(!@file_exists($file)) { if(!@file_exists($file)) {
if (str_contains($page, 'plugins/')) { if (strpos($page, 'plugins/') !== false) {
$file = BASE . $page; $file = BASE . $page;
} }
else { else {

View File

@@ -7,19 +7,13 @@
* @copyright 2020 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Account editor'; $title = 'Account editor';
csrfProtect();
$admin_base = ADMIN_URL . '?p=accounts'; $admin_base = ADMIN_URL . '?p=accounts';
$use_datatable = true; $use_datatable = true;
if (setting('core.account_country')) if ($config['account_country'])
require SYSTEM . 'countries.conf.php'; require SYSTEM . 'countries.conf.php';
$nameOrNumberColumn = 'name'; $nameOrNumberColumn = 'name';
@@ -33,7 +27,7 @@ $hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$hasTypeColumn = $db->hasColumn('accounts', 'type'); $hasTypeColumn = $db->hasColumn('accounts', 'type');
$hasGroupColumn = $db->hasColumn('accounts', 'group_id'); $hasGroupColumn = $db->hasColumn('accounts', 'group_id');
if (setting('core.account_country')) { if ($config['account_country']) {
$countries = array(); $countries = array();
foreach (array('pl', 'se', 'br', 'us', 'gb') as $c) foreach (array('pl', 'se', 'br', 'us', 'gb') as $c)
$countries[$c] = $config['countries'][$c]; $countries[$c] = $config['countries'][$c];
@@ -85,7 +79,7 @@ else if (isset($_REQUEST['search'])) {
$account = new OTS_Account(); $account = new OTS_Account();
$account->load($id); $account->load($id);
if (isset($_POST['save']) && $account->isLoaded()) { if (isset($account, $_POST['save']) && $account->isLoaded()) {
$error = false; $error = false;
$_error = ''; $_error = '';
@@ -269,9 +263,6 @@ else if (isset($_REQUEST['search'])) {
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a> <a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a>
</li> </li>
<li class="nav-item">
<a class="nav-link" id="accounts-logs-tab" data-toggle="pill" href="#accounts-logs">Logs</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a> <a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a>
</li> </li>
@@ -281,7 +272,7 @@ else if (isset($_REQUEST['search'])) {
</li> </li>
<?php endif; <?php endif;
if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) : ?> if ($db->hasTable('store_history')) : ?>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a> <a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a>
</li> </li>
@@ -291,8 +282,7 @@ else if (isset($_REQUEST['search'])) {
<div class="card-body"> <div class="card-body">
<div class="tab-content" id="accounts-tabContent"> <div class="tab-content" id="accounts-tabContent">
<div class="tab-pane fade active show" id="accounts-acc"> <div class="tab-pane fade active show" id="accounts-acc">
<form action="<?php echo $admin_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post"> <form action="<?php echo $admin_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post">
<?php csrf(); ?>
<div class="form-group row"> <div class="form-group row">
<?php if (USE_ACCOUNT_NAME): ?> <?php if (USE_ACCOUNT_NAME): ?>
<div class="col-12 col-sm-12 col-lg-4"> <div class="col-12 col-sm-12 col-lg-4">
@@ -331,8 +321,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group">Account Type:</label> <label for="group">Account Type:</label>
<select name="group" id="group" class="form-control"> <select name="group" id="group" class="form-control">
<?php foreach ($acc_type as $_id => $a_type): ?> <?php foreach ($acc_type as $id => $a_type): ?>
<option value="<?php echo($_id); ?>" <?php echo($acc_group == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($id); ?>" <?php echo($acc_group == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -342,8 +332,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group">Account Type:</label> <label for="group">Account Type:</label>
<select name="group" id="group" class="form-control"> <select name="group" id="group" class="form-control">
<?php foreach ($groups->getGroups() as $_id => $group): ?> <?php foreach ($groups->getGroups() as $id => $group): ?>
<option value="<?php echo $_id; ?>" <?php echo($acc_group == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option> <option value="<?php echo $id; ?>" <?php echo($acc_group == $id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -351,8 +341,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="web_flags">Website Access:</label> <label for="web_flags">Website Access:</label>
<select name="web_flags" id="web_flags" class="form-control"> <select name="web_flags" id="web_flags" class="form-control">
<?php foreach ($web_acc as $_id => $a_type): ?> <?php foreach ($web_acc as $id => $a_type): ?>
<option value="<?php echo($_id); ?>" <?php echo($account->getWebFlags() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($id); ?>" <?php echo($account->getWebFlags() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -407,8 +397,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="rl_country">Country:</label> <label for="rl_country">Country:</label>
<select name="rl_country" id="rl_country" class="form-control"> <select name="rl_country" id="rl_country" class="form-control">
<?php foreach ($countries as $_id => $a_type): ?> <?php foreach ($countries as $id => $a_type): ?>
<option value="<?php echo($_id); ?>" <?php echo($account->getCountry() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($id); ?>" <?php echo($account->getCountry() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -430,39 +420,12 @@ else if (isset($_REQUEST['search'])) {
<a href="<?php echo ADMIN_URL; ?>?p=accounts" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a> <a href="<?php echo ADMIN_URL; ?>?p=accounts" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a>
</form> </form>
</div> </div>
<div class="tab-pane fade" id="accounts-logs">
<div class="row">
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Action</th>
<th>IP</th>
</tr>
</thead>
<tbody>
<?php
$accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
foreach ($accountActions as $i => $log):
$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6));
?>
<tr>
<td><?php echo $i + 1; ?></td>
<td><?= date("M d Y, H:i:s", $log->date); ?></td>
<td><?= $log->action; ?></td>
<td><?= $log->ip; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="tab-pane fade" id="accounts-chars"> <div class="tab-pane fade" id="accounts-chars">
<div class="row"> <div class="row">
<?php <?php
if (isset($account) && $account->isLoaded()) { if (isset($account) && $account->isLoaded()) {
$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get(); $account_players = $account->getPlayersList();
$account_players->orderBy('id');
if (isset($account_players)) { ?> if (isset($account_players)) { ?>
<table class="table table-striped table-condensed table-responsive d-md-table"> <table class="table table-striped table-condensed table-responsive d-md-table">
<thead> <thead>
@@ -475,13 +438,25 @@ else if (isset($_REQUEST['search'])) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach ($account_players as $i => $player): ?> <?php $i= 0;
foreach ($account_players as $i => $player):
$i++;
$player_vocation = $player->getVocation();
$player_promotion = $player->getPromotion();
if (isset($player_promotion)) {
if ((int)$player_promotion > 0)
$player_vocation += ($player_promotion * $config['vocations_amount']);
}
if (isset($config['vocations'][$player_vocation])) {
$vocation_name = $config['vocations'][$player_vocation];
} ?>
<tr> <tr>
<th><?php echo $i + 1; ?></th> <th><?php echo $i; ?></th>
<td><?php echo $player->name; ?></td> <td><?php echo $player->getName(); ?></td>
<td><?php echo $player->level; ?></td> <td><?php echo $player->getLevel(); ?></td>
<td><?php echo $player->vocation_name; ?></td> <td><?php echo $vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td> <td><a href="?p=players&id=<?php echo $player->getId() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
</tr> </tr>
<?php endforeach ?> <?php endforeach ?>
</tbody> </tbody>
@@ -548,7 +523,7 @@ else if (isset($_REQUEST['search'])) {
} ?> } ?>
</div> </div>
<?php endif; <?php endif;
if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) { ?> if ($db->hasTable('store_history')) { ?>
<div class="tab-pane fade" id="accounts-store"> <div class="tab-pane fade" id="accounts-store">
<?php $store_history = $db->query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?> <?php $store_history = $db->query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?>
<table class="table table-striped table-condensed table-responsive d-md-table"> <table class="table table-striped table-condensed table-responsive d-md-table">
@@ -585,20 +560,18 @@ else if (isset($_REQUEST['search'])) {
<div class="row"> <div class="row">
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post"> <form action="<?php echo $admin_base; ?>" method="post">
<?php csrf(); ?> <label for="name">Account Name:</label>
<label for="search">Account Name:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_account); ?>" maxlength="32" size="32"> <input type="text" class="form-control" name="search" value="<?php echo $search_account; ?>" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>
</div> </div>
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post"> <form action="<?php echo $admin_base; ?>" method="post">
<?php csrf(); ?> <label for="name">Account ID:</label>
<label for="id">Account ID:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32"> <input type="text" class="form-control" name="id" value="" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>

View File

@@ -8,34 +8,32 @@
* @copyright 2020 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Changelog;
use MyAAC\Models\Changelog as ModelsChangelog;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Changelog';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
} }
$title = 'Changelog';
$use_datatable = true; $use_datatable = true;
const CL_LIMIT = 600; // maximum changelog body length const CL_LIMIT = 600; // maximum changelog body length
?>
<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ >
<script src="<?php echo BASE_URL; ?>tools/js/jquery.datetimepicker.js"></script>
<?php
$id = $_GET['id'] ?? 0; $id = $_GET['id'] ?? 0;
require_once LIBS . 'changelog.php';
if(!empty($action) && isRequestMethod('post')) if(!empty($action))
{ {
$id = $_POST['id'] ?? null; $id = $_REQUEST['id'] ?? null;
$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null; $body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null;
$create_date = isset($_POST['createdate']) ? (int)strtotime($_POST['createdate'] ): null; $create_date = isset($_REQUEST['createdate']) ? (int)strtotime($_REQUEST['createdate'] ): null;
$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null; $player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null;
$type = isset($_POST['type']) ? (int)$_POST['type'] : null; $type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null;
$where = isset($_POST['where']) ? (int)$_POST['where'] : null; $where = isset($_REQUEST['where']) ? (int)$_REQUEST['where'] : null;
$errors = array(); $errors = array();
@@ -45,13 +43,12 @@ if(!empty($action) && isRequestMethod('post'))
$body = ''; $body = '';
$type = $where = $player_id = $create_date = 0; $type = $where = $player_id = $create_date = 0;
success('Added successful.'); success("Added successful.");
} }
} }
else if($action == 'delete') { else if($action == 'delete') {
if (Changelog::delete($id, $errors)) { Changelog::delete($id, $errors);
success('Deleted successful.'); success("Deleted successful.");
}
} }
else if($action == 'edit') else if($action == 'edit')
{ {
@@ -68,21 +65,20 @@ if(!empty($action) && isRequestMethod('post'))
$action = $body = ''; $action = $body = '';
$type = $where = $player_id = $create_date = 0; $type = $where = $player_id = $create_date = 0;
success('Updated successful.'); success("Updated successful.");
} }
} }
} }
else if($action == 'hide') { else if($action == 'hide') {
if (Changelog::toggleHide($id, $errors, $status)) { Changelog::toggleHidden($id, $errors, $status);
success(($status == 1 ? 'Hide' : 'Show') . ' successful.'); success(($status == 1 ? 'Show' : 'Hide') . " successful.");
}
} }
if(!empty($errors)) if(!empty($errors))
error(implode(", ", $errors)); error(implode(", ", $errors));
} }
$changelogs = ModelsChangelog::orderBy('id')->get()->toArray(); $changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog' . '` ORDER BY `id` DESC')->fetchAll();
$i = 0; $i = 0;
@@ -114,7 +110,7 @@ if($action == 'edit' || $action == 'new') {
$account_players->orderBy('group_id', POT::ORDER_DESC); $account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.changelog.form.html.twig', array( $twig->display('admin.changelog.form.html.twig', array(
'action' => $action, 'action' => $action,
'cl_link_form' => constant('ADMIN_URL').'?p=changelog', 'cl_link_form' => constant('ADMIN_URL').'?p=changelog&action=' . ($action == 'edit' ? 'edit' : 'new'),
'cl_id' => $id ?? null, 'cl_id' => $id ?? null,
'body' => isset($body) ? escapeHtml($body) : '', 'body' => isset($body) ? escapeHtml($body) : '',
'create_date' => $create_date ?? '', 'create_date' => $create_date ?? '',
@@ -129,3 +125,15 @@ if($action == 'edit' || $action == 'new') {
$twig->display('admin.changelog.html.twig', array( $twig->display('admin.changelog.html.twig', array(
'changelogs' => $changelogs, 'changelogs' => $changelogs,
)); ));
?>
<script>
$(document).ready(function () {
$('#createdate').datetimepicker({format: "M d Y, H:i:s",});
$('.tb_datatable').DataTable({
"order": [[0, "desc"]],
"columnDefs": [{targets: [1, 2,4,5],orderable: false}]
});
});
</script>

View File

@@ -10,9 +10,7 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Dashboard'; $title = 'Dashboard';
csrfProtect(); if (isset($_GET['clear_cache'])) {
if (isset($_POST['clear_cache'])) {
if (clearCache()) { if (clearCache()) {
success('Cache cleared.'); success('Cache cleared.');
} else { } else {
@@ -20,7 +18,7 @@ if (isset($_POST['clear_cache'])) {
} }
} }
if (isset($_POST['maintenance'])) { if (isset($_GET['maintenance'])) {
$message = (!empty($_POST['message']) ? $_POST['message'] : null); $message = (!empty($_POST['message']) ? $_POST['message'] : null);
$_status = (isset($_POST['status']) && $_POST['status'] == 'true'); $_status = (isset($_POST['status']) && $_POST['status'] == 'true');
$_status = ($_status ? '0' : '1'); $_status = ($_status ? '0' : '1');

View File

@@ -10,8 +10,6 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Login'; $title = 'Login';
csrfProtect();
require PAGES . 'account/login.php'; require PAGES . 'account/login.php';
if ($logged) { if ($logged) {
header('Location: ' . (admin() ? ADMIN_URL : BASE_URL)); header('Location: ' . (admin() ? ADMIN_URL : BASE_URL));

View File

@@ -10,8 +10,6 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mailer'; $title = 'Mailer';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
@@ -22,7 +20,7 @@ if (!setting('core.mail_enabled')) {
return; return;
} }
$mail_to = isset($_POST['mail_to']) ? stripslashes(trim($_POST['mail_to'])) : null; $mail_to = isset($_REQUEST['mail_to']) ? stripslashes(trim($_REQUEST['mail_to'])) : null;
$mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null; $mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null;
$mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null; $mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null;
@@ -56,7 +54,7 @@ if (!empty($mail_content) && !empty($mail_subject) && empty($mail_to)) {
$failed = 0; $failed = 0;
$add = ''; $add = '';
if (setting('core.account_mail_verify')) { if (config('account_mail_verify')) {
note('Note: Sending only to users with verified E-Mail.'); note('Note: Sending only to users with verified E-Mail.');
$add = ' AND `email_verified` = 1'; $add = ' AND `email_verified` = 1';
} }

View File

@@ -9,15 +9,10 @@
* @copyright 2020 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Account Actions'; $title = 'Mass Account Actions';
csrfProtect();
$hasCoinsColumn = $db->hasColumn('accounts', 'coins'); $hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); $hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$freePremium = $config['lua']['freePremium']; $freePremium = $config['lua']['freePremium'];
@@ -31,14 +26,15 @@ function admin_give_points($points)
return; return;
} }
$statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points'); $statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points');
if (!$statement) { if (!$statement) {
displayMessage('Failed to prepare query statement.'); displayMessage('Failed to prepare query statement.');
return; return;
} }
if (!Account::query()->increment('premium_points', $points)) { if (!$statement->execute([
'points' => $points
])) {
displayMessage('Failed to add points.'); displayMessage('Failed to add points.');
return; return;
} }
@@ -54,7 +50,15 @@ function admin_give_coins($coins)
return; return;
} }
if (!Account::query()->increment('coins', $coins)) { $statement = $db->prepare('UPDATE `accounts` SET `coins` = `coins` + :coins');
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return;
}
if (!$statement->execute([
'coins' => $coins
])) {
displayMessage('Failed to add coins.'); displayMessage('Failed to add coins.');
return; return;
} }
@@ -162,9 +166,9 @@ function admin_give_premdays($days)
displayMessage('Premium Days not supported.'); displayMessage('Premium Days not supported.');
} }
if (!empty(ACTION) && isRequestMethod('post')) { if (isset($_POST['action']) && $_POST['action']) {
$action = ACTION; $action = $_POST['action'];
if (preg_match("/[^A-z0-9_\-]/", $action)) { if (preg_match("/[^A-z0-9_\-]/", $action)) {
displayMessage('Invalid action.'); displayMessage('Invalid action.');

View File

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

View File

@@ -7,49 +7,35 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Cache\Cache;
use MyAAC\Models\Menu;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Menus'; $title = 'Menus';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
} }
if (isset($_POST['template'])) { if (isset($_REQUEST['template'])) {
$template = $_POST['template']; $template = $_REQUEST['template'];
if (isset($_POST['menu'])) { if (isset($_REQUEST['menu'])) {
$post_menu = $_POST['menu']; $post_menu = $_REQUEST['menu'];
$post_menu_link = $_POST['menu_link']; $post_menu_link = $_REQUEST['menu_link'];
$post_menu_blank = $_POST['menu_blank']; $post_menu_blank = $_REQUEST['menu_blank'];
$post_menu_color = $_POST['menu_color']; $post_menu_color = $_REQUEST['menu_color'];
if (count($post_menu) != count($post_menu_link)) { if (count($post_menu) != count($post_menu_link)) {
echo 'Menu count is not equal menu links. Something went wrong when sending form.'; echo 'Menu count is not equal menu links. Something went wrong when sending form.';
return; return;
} }
Menu::where('template', $template)->delete(); $db->query('DELETE FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($template));
foreach ($post_menu as $category => $menus) { foreach ($post_menu as $category => $menus) {
foreach ($menus as $i => $menu) { foreach ($menus as $i => $menu) {
if (empty($menu)) // don't save empty menu item if (empty($menu)) // don't save empty menu item
continue; continue;
try { try {
Menu::create([ $db->insert(TABLE_PREFIX . 'menu', array('template' => $template, 'name' => $menu, 'link' => $post_menu_link[$category][$i], 'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0, 'color' => str_replace('#', '', $post_menu_color[$category][$i]), 'category' => $category, 'ordering' => $i));
'template' => $template,
'name' => $menu,
'link' => $post_menu_link[$category][$i],
'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0,
'color' => str_replace('#', '', $post_menu_color[$category][$i]),
'category' => $category,
'ordering' => $i
]);
} catch (PDOException $error) { } catch (PDOException $error) {
warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage()); warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage());
} }
@@ -72,16 +58,6 @@ if (isset($_POST['template'])) {
return; return;
} }
if (isset($_GET['reset_colors'])) {
if (isset($config['menu_default_color'])) {
Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]);
success('Colors has been reset.');
}
else {
warning('There is no default color defined, cannot reset colors.');
}
}
if (!isset($config['menu_categories'])) { if (!isset($config['menu_categories'])) {
echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus."; echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus.";
return; return;
@@ -95,31 +71,17 @@ if (isset($_POST['template'])) {
Hint: Add links to external sites using: <b>http://</b> or <b>https://</b> prefix.<br/> Hint: Add links to external sites using: <b>http://</b> or <b>https://</b> prefix.<br/>
Not all templates support blank and colorful links. Not all templates support blank and colorful links.
</p> </p>
<?php if (isset($config['menu_default_color'])) {?>
<form method="post" action="?p=menus&reset_colors" onsubmit="return confirm('Do you really want to reset colors?');">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-danger">Reset Colors to default</button>
</form>
<br/>
<?php } ?>
</div> </div>
<?php <?php
$menus = Menu::query() $menus = array();
->select('name', 'link', 'blank', 'color', 'category', 'ordering') $menus_db = $db->query('SELECT `name`, `link`, `blank`, `color`, `category`, `ordering` FROM `' . TABLE_PREFIX . 'menu` WHERE `enabled` = 1 AND `template` = ' . $db->quote($template) . ' ORDER BY `ordering` ASC;')->fetchAll();
->where('enabled', 1) foreach ($menus_db as $menu) {
->where('template', $template) $menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']);
->orderBy('ordering') }
->get()
->groupBy('category')
->toArray();
$last_id = array(); $last_id = array();
?> ?>
<form method="post" id="menus-form" action="?p=menus"> <form method="post" id="menus-form" action="?p=menus">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/> <input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-info">Save</button><br/><br/>
<div class="row"> <div class="row">
<?php foreach ($config['menu_categories'] as $id => $cat): ?> <?php foreach ($config['menu_categories'] as $id => $cat): ?>
<div class="col-md-12 col-lg-6"> <div class="col-md-12 col-lg-6">
@@ -151,7 +113,7 @@ if (isset($_POST['template'])) {
</div> </div>
<div class="row pb-2"> <div class="row pb-2">
<div class="col-md-12"> <div class="col-md-12">
<button type="submit" class="btn btn-info">Save</button> <button type="submit" class="btn btn-info"><i class="fas fa-update"></i> Save</button>
<?php <?php
echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>'; echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>';
?> ?>
@@ -167,7 +129,7 @@ if (isset($_POST['template'])) {
?> ?>
<?php <?php
} else { } else {
$templates = Menu::select('template')->distinct()->get()->toArray(); $templates = $db->query('SELECT `template` FROM `' . TABLE_PREFIX . 'menu` GROUP BY `template`;')->fetchAll();
foreach ($templates as $key => $value) { foreach ($templates as $key => $value) {
$file = TEMPLATES . $value['template'] . '/config.php'; $file = TEMPLATES . $value['template'] . '/config.php';
if (!file_exists($file)) { if (!file_exists($file)) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,32 +1,28 @@
<div class="col-12 col-md-6"> <div class="col-12 col-md-6">
<div class="card card-warning card-outline"> <div class="card card-warning card-outline">
<div class="card-header"> <form action="?p=dashboard&maintenance" method="post" class="form-horizontal">
<span class="m-0">Website Status<span class="float-right"> <div class="card-header">
<div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success"> <span class="m-0">Website Status<span class="float-right">
<input form="maintenance-form" type="checkbox" class="custom-control-input" name="status" id="status" value="true" {% if not is_closed %} checked{% endif %}> <div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success">
<label id="status-label" class="custom-control-label" for="status"> {% if is_closed %}Closed{% else %}Open{% endif %}</label> <input type="checkbox" class="custom-control-input" name="status" id="status" value="true" {% if not is_closed %} checked{% endif %}>
</div></span> <label id="status-label" class="custom-control-label" for="status"> {% if is_closed %}Closed{% else %}Open{% endif %}</label>
</span> </div></span>
</div> </span>
<div class="card-body p-2">
<div class="col-sm-12">
<label for="message" class="col-form-label">Maintenance Message</label>
<textarea form="maintenance-form" name="message" class="form-control" cols="40" rows="3" maxlength="255" placeholder="Enter ...">{{ closed_message }}</textarea>
<small>(only visible if closed)</small>
</div> </div>
</div> <div class="card-body p-2">
<div class="card-footer"> <div class="col-sm-12">
<form id="maintenance-form" method="post" action="?p=dashboard" class="float-left"> <label for="message" class="col-form-label">Maintenance Message</label>
{{ csrf() }} <textarea name="message" class="form-control" cols="40" rows="3" maxlength="255" placeholder="Enter ...">{{ closed_message }}</textarea>
<input type="hidden" name="maintenance" value="1" /> <small>(only visible if closed)</small>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-info"><i class="far fa-update"></i> Update</button> <button type="submit" class="btn btn-info"><i class="far fa-update"></i> Update</button>
</form> <a href="?p=dashboard&clear_cache" onclick="return confirm('Are you sure?');" class="float-right">
<form method="post" action="?p=dashboard" class="float-right"> <span class="btn btn-danger"><i class="fas fa-clear"></i>Clear cache</span>
{{ csrf() }} </a>
<input type="hidden" name="clear_cache" value="1" /> </div>
<button type="submit" onclick="return confirm('Are you sure that you want to clear cache?');" class="btn btn-danger" title="Clear Cache"><i class="fas fa-clear"></i>Clear cache</button> </form>
</form>
</div>
</div> </div>
</div> </div>

View File

@@ -7,16 +7,12 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Forum;
use MyAAC\News;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
require_once LIBS . 'forum.php';
require_once LIBS . 'news.php';
$title = 'News Panel'; $title = 'News Panel';
csrfProtect();
$use_datatable = true; $use_datatable = true;
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
@@ -27,79 +23,80 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
header('X-XSS-Protection:0'); header('X-XSS-Protection:0');
// some constants, used mainly by database (cannot by modified without schema changes) // some constants, used mainly by database (cannot by modified without schema changes)
const NEWS_TITLE_LIMIT = 100; define('NEWS_TITLE_LIMIT', 100);
const NEWS_BODY_LIMIT = 65535; // maximum news body length define('NEWS_BODY_LIMIT', 65535); // maximum news body length
const ARTICLE_TEXT_LIMIT = 300; define('ARTICLE_TEXT_LIMIT', 300);
const ARTICLE_IMAGE_LIMIT = 100; define('ARTICLE_IMAGE_LIMIT', 100);
$name = $p_title = ''; $name = $p_title = '';
if(!empty($action)) if(!empty($action))
{ {
$id = $_POST['id'] ?? null; $id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
$p_title = $_POST['title'] ?? null; $p_title = isset($_REQUEST['title']) ? $_REQUEST['title'] : null;
$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null; $body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null;
$comments = $_POST['comments'] ?? null; $comments = isset($_REQUEST['comments']) ? $_REQUEST['comments'] : null;
$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : 1; $type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null;
$category = isset($_POST['category']) ? (int)$_POST['category'] : null; $category = isset($_REQUEST['category']) ? (int)$_REQUEST['category'] : null;
$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null; $player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null;
$article_text = $_POST['article_text'] ?? null; $article_text = isset($_REQUEST['article_text']) ? $_REQUEST['article_text'] : null;
$article_image = $_POST['article_image'] ?? null; $article_image = isset($_REQUEST['article_image']) ? $_REQUEST['article_image'] : null;
$forum_section = $_POST['forum_section'] ?? null; $forum_section = isset($_REQUEST['forum_section']) ? $_REQUEST['forum_section'] : null;
$errors = []; $errors = array();
if (isRequestMethod('post')) { if($action == 'new') {
if ($action == 'new') { if(isset($forum_section) && $forum_section != '-1') {
if (isset($forum_section) && $forum_section != '-1') { $forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors);
$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors); }
}
if (isset($p_title) && News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) { if(isset($p_title) && News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) {
$p_title = $body = $comments = $article_text = $article_image = ''; $p_title = $body = $comments = $article_text = $article_image = '';
$type = $category = $player_id = 0;
success("Added successful.");
}
}
else if($action == 'delete') {
News::delete($id, $errors);
success("Deleted successful.");
}
else if($action == 'edit')
{
if(isset($id) && !isset($p_title)) {
$news = News::get($id);
$p_title = $news['title'];
$body = $news['body'];
$comments = $news['comments'];
$type = $news['type'];
$category = $news['category'];
$player_id = $news['player_id'];
$article_text = $news['article_text'];
$article_image = $news['article_image'];
}
else {
if(News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) {
// update forum thread if exists
if(isset($forum_section) && Validator::number($forum_section)) {
$db->query("UPDATE `" . TABLE_PREFIX . "forum` SET `author_guid` = ".(int) $player_id.", `post_text` = ".$db->quote($body).", `post_topic` = ".$db->quote($p_title).", `edit_date` = " . time() . " WHERE `id` = " . $db->quote($forum_section));
}
$action = $p_title = $body = $comments = $article_text = $article_image = '';
$type = $category = $player_id = 0; $type = $category = $player_id = 0;
success('Added successful.'); success("Updated successful.");
}
} else if ($action == 'delete') {
if (News::delete($id, $errors)) {
success('Deleted successful.');
}
} else if ($action == 'edit') {
if (isset($id) && !isset($p_title)) {
$news = News::get($id);
$p_title = $news['title'];
$body = $news['body'];
$comments = $news['comments'];
$type = $news['type'];
$category = $news['category'];
$player_id = $news['player_id'];
$article_text = $news['article_text'];
$article_image = $news['article_image'];
} else {
if (News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) {
// update forum thread if exists
if (isset($forum_section) && Validator::number($forum_section)) {
$db->query("UPDATE `" . TABLE_PREFIX . "forum` SET `author_guid` = " . (int)$player_id . ", `post_text` = " . $db->quote($body) . ", `post_topic` = " . $db->quote($p_title) . ", `edit_date` = " . time() . " WHERE `id` = " . $db->quote($forum_section));
}
$action = $p_title = $body = $comments = $article_text = $article_image = '';
$type = $category = $player_id = 0;
success('Updated successful.');
}
}
} else if ($action == 'hide') {
if (News::toggleHide($id, $errors, $status)) {
success(($status == 1 ? 'Hide' : 'Show') . ' successful.');
} }
} }
} }
else if($action == 'hide') {
News::toggleHidden($id, $errors, $status);
success(($status == 1 ? 'Show' : 'Hide') . " successful.");
}
if(!empty($errors)) if(!empty($errors))
error(implode(", ", $errors)); error(implode(", ", $errors));
} }
$categories = array(); $categories = array();
foreach($db->query('SELECT `id`, `name`, `icon_id` FROM `' . TABLE_PREFIX . 'news_categories` WHERE `hide` != 1') as $cat) foreach($db->query('SELECT `id`, `name`, `icon_id` FROM `' . TABLE_PREFIX . 'news_categories` WHERE `hidden` != 1') as $cat)
{ {
$categories[$cat['id']] = array( $categories[$cat['id']] = array(
'name' => $cat['name'], 'name' => $cat['name'],
@@ -117,10 +114,12 @@ if($action == 'edit' || $action == 'new') {
$account_players->orderBy('group_id', POT::ORDER_DESC); $account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.news.form.html.twig', array( $twig->display('admin.news.form.html.twig', array(
'action' => $action, 'action' => $action,
'news_link' => getLink(PAGE),
'news_link_form' => '?p=news&action=' . ($action == 'edit' ? 'edit' : 'new'),
'news_id' => $id ?? null, 'news_id' => $id ?? null,
'title' => $p_title ?? '', 'title' => $p_title ?? '',
'body' => isset($body) ? escapeHtml($body) : '', 'body' => isset($body) ? escapeHtml($body) : '',
'type' => $type, 'type' => $type ?? null,
'player' => isset($player) && $player->isLoaded() ? $player : null, 'player' => isset($player) && $player->isLoaded() ? $player : null,
'player_id' => $player_id ?? null, 'player_id' => $player_id ?? null,
'account_players' => $account_players, 'account_players' => $account_players,
@@ -142,12 +141,12 @@ foreach ($query as $_news) {
$newses[$_news['type']][] = array( $newses[$_news['type']][] = array(
'id' => $_news['id'], 'id' => $_news['id'],
'hide' => $_news['hide'], 'hidden' => $_news['hidden'],
'archive_link' => getLink('news') . '/archive/' . $_news['id'], 'archive_link' => getLink('news') . '/archive/' . $_news['id'],
'title' => $_news['title'], 'title' => $_news['title'],
'date' => $_news['date'], 'date' => $_news['date'],
'player_name' => $_player->isLoaded() ? $_player->getName() : '', 'player_name' => isset($_player) && $_player->isLoaded() ? $_player->getName() : '',
'player_link' => $_player->isLoaded() ? getPlayerLink($_player->getName(), false) : '', 'player_link' => isset($_player) && $_player->isLoaded() ? getPlayerLink($_player->getName(), false) : '',
); );
} }

View File

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

View File

@@ -7,16 +7,10 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Models\Pages as ModelsPages;
use MyAAC\Admin\Pages;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Pages'; $title = 'Pages';
$use_datatable = true; $use_datatable = true;
csrfProtect();
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
@@ -32,36 +26,31 @@ $enable_tinymce = true;
$access = 0; $access = 0;
// some constants, used mainly by database (cannot by modified without schema changes) // some constants, used mainly by database (cannot by modified without schema changes)
const PAGE_TITLE_LIMIT = 30; define('PAGE_TITLE_LIMIT', 30);
const PAGE_NAME_LIMIT = 30; define('PAGE_NAME_LIMIT', 30);
const PAGE_BODY_LIMIT = 65535; // maximum page body length define('PAGE_BODY_LIMIT', 65535); // maximum page body length
if (!empty($action) && isRequestMethod('post')) { if (!empty($action)) {
if ($action == 'delete' || $action == 'edit' || $action == 'hide') { if ($action == 'delete' || $action == 'edit' || $action == 'hide')
$id = $_POST['id']; $id = $_REQUEST['id'];
if (isset($_REQUEST['name']))
$name = $_REQUEST['name'];
if (isset($_REQUEST['title']))
$p_title = $_REQUEST['title'];
$php = isset($_REQUEST['php']) && $_REQUEST['php'] == 1;
$enable_tinymce = isset($_REQUEST['enable_tinymce']) && $_REQUEST['enable_tinymce'] == 1;
if ($php)
$body = $_REQUEST['body'];
else if (isset($_REQUEST['body'])) {
//$body = $_REQUEST['body'];
$body = html_entity_decode(stripslashes($_REQUEST['body']));
} }
if (isset($_POST['name'])) { if (isset($_REQUEST['access']))
$name = $_POST['name']; $access = $_REQUEST['access'];
}
if (isset($_POST['title'])) {
$p_title = $_POST['title'];
}
$php = isset($_POST['php']) && $_POST['php'] == 1;
$enable_tinymce = (isset($_POST['enable_tinymce']) && $_POST['enable_tinymce'] == 1) ?: $enable_tinymce;
if ($php) {
$body = $_POST['body'];
}
else if (isset($_POST['body'])) {
//$body = $_POST['body'];
$body = html_entity_decode(stripslashes($_POST['body']));
}
if (isset($_POST['access'])) {
$access = $_POST['access'];
}
$errors = array(); $errors = array();
$player_id = 1; $player_id = 1;
@@ -78,7 +67,7 @@ if (!empty($action) && isRequestMethod('post')) {
if (Pages::delete($id, $errors)) if (Pages::delete($id, $errors))
success('Page with id ' . $id . ' has been deleted'); success('Page with id ' . $id . ' has been deleted');
} else if ($action == 'edit') { } else if ($action == 'edit') {
if (isset($id) && !isset($_POST['name'])) { if (isset($id) && !isset($_REQUEST['name'])) {
$_page = Pages::get($id); $_page = Pages::get($id);
$name = $_page['name']; $name = $_page['name'];
$p_title = $_page['title']; $p_title = $_page['title'];
@@ -97,26 +86,29 @@ if (!empty($action) && isRequestMethod('post')) {
} }
} }
} else if ($action == 'hide') { } else if ($action == 'hide') {
if (Pages::toggleHide($id, $errors, $status)) { Pages::toggleHidden($id, $errors, $status);
success(($status == 0 ? 'Show' : 'Hide') . ' successful.'); success(($status == 1 ? 'Show' : 'Hide') . ' successful.');
}
} }
if (!empty($errors)) if (!empty($errors))
error(implode(", ", $errors)); error(implode(", ", $errors));
} }
$pages = ModelsPages::all()->map(function ($e) { $query =
return [ $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'pages'));
'link' => getFullLink($e->name, $e->name, true),
'title' => substr($e->title, 0, 20),
'php' => $e->php == '1',
'id' => $e->id,
'hide' => $e->hide
];
})->toArray();
$twig->display('admin.pages.form.html.twig', [ $pages = array();
foreach ($query as $_page) {
$pages[] = array(
'link' => getFullLink($_page['name'], $_page['name'], true),
'title' => substr($_page['title'], 0, 20),
'php' => $_page['php'] == '1',
'id' => $_page['id'],
'hidden' => $_page['hidden']
);
}
$twig->display('admin.pages.form.html.twig', array(
'action' => $action, 'action' => $action,
'id' => $action == 'edit' ? $id : null, 'id' => $action == 'edit' ? $id : null,
'name' => $name, 'name' => $name,
@@ -126,8 +118,143 @@ $twig->display('admin.pages.form.html.twig', [
'body' => isset($body) ? escapeHtml($body) : '', 'body' => isset($body) ? escapeHtml($body) : '',
'groups' => $groups->getGroups(), 'groups' => $groups->getGroups(),
'access' => $access 'access' => $access
]); ));
$twig->display('admin.pages.html.twig', [ $twig->display('admin.pages.html.twig', array(
'pages' => $pages 'pages' => $pages
]); ));
class Pages
{
static public function verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors)
{
if(!isset($title[0]) || !isset($body[0])) {
$errors[] = 'Please fill all inputs.';
return false;
}
if(strlen($name) > PAGE_NAME_LIMIT) {
$errors[] = 'Page name cannot be longer than ' . PAGE_NAME_LIMIT . ' characters.';
return false;
}
if(strlen($title) > PAGE_TITLE_LIMIT) {
$errors[] = 'Page title cannot be longer than ' . PAGE_TITLE_LIMIT . ' characters.';
return false;
}
if(strlen($body) > PAGE_BODY_LIMIT) {
$errors[] = 'Page content cannot be longer than ' . PAGE_BODY_LIMIT . ' characters.';
return false;
}
if(!isset($player_id) || $player_id == 0) {
$errors[] = 'Player ID is wrong.';
return false;
}
if(!isset($php) || ($php != 0 && $php != 1)) {
$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;
}
if(!isset($access) || $access < 0 || $access > PHP_INT_MAX) {
$errors[] = 'Access is wrong.';
return false;
}
return true;
}
static public function get($id)
{
global $db;
$query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id));
if ($query !== false)
return $query;
return false;
}
static public function add($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;
}
global $db;
$query = $db->select(TABLE_PREFIX . 'pages', array('name' => $name));
if ($query === false)
$db->insert(TABLE_PREFIX . 'pages',
array(
'name' => $name,
'title' => $title,
'body' => $body,
'player_id' => $player_id,
'php' => $php ? '1' : '0',
'enable_tinymce' => $enable_tinymce ? '1' : '0',
'access' => $access
)
);
else
$errors[] = 'Page with this link already exists.';
return !count($errors);
}
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;
}
global $db;
$db->update(TABLE_PREFIX . 'pages',
array(
'name' => $name,
'title' => $title,
'body' => $body,
'player_id' => $player_id,
'php' => $php ? '1' : '0',
'enable_tinymce' => $enable_tinymce ? '1' : '0',
'access' => $access
),
array('id' => $id));
return true;
}
static public function delete($id, &$errors)
{
global $db;
if (isset($id)) {
if ($db->select(TABLE_PREFIX . 'pages', array('id' => $id)) !== false)
$db->delete(TABLE_PREFIX . 'pages', array('id' => $id));
else
$errors[] = 'Page with id ' . $id . ' does not exists.';
} else
$errors[] = 'id not set';
return !count($errors);
}
static public function toggleHidden($id, &$errors, &$status)
{
global $db;
if (isset($id)) {
$query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id));
if ($query !== false) {
$db->update(TABLE_PREFIX . 'pages', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
$status = $query['hidden'];
}
else {
$errors[] = 'Page with id ' . $id . ' does not exists.';
}
} else
$errors[] = 'id not set';
return !count($errors);
}
}

View File

@@ -7,19 +7,13 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Forum;
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Player editor'; $title = 'Player editor';
csrfProtect();
$player_base = ADMIN_URL . '?p=players'; $player_base = ADMIN_URL . '?p=players';
$use_datatable = true; $use_datatable = true;
require_once LIBS . 'forum.php';
$skills = array( $skills = array(
POT::SKILL_FIST => array('Fist fighting', 'fist'), POT::SKILL_FIST => array('Fist fighting', 'fist'),
@@ -78,7 +72,7 @@ else if (isset($_REQUEST['search'])) {
$player = new OTS_Player(); $player = new OTS_Player();
$player->load($id); $player->load($id);
if ($player->isLoaded() && isset($_POST['save'])) {// we want to save if (isset($player) && $player->isLoaded() && isset($_POST['save'])) {// we want to save
$error = false; $error = false;
if ($player->isOnline()) if ($player->isOnline())
@@ -213,7 +207,7 @@ else if (isset($_REQUEST['search'])) {
} }
$deleted = (isset($_POST['deleted']) && $_POST['deleted'] == 'true'); $deleted = (isset($_POST['deleted']) && $_POST['deleted'] == 'true');
$hide = (isset($_POST['hide']) && $_POST['hide'] == 'true'); $hidden = (isset($_POST['hidden']) && $_POST['hidden'] == 'true');
$created = strtotime($_POST['created']); $created = strtotime($_POST['created']);
verify_number($created, 'Created', 11); verify_number($created, 'Created', 11);
@@ -290,7 +284,7 @@ else if (isset($_REQUEST['search'])) {
$player->setCustomField('deletion', $deleted ? '1' : '0'); $player->setCustomField('deletion', $deleted ? '1' : '0');
else else
$player->setCustomField('deleted', $deleted ? '1' : '0'); $player->setCustomField('deleted', $deleted ? '1' : '0');
$player->setCustomField('hide', $hide ? '1' : '0'); $player->setCustomField('hidden', $hidden ? '1' : '0');
$player->setCustomField('created', $created); $player->setCustomField('created', $created);
if (isset($comment)) if (isset($comment))
$player->setCustomField('comment', $comment); $player->setCustomField('comment', $comment);
@@ -375,8 +369,7 @@ else if (isset($_REQUEST['search'])) {
</li> </li>
</ul> </ul>
</div> </div>
<form action="<?php echo $player_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post"> <form action="<?php echo $player_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post">
<?php csrf(); ?>
<div class="card-body"> <div class="card-body">
<div class="tab-content" id="tabs-tabContent"> <div class="tab-content" id="tabs-tabContent">
<div class="tab-pane fade active show" id="tabs-home"> <div class="tab-pane fade active show" id="tabs-home">
@@ -394,8 +387,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group">Group:</label> <label for="group">Group:</label>
<select name="group" id="group" class="form-control custom-select"> <select name="group" id="group" class="form-control custom-select">
<?php foreach ($groups->getGroups() as $_id => $group): ?> <?php foreach ($groups->getGroups() as $id => $group): ?>
<option value="<?php echo $_id; ?>" <?php echo($player->getGroup()->getId() == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option> <option value="<?php echo $id; ?>" <?php echo($player->getGroup()->getId() == $id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -403,8 +396,8 @@ else if (isset($_REQUEST['search'])) {
<label for="vocation">Vocation</label> <label for="vocation">Vocation</label>
<select name="vocation" id="vocation" class="form-control custom-select"> <select name="vocation" id="vocation" class="form-control custom-select">
<?php <?php
foreach ($config['vocations'] as $_id => $name) { foreach ($config['vocations'] as $id => $name) {
echo '<option value=' . $_id . ($_id == $player->getVocation() ? ' selected' : '') . '>' . $name . '</option>'; echo '<option value=' . $id . ($id == $player->getVocation() ? ' selected' : '') . '>' . $name . '</option>';
} }
?> ?>
</select> </select>
@@ -414,8 +407,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="sex">Sex:</label> <label for="sex">Sex:</label>
<select name="sex" id="sex" class="form-control custom-select">> <select name="sex" id="sex" class="form-control custom-select">>
<?php foreach ($config['genders'] as $_id => $sex): ?> <?php foreach ($config['genders'] as $id => $sex): ?>
<option value="<?php echo $_id; ?>" <?php echo($player->getSex() == $_id ? 'selected' : ''); ?>><?php echo strtolower($sex); ?></option> <option value="<?php echo $id; ?>" <?php echo($player->getSex() == $id ? 'selected' : ''); ?>><?php echo strtolower($sex); ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -428,8 +421,8 @@ else if (isset($_REQUEST['search'])) {
$configTowns[$player->getTownId()] = 'Unknown Town'; $configTowns[$player->getTownId()] = 'Unknown Town';
} }
foreach ($configTowns as $_id => $town): ?> foreach ($configTowns as $id => $town): ?>
<option value="<?php echo $_id; ?>" <?php echo($player->getTownId() == $_id ? 'selected' : ''); ?>><?php echo $town; ?></option> <option value="<?php echo $id; ?>" <?php echo($player->getTownId() == $id ? 'selected' : ''); ?>><?php echo $town; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -440,8 +433,8 @@ else if (isset($_REQUEST['search'])) {
<select name="skull" id="skull" class="form-control custom-select"> <select name="skull" id="skull" class="form-control custom-select">
<?php <?php
foreach ($skull_type as $_id => $s_name) { foreach ($skull_type as $id => $s_name) {
echo '<option value=' . $_id . ($_id == $player->getSkull() ? ' selected' : '') . '>' . $s_name . '</option>'; echo '<option value=' . $id . ($id == $player->getSkull() ? ' selected' : '') . '>' . $s_name . '</option>';
} }
?> ?>
</select> </select>
@@ -485,8 +478,8 @@ else if (isset($_REQUEST['search'])) {
</div> </div>
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<div class="custom-control custom-switch custom-switch-on-success"> <div class="custom-control custom-switch custom-switch-on-success">
<input type="checkbox" class="custom-control-input" name="hide" id="hide" value="true" <?php echo($player->isHidden() ? ' checked' : ''); ?>> <input type="checkbox" class="custom-control-input" name="hidden" id="hidden" value="true" <?php echo($player->isHidden() ? ' checked' : ''); ?>>
<label class="custom-control-label" for="hide">Hidden</label> <label class="custom-control-label" for="hidden">Hidden</label>
</div> </div>
</div> </div>
</div> </div>
@@ -558,22 +551,22 @@ else if (isset($_REQUEST['search'])) {
</div> </div>
<div class="tab-pane fade" id="tabs-skills"> <div class="tab-pane fade" id="tabs-skills">
<?php <?php
foreach ($skills as $_id => $info) { foreach ($skills as $id => $info) {
?> ?>
<div class="form-group row"> <div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<?php echo '<label for="skills[' . $_id . ']" class="control-label">' . $info[0] . '</label> <?php echo '<label for="skills[' . $id . ']" class="control-label">' . $info[0] . '</label>
<input type="text" class="form-control" id="skills[' . $_id . ']" name="skills[' . $_id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkill($_id) . '"/>'; ?> <input type="text" class="form-control" id="skills[' . $id . ']" name="skills[' . $id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkill($id) . '"/>'; ?>
</div> </div>
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<?php echo '<label for="skills_tries[' . $_id . ']" class="control-label">' . $info[0] . ' tries</label> <?php echo '<label for="skills_tries[' . $id . ']" class="control-label">' . $info[0] . ' tries</label>
<input type="text" class="form-control" id="skills_tries[' . $_id . ']" name="skills_tries[' . $_id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkillTries($_id) . '"/>'; ?> <input type="text" class="form-control" id="skills_tries[' . $id . ']" name="skills_tries[' . $id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkillTries($id) . '"/>'; ?>
</div> </div>
</div> </div>
<?php } ?> <?php } ?>
</div> </div>
<div class="tab-pane fade" id="tabs-pos"> <div class="tab-pane fade" id="tabs-pos">
<?php $outfit = setting('core.outfit_images_url') . '?id=' . $player->getLookType() . ($hasLookAddons ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); ?> <?php $outfit = $config['outfit_images_url'] . '?id=' . $player->getLookType() . ($hasLookAddons ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); ?>
<div id="imgchar" style="width:64px;height:64px;position:absolute; top:30px; right:30px"> <div id="imgchar" style="width:64px;height:64px;position:absolute; top:30px; right:30px">
<img id="player_outfit" style="margin-left:0;margin-top:0;width:64px;height:64px;" src="<?php echo $outfit; ?>" alt="player outfit"/> <img id="player_outfit" style="margin-left:0;margin-top:0;width:64px;height:64px;" src="<?php echo $outfit; ?>" alt="player outfit"/>
</div> </div>
@@ -626,7 +619,7 @@ else if (isset($_REQUEST['search'])) {
if ($outfitlist) { ?> if ($outfitlist) { ?>
<select name="look_type" id="look_type" class="form-control custom-select"> <select name="look_type" id="look_type" class="form-control custom-select">
<?php <?php
foreach ($outfitlist as $_id => $outfit) { foreach ($outfitlist as $id => $outfit) {
if ($outfit['enabled'] == 'yes') ; if ($outfit['enabled'] == 'yes') ;
echo '<option value=' . $outfit['id'] . ($outfit['id'] == $player->getLookType() ? ' selected' : '') . '>' . $outfit['name'] . ' - ' . ($outfit['type'] == 1 ? 'Male' : 'Female') . '</option>'; echo '<option value=' . $outfit['id'] . ($outfit['id'] == $player->getLookType() ? ' selected' : '') . '>' . $outfit['name'] . ' - ' . ($outfit['type'] == 1 ? 'Male' : 'Female') . '</option>';
} }
@@ -642,8 +635,8 @@ else if (isset($_REQUEST['search'])) {
<select name="look_addons" id="look_addons" class="form-control custom-select"> <select name="look_addons" id="look_addons" class="form-control custom-select">
<?php <?php
$addon_type = array("None", "First", "Second", "Both"); $addon_type = array("None", "First", "Second", "Both");
foreach ($addon_type as $_id => $s_name) { foreach ($addon_type as $id => $s_name) {
echo '<option value=' . $_id . ($_id == $player->getLookAddons() ? ' selected' : '') . '>' . $s_name . '</option>'; echo '<option value=' . $id . ($id == $player->getLookAddons() ? ' selected' : '') . '>' . $s_name . '</option>';
} }
?> ?>
</select> </select>
@@ -708,7 +701,7 @@ else if (isset($_REQUEST['search'])) {
<div class="form-group row"> <div class="form-group row">
<div class="col-12"> <div class="col-12">
<label for="comment" class="control-label">Comment:</label> <label for="comment" class="control-label">Comment:</label>
<textarea class="form-control" id="comment" name="comment" rows="10" cols="50" wrap="virtual"><?php echo $player->getCustomField("comment"); ?></textarea> <textarea class="form-control" name="comment" rows="10" cols="50" wrap="virtual"><?php echo $player->getCustomField("comment"); ?></textarea>
<small>[max. length: 2000 chars, 50 lines (ENTERs)]</small> <small>[max. length: 2000 chars, 50 lines (ENTERs)]</small>
</div> </div>
</div> </div>
@@ -751,7 +744,8 @@ else if (isset($_REQUEST['search'])) {
<div class="row"> <div class="row">
<?php <?php
if (isset($account) && $account->isLoaded()) { if (isset($account) && $account->isLoaded()) {
$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get(); $account_players = $account->getPlayersList();
$account_players->orderBy('id');
if (isset($account_players)) { ?> if (isset($account_players)) { ?>
<table class="table table-striped table-condensed table-responsive d-md-table"> <table class="table table-striped table-condensed table-responsive d-md-table">
<thead> <thead>
@@ -764,13 +758,23 @@ else if (isset($_REQUEST['search'])) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach ($account_players as $i => $player): ?> <?php foreach ($account_players as $i => $player):
$player_vocation = $player->getVocation();
$player_promotion = $player->getPromotion();
if (isset($player_promotion)) {
if ((int)$player_promotion > 0)
$player_vocation += ($player_promotion * $config['vocations_amount']);
}
if (isset($config['vocations'][$player_vocation])) {
$vocation_name = $config['vocations'][$player_vocation];
} ?>
<tr> <tr>
<th><?php echo $i + 1; ?></th> <th><?php echo $i; ?></th>
<td><?php echo $player->name; ?></td> <td><?php echo $player->getName(); ?></td>
<td><?php echo $player->level; ?></td> <td><?php echo $player->getLevel(); ?></td>
<td><?php echo $player->vocation_name; ?></td> <td><?php echo $vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td> <td><a href="?p=players&id=<?php echo $player->getId() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
</tr> </tr>
<?php endforeach ?> <?php endforeach ?>
</tbody> </tbody>
@@ -845,7 +849,7 @@ else if (isset($_REQUEST['search'])) {
<?php if($hasLookAddons): ?> <?php if($hasLookAddons): ?>
const $addonvalue = $('#look_addons'); const $addonvalue = $('#look_addons');
$addonvalue.on('change', () => { $('#look_addons').on('change', () => {
updateOutfit(); updateOutfit();
}); });
<?php endif; ?> <?php endif; ?>
@@ -862,7 +866,7 @@ else if (isset($_REQUEST['search'])) {
<?php if($hasLookAddons): ?> <?php if($hasLookAddons): ?>
look_addons = '&addons=' + $('#look_addons').val(); look_addons = '&addons=' + $('#look_addons').val();
<?php endif; ?> <?php endif; ?>
$("#player_outfit").attr("src", '<?= setting('core.outfit_images_url'); ?>?id=' + look_type + look_addons + '&head=' + look_head + '&body=' + look_body + '&legs=' + look_legs + '&feet=' + look_feet); $("#player_outfit").attr("src", '<?= $config['outfit_images_url']; ?>?id=' + look_type + look_addons + '&head=' + look_head + '&body=' + look_body + '&legs=' + look_legs + '&feet=' + look_feet);
} }
</script> </script>
<?php } ?> <?php } ?>
@@ -874,20 +878,18 @@ else if (isset($_REQUEST['search'])) {
<div class="card-body row"> <div class="card-body row">
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $player_base; ?>" method="post"> <form action="<?php echo $player_base; ?>" method="post">
<?php csrf(); ?> <label for="name">Player Name:</label>
<label for="search">Player Name:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_player); ?>" maxlength="32" size="32"> <input type="text" class="form-control" name="search" value="<?php echo $search_player; ?>" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>
</div> </div>
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $player_base; ?>" method="post"> <form action="<?php echo $player_base; ?>" method="post">
<?php csrf(); ?> <label for="name">Player ID:</label>
<label for="id">Player ID:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32"> <input type="text" class="form-control" name="id" value="" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>
@@ -898,7 +900,7 @@ else if (isset($_REQUEST['search'])) {
</div> </div>
<script> <script>
$(function () { $(document).ready(function () {
$('.player_datatable').DataTable({ $('.player_datatable').DataTable({
"order": [[0, "asc"]] "order": [[0, "asc"]]
}); });

View File

@@ -7,39 +7,35 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Plugins;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Plugin manager'; $title = 'Plugin manager';
csrfProtect();
$use_datatable = true; $use_datatable = true;
require_once LIBS . 'plugins.php';
if (!getBoolean(setting('core.admin_plugins_manage_enable'))) { 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>.'); 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 { else {
$twig->display('admin.plugins.form.html.twig'); $twig->display('admin.plugins.form.html.twig');
if (isset($_POST['uninstall'])) { if (isset($_REQUEST['uninstall'])) {
$uninstall = $_POST['uninstall']; $uninstall = $_REQUEST['uninstall'];
if (Plugins::uninstall($uninstall)) { if (Plugins::uninstall($uninstall)) {
success('Successfully uninstalled plugin ' . $uninstall); success('Successfully uninstalled plugin ' . $uninstall);
} else { } else {
error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError());
} }
} else if (isset($_POST['enable'])) { } else if (isset($_REQUEST['enable'])) {
$enable = $_POST['enable']; $enable = $_REQUEST['enable'];
if (Plugins::enable($enable)) { if (Plugins::enable($enable)) {
success('Successfully enabled plugin ' . $enable); success('Successfully enabled plugin ' . $enable);
} else { } else {
error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError()); error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError());
} }
} else if (isset($_POST['disable'])) { } else if (isset($_REQUEST['disable'])) {
$disable = $_POST['disable']; $disable = $_REQUEST['disable'];
if (Plugins::disable($disable)) { if (Plugins::disable($disable)) {
success('Successfully disabled plugin ' . $disable); success('Successfully disabled plugin ' . $disable);
} else { } else {
@@ -120,7 +116,7 @@ foreach (get_plugins(true) as $plugin) {
if (!$plugin_info) { if (!$plugin_info) {
warning('Cannot load plugin info ' . $plugin . '.json'); warning('Cannot load plugin info ' . $plugin . '.json');
} else { } else {
$disabled = (str_contains($plugin, 'disabled.')); $disabled = (strpos($plugin, 'disabled.') !== false);
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin); $pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
$plugins[] = array( $plugins[] = array(
'name' => $plugin_info['name'] ?? '', 'name' => $plugin_info['name'] ?? '',

View File

@@ -7,10 +7,6 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Plugins;
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Settings'; $title = 'Settings';

View File

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

View File

@@ -12,7 +12,6 @@ defined('MYAAC') or die('Direct access not allowed!');
use DeviceDetector\DeviceDetector; use DeviceDetector\DeviceDetector;
use DeviceDetector\Parser\Client\Browser; use DeviceDetector\Parser\Client\Browser;
use DeviceDetector\Parser\OperatingSystem; use DeviceDetector\Parser\OperatingSystem;
use MyAAC\Visitors;
$title = 'Visitors'; $title = 'Visitors';
$use_datatable = true; $use_datatable = true;
@@ -25,6 +24,7 @@ if (!setting('core.visitors_counter')): ?>
return; return;
endif; endif;
require SYSTEM . 'libs/visitors.php';
$visitors = new Visitors(setting('core.visitors_counter_ttl')); $visitors = new Visitors(setting('core.visitors_counter_ttl'));
function compare($a, $b): int { function compare($a, $b): int {

View File

@@ -1,6 +1,6 @@
<?php <?php
$menus = [ return [
['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'], ['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'],
['name' => 'Settings', 'icon' => 'edit', 'order' => 19, 'link' => ['name' => 'Settings', 'icon' => 'edit', 'order' => 19, 'link' =>
require ADMIN . 'includes/settings_menus.php' require ADMIN . 'includes/settings_menus.php'

View File

@@ -8,8 +8,3 @@
.sidebar-mini.sidebar-collapse .menu-text { .sidebar-mini.sidebar-collapse .menu-text {
display: none; display: none;
} }
.myaac-table tbody tr:nth-child(even) {background: #FFF} /* light border */
.myaac-table tbody tr:nth-child(odd) {background: #CCC} /* dark border */
.myaac-table thead td {background: #000000; color: #ffffff !important;} /* vdark border */
.myaac-table tfoot td {background: #000000; color: #ffffff !important;} /* vdark border */

View File

@@ -191,8 +191,8 @@ if ($logged && admin()) {
]); ]);
} }
?> ?>
<script src="<?php echo BASE_URL; ?>tools/ext/bootstrap/js/bootstrap.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/bootstrap.min.js"></script>
<script src="<?php echo BASE_URL; ?>tools/ext/jquery-ui/jquery-ui.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/jquery-ui.min.js"></script>
<?php if (isset($use_datatable)) { ?> <?php if (isset($use_datatable)) { ?>
<script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script>
<script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script>

View File

@@ -22,10 +22,7 @@
* @copyright 2020 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
define('MYAAC_ADMIN', true);
use MyAAC\DataLoader;
const MYAAC_ADMIN = true;
require '../../common.php'; require '../../common.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';
@@ -37,9 +34,11 @@ if (!admin())
ini_set('max_execution_time', 300); ini_set('max_execution_time', 300);
ob_implicit_flush(); ob_implicit_flush();
@ob_end_flush(); ob_end_flush();
header('X-Accel-Buffering: no'); header('X-Accel-Buffering: no');
require LIBS . 'DataLoader.php';
require LOCALE . 'en/main.php'; require LOCALE . 'en/main.php';
require LOCALE . 'en/install.php'; require LOCALE . 'en/install.php';

View File

@@ -1,8 +1,4 @@
<?php <?php
use MyAAC\Hooks;
use MyAAC\Settings;
const MYAAC_ADMIN = true; const MYAAC_ADMIN = true;
require '../../common.php'; require '../../common.php';
@@ -15,8 +11,6 @@ if(!admin()) {
die('Access denied.'); die('Access denied.');
} }
csrfProtect();
if (!isset($_REQUEST['plugin'])) { if (!isset($_REQUEST['plugin'])) {
http_response_code(500); http_response_code(500);
die('Please enter plugin name.'); die('Please enter plugin name.');
@@ -29,7 +23,7 @@ if (!isset($_POST['settings'])) {
$settings = Settings::getInstance(); $settings = Settings::getInstance();
$success = $settings->save($_REQUEST['plugin'], $_POST['settings']); $settings->save($_REQUEST['plugin'], $_POST['settings']);
$errors = $settings->getErrors(); $errors = $settings->getErrors();
if (count($errors) > 0) { if (count($errors) > 0) {
@@ -37,6 +31,4 @@ if (count($errors) > 0) {
die(implode('<br/>', $errors)); die(implode('<br/>', $errors));
} }
if ($success) { echo 'Saved at ' . date('H:i');
echo 'Saved at ' . date('H:i');
}

View File

@@ -23,11 +23,11 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.');
const MYAAC = true; const MYAAC = true;
const MYAAC_VERSION = '1.0-beta'; const MYAAC_VERSION = '0.10.0-dev';
const DATABASE_VERSION = 40; const DATABASE_VERSION = 36;
const TABLE_PREFIX = 'myaac_'; const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true)); define('START_TIME', microtime(true));
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
@@ -108,13 +108,6 @@ const TFS_FIRST = TFS_02;
const TFS_LAST = TFS_03; const TFS_LAST = TFS_03;
// other definitions // other definitions
const MAIL_MAIL = 0;
const MAIL_SMTP = 1;
const SMTP_SECURITY_NONE = 0;
const SMTP_SECURITY_SSL = 1;
const SMTP_SECURITY_TLS = 2;
const ACCOUNT_NUMBER_LENGTH = 8; const ACCOUNT_NUMBER_LENGTH = 8;
if (!IS_CLI) { if (!IS_CLI) {
@@ -143,7 +136,7 @@ if(!IS_CLI) {
} }
} }
define('SERVER_URL', 'http' . (isHttps() ? 's' : '') . '://' . $baseHost); define('SERVER_URL', 'http' . (isset($_SERVER['HTTPS'][0]) && strtolower($_SERVER['HTTPS']) === 'on' ? 's' : '') . '://' . $baseHost);
define('BASE_URL', SERVER_URL . BASE_DIR . '/'); define('BASE_URL', SERVER_URL . BASE_DIR . '/');
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/'); define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/');
@@ -154,7 +147,6 @@ if (file_exists(BASE . 'config.local.php')) {
require BASE . 'config.local.php'; require BASE . 'config.local.php';
} }
/** @var array $config */
ini_set('log_errors', 1); ini_set('log_errors', 1);
if(@$config['env'] === 'dev') { if(@$config['env'] === 'dev') {
ini_set('display_errors', 1); ini_set('display_errors', 1);
@@ -173,11 +165,3 @@ if (!is_file($autoloadFile)) {
} }
require $autoloadFile; require $autoloadFile;
function isHttps(): bool
{
return
(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
|| (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443);
}

View File

@@ -1,6 +1,6 @@
{ {
"require": { "require": {
"php": "^8.0", "php": "^7.2.5 || ^8.0",
"ext-pdo": "*", "ext-pdo": "*",
"ext-pdo_mysql": "*", "ext-pdo_mysql": "*",
"ext-json": "*", "ext-json": "*",
@@ -11,21 +11,9 @@
"twig/twig": "^2.0", "twig/twig": "^2.0",
"erusev/parsedown": "^1.7", "erusev/parsedown": "^1.7",
"nikic/fast-route": "^1.3", "nikic/fast-route": "^1.3",
"matomo/device-detector": "^6.0", "matomo/device-detector": "^6.0"
"illuminate/database": "^10.18",
"peppeocchi/php-cron-scheduler": "4.*",
"symfony/console": "^6.4",
"symfony/string": "^6.4"
}, },
"require-dev": { "require-dev": {
"filp/whoops": "^2.15", "filp/whoops": "^2.15"
"maximebf/debugbar": "dev-master",
"phpstan/phpstan": "^1.10"
},
"autoload": {
"psr-4": {
"MyAAC\\": "system/src"
},
"files": ["system/src/global.php"]
} }
} }

View File

@@ -38,6 +38,7 @@ describe('Install MyAAC', () => {
cy.contains('Basic configuration'); cy.contains('Basic configuration');
cy.get('#vars_server_path').click().clear().type(Cypress.env('SERVER_PATH')) 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.get('[type="checkbox"]').uncheck() // usage statistics uncheck
@@ -69,8 +70,6 @@ describe('Install MyAAC', () => {
cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 30000 }).should('be.visible') cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 30000 }).should('be.visible')
cy.wait(2000);
cy.screenshot('install-finish') cy.screenshot('install-finish')
}) })
}) })

View File

@@ -14,7 +14,7 @@ describe('Create Account Page', () => {
cy.get('#email').type('tester@example.com') cy.get('#email').type('tester@example.com')
cy.get('#password').type('test1234') cy.get('#password').type('test1234')
cy.get('#password_confirm').type('test1234') cy.get('#password2').type('test1234')
cy.get('#character_name').type('Slaw') cy.get('#character_name').type('Slaw')

View File

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

View File

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

106
index.php
View File

@@ -24,9 +24,6 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\UsageStatistics;
use MyAAC\Visitors;
require_once 'common.php'; require_once 'common.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';
@@ -62,13 +59,22 @@ if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|zip|rar|g
if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install')) if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install'))
{ {
header('Location: ' . BASE_URL . 'install/'); header('Location: ' . BASE_URL . 'install/');
exit(); throw new RuntimeException('Setup detected that <b>install/</b> directory exists. Please visit <a href="' . BASE_URL . 'install">this</a> url to start MyAAC Installation.<br/>Delete <b>install/</b> directory if you already installed MyAAC.<br/>Remember to REFRESH this page when you\'re done!');
} }
$template_place_holders = array(); $template_place_holders = array();
require_once SYSTEM . 'init.php'; require_once SYSTEM . 'init.php';
// verify myaac tables exists in database
if(!$db->hasTable('myaac_account_actions')) {
throw new RuntimeException('Seems that the table <strong>myaac_account_actions</strong> of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting <a href="' . BASE_URL . 'install">this</a> url.');
}
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
require_once SYSTEM . 'template.php'; require_once SYSTEM . 'template.php';
require_once SYSTEM . 'login.php'; require_once SYSTEM . 'login.php';
require_once SYSTEM . 'status.php'; require_once SYSTEM . 'status.php';
@@ -76,6 +82,53 @@ require_once SYSTEM . 'status.php';
$twig->addGlobal('config', $config); $twig->addGlobal('config', $config);
$twig->addGlobal('status', $status); $twig->addGlobal('status', $status);
require_once SYSTEM . 'router.php';
$hooks->trigger(HOOK_STARTUP);
// anonymous usage statistics
// sent only when user agrees
if(setting('core.anonymous_usage_statistics')) {
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days
$should_report = true;
$value = '';
if($cache->enabled() && $cache->fetch('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
}
else {
$value = '';
if(fetchDatabaseConfig('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
if($cache->enabled()) {
$cache->set('last_usage_report', $value);
}
}
else {
registerDatabaseConfig('last_usage_report', time() - ($report_time - (7 * 24 * 60 * 60))); // first report after a week
$should_report = false;
}
}
if($should_report) {
require_once LIBS . 'usage_statistics.php';
Usage_Statistics::report();
updateDatabaseConfig('last_usage_report', time());
if($cache->enabled()) {
$cache->set('last_usage_report', time());
}
}
}
if(setting('core.views_counter'))
require_once SYSTEM . 'counter.php';
if(setting('core.visitors_counter')) {
require_once SYSTEM . 'libs/visitors.php';
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
}
// backward support for gesior // backward support for gesior
if(setting('core.backward_support')) { if(setting('core.backward_support')) {
define('INITIALIZED', true); define('INITIALIZED', true);
@@ -115,51 +168,6 @@ if(setting('core.backward_support')) {
$config['status']['serverStatus_' . $key] = $value; $config['status']['serverStatus_' . $key] = $value;
} }
require_once SYSTEM . 'router.php';
$hooks->trigger(HOOK_STARTUP);
// anonymous usage statistics
// sent only when user agrees
if(setting('core.anonymous_usage_statistics')) {
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days
$should_report = true;
$value = '';
if($cache->enabled() && $cache->fetch('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
}
else {
$value = '';
if(fetchDatabaseConfig('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
if($cache->enabled()) {
$cache->set('last_usage_report', $value);
}
}
else {
registerDatabaseConfig('last_usage_report', time() - ($report_time - (7 * 24 * 60 * 60))); // first report after a week
$should_report = false;
}
}
if($should_report) {
UsageStatistics::report();
updateDatabaseConfig('last_usage_report', time());
if($cache->enabled()) {
$cache->set('last_usage_report', time());
}
}
}
if(setting('core.views_counter'))
require_once SYSTEM . 'counter.php';
if(setting('core.visitors_counter')) {
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
}
/** /**
* @var OTS_Account $account_logged * @var OTS_Account $account_logged
*/ */

View File

@@ -17,7 +17,7 @@ function query($query)
// define php version id if its not already // define php version id if its not already
if(!defined('PHP_VERSION_ID')) { if(!defined('PHP_VERSION_ID')) {
$version = array_map('intval', explode('.', PHP_VERSION)); $version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
} }

View File

@@ -1,4 +1,4 @@
SET @myaac_database_version = 40; SET @myaac_database_version = 36;
CREATE TABLE `myaac_account_actions` CREATE TABLE `myaac_account_actions`
( (
@@ -44,11 +44,11 @@ CREATE TABLE `myaac_changelog`
`where` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - server, 2 - site', `where` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - server, 2 - site',
`date` INT(11) NOT NULL DEFAULT 0, `date` INT(11) NOT NULL DEFAULT 0,
`player_id` INT(11) NOT NULL DEFAULT 0, `player_id` INT(11) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0, `hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
INSERT INTO `myaac_changelog` (`id`, `type`, `where`, `date`, `body`, `hide`) VALUES (1, 3, 2, UNIX_TIMESTAMP(), 'MyAAC installed. (:', 0); INSERT INTO `myaac_changelog` (`id`, `type`, `where`, `date`, `body`, `hidden`) VALUES (1, 3, 2, UNIX_TIMESTAMP(), 'MyAAC installed. (:', 0);
CREATE TABLE `myaac_config` CREATE TABLE `myaac_config`
( (
@@ -67,7 +67,7 @@ CREATE TABLE `myaac_faq`
`question` VARCHAR(255) NOT NULL DEFAULT '', `question` VARCHAR(255) NOT NULL DEFAULT '',
`answer` VARCHAR(1020) NOT NULL DEFAULT '', `answer` VARCHAR(1020) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` INT(11) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0, `hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -80,7 +80,7 @@ CREATE TABLE `myaac_forum_boards`
`guild` INT(11) NOT NULL DEFAULT 0, `guild` INT(11) NOT NULL DEFAULT 0,
`access` INT(11) NOT NULL DEFAULT 0, `access` INT(11) NOT NULL DEFAULT 0,
`closed` TINYINT(1) NOT NULL DEFAULT 0, `closed` TINYINT(1) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0, `hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`, `closed`) VALUES (NULL, 'News', 'News commenting', 0, 1); INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`, `closed`) VALUES (NULL, 'News', 'News commenting', 0, 1);
@@ -127,9 +127,78 @@ CREATE TABLE `myaac_menu`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
/* MENU_CATEGORY_NEWS kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Latest News', 'news', 1, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'News Archive', 'news/archive', 1, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Changelog', 'changelog', 1, 2);
/* MENU_CATEGORY_ACCOUNT kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Account Management', 'account/manage', 2, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Create Account', 'account/create', 2, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Lost Account?', 'account/lost', 2, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Rules', 'rules', 2, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Downloads', 'downloads', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Report Bug', 'bugtracker', 2, 5);
/* MENU_CATEGORY_COMMUNITY kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Who is Online?', 'online', 3, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Characters', 'characters', 3, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Guilds', 'guilds', 3, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Highscores', 'highscores', 3, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Last Deaths', 'lastkills', 3, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Houses', 'houses', 3, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Bans', 'bans', 3, 6);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Forum', 'forum', 3, 7);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Team', 'team', 3, 8);
/* MENU_CATEGORY_LIBRARY kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Monsters', 'creatures', 5, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Spells', 'spells', 5, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Info', 'serverInfo', 5, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Commands', 'commands', 5, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Gallery', 'gallery', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Experience Table', 'experienceTable', 5, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'FAQ', 'faq', 5, 6);
/* MENU_CATEGORY_SHOP kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop Offer', 'gifts', 6, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop History', 'gifts/history', 6, 2);
/* MENU_CATEGORY_NEWS tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Latest News', 'news', 1, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'News Archive', 'news/archive', 1, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Changelog', 'changelog', 1, 2);
/* MENU_CATEGORY_ACCOUNT tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Account Management', 'account/manage', 2, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Create Account', 'account/create', 2, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Lost Account?', 'account/lost', 2, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Rules', 'rules', 2, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Downloads', 'downloads', 2, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Report Bug', 'bugtracker', 2, 5);
/* MENU_CATEGORY_COMMUNITY tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Characters', 'characters', 3, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Who Is Online?', 'online', 3, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Highscores', 'highscores', 3, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Last Kills', 'lastkills', 3, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Houses', 'houses', 3, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Guilds', 'guilds', 3, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Polls', 'polls', 3, 6);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Bans', 'bans', 3, 7);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Support List', 'team', 3, 8);
/* MENU_CATEGORY_FORUM tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Forum', 'forum', 4, 0);
/* MENU_CATEGORY_LIBRARY tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Creatures', 'creatures', 5, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Spells', 'spells', 5, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Commands', 'commands', 5, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Exp Stages', 'experienceStages', 5, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Gallery', 'gallery', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Info', 'serverInfo', 5, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Experience Table', 'experienceTable', 5, 6);
/* MENU_CATEGORY_SHOP tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop Offer', 'gifts', 6, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop History', 'gifts/history', 6, 2);
CREATE TABLE `myaac_monsters` ( CREATE TABLE `myaac_monsters` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`hide` tinyint(1) NOT NULL default 0, `hidden` tinyint(1) NOT NULL default 0,
`name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL,
`mana` int(11) NOT NULL DEFAULT 0, `mana` int(11) NOT NULL DEFAULT 0,
`exp` int(11) NOT NULL, `exp` int(11) NOT NULL,
@@ -174,7 +243,7 @@ CREATE TABLE `myaac_news`
`comments` VARCHAR(50) NOT NULL DEFAULT '', `comments` VARCHAR(50) NOT NULL DEFAULT '',
`article_text` VARCHAR(300) NOT NULL DEFAULT '', `article_text` VARCHAR(300) NOT NULL DEFAULT '',
`article_image` VARCHAR(100) NOT NULL DEFAULT '', `article_image` VARCHAR(100) NOT NULL DEFAULT '',
`hide` TINYINT(1) NOT NULL DEFAULT 0, `hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -184,7 +253,7 @@ CREATE TABLE `myaac_news_categories`
`name` VARCHAR(50) NOT NULL DEFAULT "", `name` VARCHAR(50) NOT NULL DEFAULT "",
`description` VARCHAR(50) NOT NULL DEFAULT "", `description` VARCHAR(50) NOT NULL DEFAULT "",
`icon_id` INT(2) NOT NULL DEFAULT 0, `icon_id` INT(2) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0, `hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -215,7 +284,7 @@ CREATE TABLE `myaac_pages`
`php` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 - plain html, 1 - php', `php` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 - plain html, 1 - php',
`enable_tinymce` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 - enabled, 0 - disabled', `enable_tinymce` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 - enabled, 0 - disabled',
`access` TINYINT(2) NOT NULL DEFAULT 0, `access` TINYINT(2) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0, `hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE (`name`) UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -228,7 +297,7 @@ CREATE TABLE `myaac_gallery`
`thumb` VARCHAR(255) NOT NULL, `thumb` VARCHAR(255) NOT NULL,
`author` VARCHAR(50) NOT NULL DEFAULT '', `author` VARCHAR(50) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` INT(11) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0, `hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -262,7 +331,7 @@ CREATE TABLE `myaac_spells`
`item_id` INT(11) NOT NULL DEFAULT 0, `item_id` INT(11) NOT NULL DEFAULT 0,
`premium` TINYINT(1) NOT NULL DEFAULT 0, `premium` TINYINT(1) NOT NULL DEFAULT 0,
`vocations` VARCHAR(100) NOT NULL DEFAULT '', `vocations` VARCHAR(100) NOT NULL DEFAULT '',
`hide` TINYINT(1) NOT NULL DEFAULT 0, `hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE (`name`) UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

View File

@@ -12,6 +12,7 @@ require SYSTEM . 'functions.php';
require BASE . 'install/includes/functions.php'; require BASE . 'install/includes/functions.php';
require BASE . 'install/includes/locale.php'; require BASE . 'install/includes/locale.php';
require SYSTEM . 'clients.conf.php'; require SYSTEM . 'clients.conf.php';
require LIBS . 'settings.php';
// ignore undefined index from Twig autoloader // ignore undefined index from Twig autoloader
$config['env'] = 'prod'; $config['env'] = 'prod';

View File

@@ -1,7 +1,4 @@
<?php <?php
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
//ini_set('display_errors', false); //ini_set('display_errors', false);
@@ -37,8 +34,6 @@ if(!$error) {
} }
} }
$configToSave['gzip_output'] = false;
$configToSave['cache_engine'] = 'auto';
$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true); $configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true);
require BASE . 'install/includes/config.php'; require BASE . 'install/includes/config.php';

View File

@@ -1,7 +1,4 @@
<?php <?php
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
ini_set('max_execution_time', 300); ini_set('max_execution_time', 300);
@@ -113,8 +110,8 @@ else {
$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX ."news` WHERE `title` LIKE 'Hello!';"); $query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX ."news` WHERE `title` LIKE 'Hello!';");
if($query->rowCount() == 0) { if($query->rowCount() == 0) {
if(query("INSERT INTO `" . TABLE_PREFIX ."news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hide`) VALUES (NULL, '1', UNIX_TIMESTAMP(), '2', 'Hello!', 'MyAAC is just READY to use!', " . $player_id . ", 'https://my-aac.org', '0'); if(query("INSERT INTO `" . TABLE_PREFIX ."news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '1', UNIX_TIMESTAMP(), '2', 'Hello!', 'MyAAC is just READY to use!', " . $player_id . ", 'https://my-aac.org', '0');
INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hide`) VALUES (NULL, '2', UNIX_TIMESTAMP(), '4', 'Hello tickets!', 'https://my-aac.org', " . $player_id . ", '', '0');")) { INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '2', UNIX_TIMESTAMP(), '4', 'Hello tickets!', 'https://my-aac.org', " . $player_id . ", '', '0');")) {
success($locale['step_database_created_news']); success($locale['step_database_created_news']);
} }
} }

View File

@@ -6,7 +6,7 @@
<title>MyAAC - <?php echo $locale['installation']; ?></title> <title>MyAAC - <?php echo $locale['installation']; ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" 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" /> <link rel="stylesheet" type="text/css" href="template/style.css" />
<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/ext/jquery/jquery.min.js"></script> <script type="text/javascript" src="<?php echo BASE_URL; ?>tools/js/jquery.min.js"></script>
</head> </head>
<body> <body>

View File

@@ -11,10 +11,8 @@ $error = false;
require BASE . 'install/includes/config.php'; require BASE . 'install/includes/config.php';
ini_set('max_execution_time', 300); ini_set('max_execution_time', 300);
@ob_end_flush();
ob_implicit_flush(); ob_implicit_flush();
ob_end_flush();
header('X-Accel-Buffering: no'); header('X-Accel-Buffering: no');
if(!$error) { if(!$error) {
@@ -180,17 +178,17 @@ if(!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion
} }
if($db->hasColumn('players', 'hide_char')) { if($db->hasColumn('players', 'hide_char')) {
if(!$db->hasColumn('players', 'hide')) { if(!$db->hasColumn('players', 'hidden')) {
if(query("ALTER TABLE `players` CHANGE `hide_char` `hide` TINYINT(1) NOT NULL DEFAULT 0;")) { if(query("ALTER TABLE `players` CHANGE `hide_char` `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']); $tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'players.hide', $tmp); $tmp = str_replace('$FIELD_NEW$', 'players.hidden', $tmp);
success($tmp); success($tmp);
} }
} }
} }
else if(!$db->hasColumn('players', 'hide')) { else if(!$db->hasColumn('players', 'hidden')) {
if(query("ALTER TABLE `players` ADD `hide` TINYINT(1) NOT NULL DEFAULT 0;")) if(query("ALTER TABLE `players` ADD `hidden` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.hide...'); success($locale['step_database_adding_field'] . ' players.hidden...');
} }
if(!$db->hasColumn('players', 'comment')) { if(!$db->hasColumn('players', 'comment')) {

View File

@@ -1,10 +1,6 @@
<?php <?php
define('MYAAC_INSTALL', true); define('MYAAC_INSTALL', true);
use MyAAC\DataLoader;
use MyAAC\Models\FAQ as ModelsFAQ;
use MyAAC\Plugins;
require_once '../../common.php'; require_once '../../common.php';
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';
@@ -12,10 +8,8 @@ require BASE . 'install/includes/functions.php';
require BASE . 'install/includes/locale.php'; require BASE . 'install/includes/locale.php';
ini_set('max_execution_time', 300); ini_set('max_execution_time', 300);
@ob_end_flush();
ob_implicit_flush(); ob_implicit_flush();
ob_end_flush();
header('X-Accel-Buffering: no'); header('X-Accel-Buffering: no');
/* /*
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) { if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
@@ -35,7 +29,7 @@ function insert_sample_if_not_exist($p) {
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote($p['name'])); $query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote($p['name']));
if($query->rowCount() == 0) { if($query->rowCount() == 0) {
if(!query("INSERT INTO `players` (`id`, `name`, `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `maglevel`, `mana`, `manamax`, `manaspent`, `soul`, `town_id`, `posx`, `posy`, `posz`, `conditions`, `cap`, `sex`, `lastlogin`, `lastip`, `save`, `lastlogout`, `balance`, `$deleted`, `created`, `hide`, `comment`) VALUES (null, " . $db->quote($p['name']) . ", 1, " . getSession('account') . ", " . $p['level'] . ", " . $p['vocation_id'] . ", " . $p['health'] . ", " . $p['healthmax'] . ", " . $p['experience'] . ", 118, 114, 38, 57, " . $p['looktype'] . ", 0, " . $p['mana'] . ", " . $p['manamax'] . ", 0, " . $p['soul'] . ", 1, 1000, 1000, 7, '', " . $p['cap'] . ", 1, " . $time . ", 2130706433, 1, " . $time . ", 0, 0, " . $time . ", 1, '');")) if(!query("INSERT INTO `players` (`id`, `name`, `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `maglevel`, `mana`, `manamax`, `manaspent`, `soul`, `town_id`, `posx`, `posy`, `posz`, `conditions`, `cap`, `sex`, `lastlogin`, `lastip`, `save`, `lastlogout`, `balance`, `$deleted`, `created`, `hidden`, `comment`) VALUES (null, " . $db->quote($p['name']) . ", 1, " . getSession('account') . ", " . $p['level'] . ", " . $p['vocation_id'] . ", " . $p['health'] . ", " . $p['healthmax'] . ", " . $p['experience'] . ", 118, 114, 38, 57, " . $p['looktype'] . ", 0, " . $p['mana'] . ", " . $p['manamax'] . ", 0, " . $p['soul'] . ", 1, 1000, 1000, 7, '', " . $p['cap'] . ", 1, " . $time . ", 2130706433, 1, " . $time . ", 0, 0, " . $time . ", 1, '');"))
$success = false; $success = false;
} }
} }
@@ -51,9 +45,7 @@ if($success) {
success($locale['step_database_imported_players']); success($locale['step_database_imported_players']);
} }
Plugins::installMenus('kathrine', require TEMPLATES . 'kathrine/menus.php'); require LIBS . 'DataLoader.php';
Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php');
DataLoader::setLocale($locale); DataLoader::setLocale($locale);
DataLoader::load(); DataLoader::load();
@@ -67,18 +59,6 @@ require_once SYSTEM . 'migrations/22.php';
require_once SYSTEM . 'migrations/27.php'; require_once SYSTEM . 'migrations/27.php';
require_once SYSTEM . 'migrations/30.php'; require_once SYSTEM . 'migrations/30.php';
// new monster columns
require_once SYSTEM . 'migrations/31.php';
if(ModelsFAQ::count() == 0) {
ModelsFAQ::create([
'question' => 'What is this?',
'answer' => 'This is website for OTS powered by MyAAC.',
]);
}
$db->setClearCacheAfter(true);
$locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']); $locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(str_replace('tools/', '', BASE_URL), $locale['step_finish_homepage'], true), $locale['step_finish_desc']); $locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(str_replace('tools/', '', BASE_URL), $locale['step_finish_homepage'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$LINK$', generateLink('https://my-aac.org', 'https://my-aac.org', true), $locale['step_finish_desc']); $locale['step_finish_desc'] = str_replace('$LINK$', generateLink('https://my-aac.org', 'https://my-aac.org', true), $locale['step_finish_desc']);

102
login.php
View File

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

View File

@@ -25,7 +25,7 @@ server {
} }
location / { location / {
try_files $uri $uri/ /index.php?$query_string;; try_files $uri $uri/ /index.php;
} }
location ~ \.php$ { location ~ \.php$ {

View File

@@ -1,16 +0,0 @@
const fse = require('fs-extra');
const path = require('path');
const nodeModulesDir = path.join(__dirname, 'node_modules');
const publicDir = path.join(__dirname, 'tools/ext');
fse.emptyDirSync(path.join(publicDir, 'jquery'));
fse.emptyDirSync(path.join(publicDir, 'jquery-ui'));
fse.emptyDirSync(path.join(publicDir, 'bootstrap'));
fse.emptyDirSync(path.join(publicDir, 'tinymce'));
fse.emptyDirSync(path.join(publicDir, 'tinymce-jquery'));
fse.copySync(path.join(nodeModulesDir, 'jquery', 'dist'), path.join(publicDir, 'jquery'), { overwrite: true });
fse.copySync(path.join(nodeModulesDir, 'jquery-ui', 'dist'), path.join(publicDir, 'jquery-ui'), { overwrite: true });
fse.copySync(path.join(nodeModulesDir, 'bootstrap', 'dist'), path.join(publicDir, 'bootstrap'), { overwrite: true });
fse.copySync(path.join(nodeModulesDir, 'tinymce'), path.join(publicDir, 'tinymce'), { overwrite: true });
fse.copySync(path.join(nodeModulesDir, '@tinymce', 'tinymce-jquery', 'dist'), path.join(publicDir, 'tinymce-jquery'), { overwrite: true });

433
package-lock.json generated
View File

@@ -4,15 +4,6 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"hasInstallScript": true,
"dependencies": {
"@tinymce/tinymce-jquery": "^2.1.0",
"bootstrap": "^4.6.2",
"fs-extra": "^11.2.0",
"jquery": "^3.7.1",
"jquery-ui": "^1.13.2",
"tinymce": "^6.8.3"
},
"devDependencies": { "devDependencies": {
"cypress": "^12.12.0" "cypress": "^12.12.0"
} }
@@ -28,9 +19,9 @@
} }
}, },
"node_modules/@cypress/request": { "node_modules/@cypress/request": {
"version": "2.88.12", "version": "2.88.11",
"resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.12.tgz", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz",
"integrity": "sha512-tOn+0mDZxASFM+cuAP9szGUGPI1HwWVSvdzm7V4cCsPdFTx6qMj29CwaQmRAMIEhORIUBFBsYROYJcveK4uOjA==", "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"aws-sign2": "~0.7.0", "aws-sign2": "~0.7.0",
@@ -48,7 +39,7 @@
"performance-now": "^2.1.0", "performance-now": "^2.1.0",
"qs": "~6.10.3", "qs": "~6.10.3",
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"tough-cookie": "^4.1.3", "tough-cookie": "~2.5.0",
"tunnel-agent": "^0.6.0", "tunnel-agent": "^0.6.0",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
@@ -75,15 +66,10 @@
"ms": "^2.1.1" "ms": "^2.1.1"
} }
}, },
"node_modules/@tinymce/tinymce-jquery": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tinymce/tinymce-jquery/-/tinymce-jquery-2.1.0.tgz",
"integrity": "sha512-ynfgfL/n5/Us7h3AnJL3mAwsShuE/USvAJFOdilJDkZuVCypWSwVVo3E3wIqSzDGvqyU+293ok1+sD+jxraT8w=="
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "16.18.82", "version": "14.18.47",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.47.tgz",
"integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==", "integrity": "sha512-OuJi8bIng4wYHHA3YpKauL58dZrPxro3d0tabPHyiNF8rKfGKuVfr83oFlPLmKri1cX+Z3cJP39GXmnqkP11Gw==",
"dev": true "dev": true
}, },
"node_modules/@types/sinonjs__fake-timers": { "node_modules/@types/sinonjs__fake-timers": {
@@ -93,15 +79,15 @@
"dev": true "dev": true
}, },
"node_modules/@types/sizzle": { "node_modules/@types/sizzle": {
"version": "2.3.8", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
"integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
"dev": true "dev": true
}, },
"node_modules/@types/yauzl": { "node_modules/@types/yauzl": {
"version": "2.10.3", "version": "2.10.0",
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
"dev": true, "dev": true,
"optional": true, "optional": true,
"dependencies": { "dependencies": {
@@ -217,9 +203,9 @@
} }
}, },
"node_modules/async": { "node_modules/async": {
"version": "3.2.5", "version": "3.2.4",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
"dev": true "dev": true
}, },
"node_modules/asynckit": { "node_modules/asynckit": {
@@ -299,25 +285,6 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true "dev": true
}, },
"node_modules/bootstrap": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz",
"integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"peerDependencies": {
"jquery": "1.9.1 - 3",
"popper.js": "^1.16.1"
}
},
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -362,28 +329,22 @@
} }
}, },
"node_modules/cachedir": { "node_modules/cachedir": {
"version": "2.4.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
"integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/call-bind": { "node_modules/call-bind": {
"version": "1.0.7", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"es-define-property": "^1.0.0", "function-bind": "^1.1.1",
"es-errors": "^1.3.0", "get-intrinsic": "^1.0.2"
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@@ -433,9 +394,9 @@
} }
}, },
"node_modules/ci-info": { "node_modules/ci-info": {
"version": "3.9.0", "version": "3.8.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz",
"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -580,15 +541,15 @@
} }
}, },
"node_modules/cypress": { "node_modules/cypress": {
"version": "12.17.4", "version": "12.12.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-12.17.4.tgz", "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.12.0.tgz",
"integrity": "sha512-gAN8Pmns9MA5eCDFSDJXWKUpaL3IDd89N9TtIupjYnzLSmlpVr+ZR+vb4U/qaMp+lB6tBvAmt7504c3Z4RU5KQ==", "integrity": "sha512-UU5wFQ7SMVCR/hyKok/KmzG6fpZgBHHfrXcHzDmPHWrT+UUetxFzQgt7cxCszlwfozckzwkd22dxMwl/vNkWRw==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@cypress/request": "2.88.12", "@cypress/request": "^2.88.10",
"@cypress/xvfb": "^1.2.4", "@cypress/xvfb": "^1.2.4",
"@types/node": "^16.18.39", "@types/node": "^14.14.31",
"@types/sinonjs__fake-timers": "8.1.1", "@types/sinonjs__fake-timers": "8.1.1",
"@types/sizzle": "^2.3.2", "@types/sizzle": "^2.3.2",
"arch": "^2.2.0", "arch": "^2.2.0",
@@ -621,10 +582,9 @@
"minimist": "^1.2.8", "minimist": "^1.2.8",
"ospath": "^1.2.2", "ospath": "^1.2.2",
"pretty-bytes": "^5.6.0", "pretty-bytes": "^5.6.0",
"process": "^0.11.10",
"proxy-from-env": "1.0.0", "proxy-from-env": "1.0.0",
"request-progress": "^3.0.0", "request-progress": "^3.0.0",
"semver": "^7.5.3", "semver": "^7.3.2",
"supports-color": "^8.1.1", "supports-color": "^8.1.1",
"tmp": "~0.2.1", "tmp": "~0.2.1",
"untildify": "^4.0.0", "untildify": "^4.0.0",
@@ -637,21 +597,6 @@
"node": "^14.0.0 || ^16.0.0 || >=18.0.0" "node": "^14.0.0 || ^16.0.0 || >=18.0.0"
} }
}, },
"node_modules/cypress/node_modules/fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"dev": true,
"dependencies": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/dashdash": { "node_modules/dashdash": {
"version": "1.14.1", "version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -665,9 +610,9 @@
} }
}, },
"node_modules/dayjs": { "node_modules/dayjs": {
"version": "1.11.10", "version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==",
"dev": true "dev": true
}, },
"node_modules/debug": { "node_modules/debug": {
@@ -687,23 +632,6 @@
} }
} }
}, },
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": { "node_modules/delayed-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -739,39 +667,17 @@
} }
}, },
"node_modules/enquirer": { "node_modules/enquirer": {
"version": "2.4.1", "version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
"integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"ansi-colors": "^4.1.1", "ansi-colors": "^4.1.1"
"strip-ansi": "^6.0.1"
}, },
"engines": { "engines": {
"node": ">=8.6" "node": ">=8.6"
} }
}, },
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dev": true,
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escape-string-regexp": { "node_modules/escape-string-regexp": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -905,16 +811,18 @@
} }
}, },
"node_modules/fs-extra": { "node_modules/fs-extra": {
"version": "11.2.0", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"dev": true,
"dependencies": { "dependencies": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0", "graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1", "jsonfile": "^6.0.1",
"universalify": "^2.0.0" "universalify": "^2.0.0"
}, },
"engines": { "engines": {
"node": ">=14.14" "node": ">=10"
} }
}, },
"node_modules/fs.realpath": { "node_modules/fs.realpath": {
@@ -924,28 +832,21 @@
"dev": true "dev": true
}, },
"node_modules/function-bind": { "node_modules/function-bind": {
"version": "1.1.2", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true, "dev": true
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
}, },
"node_modules/get-intrinsic": { "node_modules/get-intrinsic": {
"version": "1.2.4", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"es-errors": "^1.3.0", "function-bind": "^1.1.1",
"function-bind": "^1.1.2", "has": "^1.0.3",
"has-proto": "^1.0.1", "has-proto": "^1.0.1",
"has-symbols": "^1.0.3", "has-symbols": "^1.0.3"
"hasown": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@@ -1019,22 +920,23 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"dev": true,
"dependencies": {
"get-intrinsic": "^1.1.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": { "node_modules/graceful-fs": {
"version": "4.2.11", "version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4.0"
}
}, },
"node_modules/has-flag": { "node_modules/has-flag": {
"version": "4.0.0", "version": "4.0.0",
@@ -1045,18 +947,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dev": true,
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": { "node_modules/has-proto": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
@@ -1081,18 +971,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/hasown": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
"integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-signature": { "node_modules/http-signature": {
"version": "1.3.6", "version": "1.3.6",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
@@ -1258,19 +1136,6 @@
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
"dev": true "dev": true
}, },
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
},
"node_modules/jquery-ui": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.13.2.tgz",
"integrity": "sha512-wBZPnqWs5GaYJmo1Jj0k/mrSkzdQzKDwhXNtHKcBdAcKVxMM3KNYFq+iJ2i1rwiG53Z8M4mTn3Qxrm17uH1D4Q==",
"dependencies": {
"jquery": ">=1.8.0 <4.0.0"
}
},
"node_modules/jsbn": { "node_modules/jsbn": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -1293,6 +1158,7 @@
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
"dependencies": { "dependencies": {
"universalify": "^2.0.0" "universalify": "^2.0.0"
}, },
@@ -1516,9 +1382,9 @@
} }
}, },
"node_modules/object-inspect": { "node_modules/object-inspect": {
"version": "1.13.1", "version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
"dev": true, "dev": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@@ -1608,17 +1474,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
"deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/pretty-bytes": { "node_modules/pretty-bytes": {
"version": "5.6.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
@@ -1631,15 +1486,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"dev": true,
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/proxy-from-env": { "node_modules/proxy-from-env": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
@@ -1663,9 +1509,9 @@
} }
}, },
"node_modules/punycode": { "node_modules/punycode": {
"version": "2.3.1", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
@@ -1686,12 +1532,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
"dev": true
},
"node_modules/request-progress": { "node_modules/request-progress": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
@@ -1701,12 +1541,6 @@
"throttleit": "^1.0.0" "throttleit": "^1.0.0"
} }
}, },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true
},
"node_modules/restore-cursor": { "node_modules/restore-cursor": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
@@ -1721,9 +1555,9 @@
} }
}, },
"node_modules/rfdc": { "node_modules/rfdc": {
"version": "1.3.1", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
"integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
"dev": true "dev": true
}, },
"node_modules/rimraf": { "node_modules/rimraf": {
@@ -1777,9 +1611,9 @@
"dev": true "dev": true
}, },
"node_modules/semver": { "node_modules/semver": {
"version": "7.6.0", "version": "7.5.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"lru-cache": "^6.0.0" "lru-cache": "^6.0.0"
@@ -1791,23 +1625,6 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/set-function-length": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
"integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
"dev": true,
"dependencies": {
"define-data-property": "^1.1.2",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.3",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/shebang-command": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -1830,18 +1647,14 @@
} }
}, },
"node_modules/side-channel": { "node_modules/side-channel": {
"version": "1.0.5", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"call-bind": "^1.0.6", "call-bind": "^1.0.0",
"es-errors": "^1.3.0", "get-intrinsic": "^1.0.2",
"get-intrinsic": "^1.2.4", "object-inspect": "^1.9.0"
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@@ -1868,9 +1681,9 @@
} }
}, },
"node_modules/sshpk": { "node_modules/sshpk": {
"version": "1.18.0", "version": "1.17.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
"integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"asn1": "~0.2.3", "asn1": "~0.2.3",
@@ -1943,13 +1756,10 @@
} }
}, },
"node_modules/throttleit": { "node_modules/throttleit": {
"version": "1.0.1", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
"integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==",
"dev": true, "dev": true
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
}, },
"node_modules/through": { "node_modules/through": {
"version": "2.3.8", "version": "2.3.8",
@@ -1957,11 +1767,6 @@
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"dev": true "dev": true
}, },
"node_modules/tinymce": {
"version": "6.8.3",
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.8.3.tgz",
"integrity": "sha512-3fCHKAeqT+xNwBVESf6iDbDV0VNwZNmfrkx9c/6Gz5iB8piMfaO6s7FvoiTrj1hf1gVbfyLTnz1DooI6DhgINQ=="
},
"node_modules/tmp": { "node_modules/tmp": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
@@ -1975,33 +1780,22 @@
} }
}, },
"node_modules/tough-cookie": { "node_modules/tough-cookie": {
"version": "4.1.3", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"psl": "^1.1.33", "psl": "^1.1.28",
"punycode": "^2.1.1", "punycode": "^2.1.1"
"universalify": "^0.2.0",
"url-parse": "^1.5.3"
}, },
"engines": { "engines": {
"node": ">=6" "node": ">=0.8"
}
},
"node_modules/tough-cookie/node_modules/universalify": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
"dev": true,
"engines": {
"node": ">= 4.0.0"
} }
}, },
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.6.2", "version": "2.5.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.1.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "integrity": "sha512-KaI6gPil5m9vF7DKaoXxx1ia9fxS4qG5YveErRRVknPDXXriu5M8h48YRjB6h5ZUOKuAKlSJYb0GaDe8I39fRw==",
"dev": true "dev": true
}, },
"node_modules/tunnel-agent": { "node_modules/tunnel-agent": {
@@ -2035,9 +1829,10 @@
} }
}, },
"node_modules/universalify": { "node_modules/universalify": {
"version": "2.0.1", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
"dev": true,
"engines": { "engines": {
"node": ">= 10.0.0" "node": ">= 10.0.0"
} }
@@ -2051,16 +1846,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"dev": true,
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"node_modules/uuid": { "node_modules/uuid": {
"version": "8.3.2", "version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",

View File

@@ -1,17 +1,5 @@
{ {
"scripts": {
"cypress:open": "cypress open",
"postinstall": "node ./npm-post-install.js"
},
"devDependencies": { "devDependencies": {
"cypress": "^12.12.0" "cypress": "^12.12.0"
},
"dependencies": {
"@tinymce/tinymce-jquery": "^2.1.0",
"bootstrap": "^4.6.2",
"fs-extra": "^11.2.0",
"jquery": "^3.7.1",
"jquery-ui": "^1.13.2",
"tinymce": "^6.8.3"
} }
} }

View File

@@ -1,13 +0,0 @@
<?php
require __DIR__ . '/system/libs/pot/OTS.php';
$ots = POT::getInstance();
require __DIR__ . '/system/libs/pot/InvitesDriver.php';
require __DIR__ . '/system/libs/rfc6238.php';
require __DIR__ . '/common.php';
const ACTION = '';
const PAGE = '';
const URI = '';
define('SELF_NAME', basename(__FILE__));

View File

@@ -1,38 +0,0 @@
parameters:
level: 3
paths:
- .
- templates/tibiacom
- templates/kathrine
excludePaths:
- system/cache/*
- vendor/*
- plugins/*
- system/libs
- tools/signature/mango.php
- tools/signature/gd.class.php
bootstrapFiles:
- phpstan-bootstrap.php
ignoreErrors:
- '#Variable \$db might not be defined#'
- '#Variable \$twig might not be defined#'
- '#Variable \$hooks might not be defined#'
- '#Variable \$account_logged might not be defined#'
- '#Variable \$logged might not be defined#'
- '#Variable \$config might not be defined#'
- '#Variable \$action might not be defined#'
- '#Variable \$errors might not be defined#'
- '#Variable \$cache might not be defined#'
- '#Variable \$status might not be defined#'
- '#Variable \$player might not be defined#'
- '#Variable \$guild might not be defined#'
- '#Variable \$[a-zA-Z0-9\\_]+ might not be defined#'
# Eloquent models
- '#Call to an undefined static method [a-zA-Z0-9\\_]+::[a-zA-Z0-9\\_]+()#'
# system/pages/highscores.php
- '#Call to an undefined method Illuminate\\Database\\Query\\Builder::withOnlineStatus\(\)#'
- '#Access to an undefined property Illuminate\\Database\\Eloquent\\Model::\$online_status#'
- '#Access to an undefined property Illuminate\\Database\\Eloquent\\Model::\$vocation_name#'
-
message: '#Variable \$tmp in empty\(\) always exists and is always falsy#'
path: templates\kathrine\javascript.php

View File

@@ -1,3 +1,3 @@
To play on {{ config.lua.serverName }} you need an account. 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 setting('core.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/> 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/>

View File

@@ -1,37 +1,33 @@
<?php <?php
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$reward = setting('core.account_mail_confirmed_reward'); $reward = config('account_mail_confirmed_reward');
$hasCoinsColumn = $db->hasColumn('accounts', 'coins'); $hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$rewardCoins = setting('core.account_mail_confirmed_reward_coins'); if ($reward['coins'] > 0 && $hasCoinsColumn) {
if ($rewardCoins > 0 && !$hasCoinsColumn) { log_append('email_confirm_error.log', 'accounts.coins column does not exist.');
log_append('error.log', 'email_confirm: accounts.coins column does not exist.');
} }
if (!isset($account) || !$account->isLoaded()) { if (!isset($account) || !$account->isLoaded()) {
log_append('email_confirm_error.log', 'Account not loaded.');
return; return;
} }
$rewardMessage = 'You received %d %s for confirming your E-Mail address.'; if ($reward['premium_points'] > 0) {
$account->setCustomField('premium_points', (int)$account->getCustomField('premium_points') + $reward['premium_points']);
$rewardPremiumPoints = setting('core.account_mail_confirmed_reward_premium_points'); success(sprintf($reward['message'], $reward['premium_points'], 'premium points'));
if ($rewardPremiumPoints > 0) {
$account->setCustomField('premium_points', (int)$account->getCustomField('premium_points') + $rewardPremiumPoints);
success(sprintf($rewardMessage, $rewardPremiumPoints, 'premium points'));
} }
if ($rewardCoins > 0 && $hasCoinsColumn) { if ($reward['coins'] > 0 && $hasCoinsColumn) {
$account->setCustomField('coins', (int)$account->getCustomField('coins') + $rewardCoins); $account->setCustomField('coins', (int)$account->getCustomField('coins') + $reward['coins']);
success(sprintf($rewardMessage, $rewardCoins, 'coins')); success(sprintf($reward['message'], $reward['coins'], 'coins'));
} }
$rewardPremiumDays = setting('core.account_mail_confirmed_reward_premium_days'); if ($reward['premium_days'] > 0) {
if ($rewardPremiumDays > 0) { $account->setPremDays($account->getPremDays() + $reward['premium_days']);
$account->setPremDays($account->getPremDays() + $rewardPremiumDays);
$account->save(); $account->save();
success(sprintf($rewardMessage, $rewardPremiumDays, 'premium days')); success(sprintf($reward['message'], $reward['premium_days'], 'premium days'));
} }

View File

@@ -38,7 +38,7 @@ if [ $1 = "prepare" ]; then
cd $dir || exit cd $dir || exit
# dependencies # dependencies
composer install --prefer-dist --optimize-autoloader composer install --no-dev
echo "Now you can make changes to $dir. When you are ready, type 'release.sh pack'" echo "Now you can make changes to $dir. When you are ready, type 'release.sh pack'"
exit exit

View File

@@ -0,0 +1,18 @@
<?php
if(PHP_SAPI !== 'cli') {
echo 'This script can be run only in command line mode.';
exit(1);
}
require_once __DIR__ . '/../../common.php';
require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php';
if(clearCache()) {
echo 'Cache cleared.' . PHP_EOL;
}
else {
echo 'Unexpected error.' . PHP_EOL;
exit(2);
}

View File

@@ -0,0 +1,42 @@
<?php
if(PHP_SAPI !== 'cli') {
echo 'This script can be run only in command line mode.';
exit(1);
}
require_once __DIR__ . '/../../common.php';
require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php';
require_once SYSTEM . 'hooks.php';
require_once LIBS . 'plugins.php';
if($argc !== 2) {
echo 'This command expects one parameter: zip file name (plugin)' . PHP_EOL;
exit(2);
}
$path_to_file = $argv[1];
$ext = strtolower(pathinfo($path_to_file, PATHINFO_EXTENSION));
if($ext !== 'zip') {// check if it is zipped/compressed file
echo 'Please install only .zip files.' . PHP_EOL;
exit(3);
}
if(!file_exists($path_to_file)) {
echo 'ERROR: File ' . $path_to_file . ' does not exist' . PHP_EOL;
exit(4);
}
if(Plugins::install($path_to_file)) {
foreach(Plugins::getWarnings() as $warning) {
echo 'WARNING: ' . $warning;
}
$info = Plugins::getPluginJson();
echo (isset($info['name']) ? $info['name'] . ' p' : 'P') . 'lugin has been successfully installed.' . PHP_EOL;
}
else {
echo 'ERROR: ' . Plugins::getError() . PHP_EOL;
exit(5);
}

61
system/bin/send_email.php Normal file
View File

@@ -0,0 +1,61 @@
<?php
if(PHP_SAPI !== 'cli') {
echo 'This script can be run only in command line mode.';
exit(1);
}
require_once __DIR__ . '/../../common.php';
require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php';
if($argc !== 3) {
echo 'This command expects two parameters: account_name_or_id|player_name|email address, subject.' . PHP_EOL;
exit(2);
}
$email_account_name = $argv[1];
$subject = $argv[2];
$message = file_get_contents('php://stdin');
if(strpos($email_account_name, '@') === false) {
$account = new OTS_Account();
if(USE_ACCOUNT_NAME) {
$account->find($email_account_name);
}
else {
$account->load($email_account_name);
}
if($account->isLoaded()) {
$email_account_name = $account->getEMail();
}
else {
$player = new OTS_Player();
$player->find($email_account_name);
if($player->isLoaded()) {
$email_account_name = $player->getAccount()->getEMail();
}
else {
echo 'Cannot find player or account with name: ' . $email_account_name . '.' . PHP_EOL;
exit(3);
}
}
}
if(!Validator::email($email_account_name)) {
echo 'Invalid E-Mail format.' . PHP_EOL;
exit(4);
}
if(strlen($subject) > 255) {
echo 'Subject max length is 255 characters.' . PHP_EOL;
exit(5);
}
if(!_mail($email_account_name, $subject, $message)) {
echo 'An error occurred while sending email. More info can be found in system/logs/mailer-error.log';
exit(6);
}
echo 'Mail sent to ' . $email_account_name . '.' . PHP_EOL;

View File

View File

@@ -99,10 +99,4 @@ $config['clients'] = [
1291, 1291,
1300, 1300,
1310,
1311,
1312,
1316,
1320,
1321,
]; ];

View File

@@ -9,8 +9,6 @@
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
class Validator extends \MyAAC\Validator {}
function check_name($name, &$errors = '') { function check_name($name, &$errors = '') {
if(Validator::characterName($name)) if(Validator::characterName($name))
return true; return true;
@@ -74,7 +72,4 @@ function fieldExist($field, $table)
global $db; global $db;
return $db->hasColumn($table, $field); return $db->hasColumn($table, $field);
} }
?>
function getCreatureImgPath($creature): string {
return getMonsterImgPath($creature);
}

View File

@@ -34,18 +34,8 @@ $deprecatedConfig = [
'news_limit', 'news_limit',
'news_ticker_limit', 'news_ticker_limit',
'news_date_format', 'news_date_format',
'guild_management',
'guild_need_level',
'guild_need_premium',
'guild_image_size_kb',
'guild_description_default',
'guild_description_chars_limit',
'guild_motd_chars_limit',
'highscores_groups_hidden', 'highscores_groups_hidden',
'highscores_ids_hidden', 'highscores_ids_hidden',
'highscores_vocation_box',
'highscores_vocation',
'highscores_outfit',
'online_record', 'online_record',
'online_vocations', 'online_vocations',
'online_vocations_images', 'online_vocations_images',
@@ -68,14 +58,9 @@ $deprecatedConfig = [
'status_ip', 'status_ip',
'status_port', 'status_port',
'mail_enabled', 'mail_enabled',
'mail_address',
'account_login_by_email', 'account_login_by_email',
'account_login_by_email_fallback', 'account_login_by_email_fallback',
'account_mail_verify', 'account_mail_verify',
'account_mail_unique',
'account_mail_change',
'account_premium_days',
'account_premium_points',
'account_create_character_create', 'account_create_character_create',
'account_change_character_name', 'account_change_character_name',
'account_change_character_name_points' => 'account_change_character_name_price', 'account_change_character_name_points' => 'account_change_character_name_price',

View File

@@ -44,7 +44,7 @@ switch($page)
break; break;
case 'killstatistics': case 'killstatistics':
$page = 'last-kills'; $page = 'lastkills';
break; break;
case 'buypoints': case 'buypoints':

View File

@@ -7,9 +7,6 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Cache\Cache;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
define('COUNTER_SYNC', 10); // how often counter is synchronized with database (each x site refreshes) define('COUNTER_SYNC', 10); // how often counter is synchronized with database (each x site refreshes)

View File

@@ -7,9 +7,6 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use Illuminate\Database\Capsule\Manager as Capsule;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
if (!isset($config['database_overwrite'])) { if (!isset($config['database_overwrite'])) {
@@ -94,34 +91,21 @@ if(!isset($config['database_socket'])) {
$config['database_socket'] = ''; $config['database_socket'] = '';
} }
try { try {
$ots->connect(array( $ots->connect(array(
'host' => $config['database_host'], 'host' => $config['database_host'],
'user' => $config['database_user'], 'user' => $config['database_user'],
'password' => $config['database_password'], 'password' => $config['database_password'],
'database' => $config['database_name'], 'database' => $config['database_name'],
'log' => $config['database_log'], 'log' => $config['database_log'],
'socket' => @$config['database_socket'], 'socket' => @$config['database_socket'],
'persistent' => @$config['database_persistent'] 'persistent' => @$config['database_persistent']
)); )
);
$db = POT::getInstance()->getDBHandle(); $db = POT::getInstance()->getDBHandle();
$capsule = new Capsule; }
$capsule->addConnection([ catch(PDOException $error) {
'driver' => 'mysql',
'database' => $config['database_name'],
]);
$capsule->getConnection()->setPdo($db);
$capsule->getConnection()->setReadPdo($db);
$capsule->setAsGlobal();
$capsule->bootEloquent();
$eloquentConnection = $capsule->getConnection();
} catch (Exception $e) {
if(isset($cache) && $cache->enabled()) { if(isset($cache) && $cache->enabled()) {
$cache->delete('config_lua'); $cache->delete('config_lua');
} }
@@ -135,5 +119,5 @@ try {
'<ul>' . '<ul>' .
'<li>MySQL is not configured propertly in <i>config.lua</i>.</li>' . '<li>MySQL is not configured propertly in <i>config.lua</i>.</li>' .
'<li>MySQL server is not running.</li>' . '<li>MySQL server is not running.</li>' .
'</ul>' . $e->getMessage()); '</ul>' . $error->getMessage());
} }

View File

@@ -8,8 +8,6 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Exceptions\SensitiveException;
if (class_exists(\Whoops\Run::class)) { if (class_exists(\Whoops\Run::class)) {
$whoops = new \Whoops\Run; $whoops = new \Whoops\Run;
if(IS_CLI) { if(IS_CLI) {
@@ -23,6 +21,8 @@ if (class_exists(\Whoops\Run::class)) {
return; return;
} }
require LIBS . 'SensitiveException.php';
/** /**
* @param Exception $exception * @param Exception $exception
*/ */

View File

@@ -9,17 +9,6 @@
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
use MyAAC\Cache\Cache;
use MyAAC\CsrfToken;
use MyAAC\Items;
use MyAAC\Models\Config;
use MyAAC\Models\Guild;
use MyAAC\Models\House;
use MyAAC\Models\Pages;
use MyAAC\Models\Player;
use MyAAC\News;
use MyAAC\Plugins;
use MyAAC\Settings;
use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\PHPMailer;
use Twig\Loader\ArrayLoader as Twig_ArrayLoader; use Twig\Loader\ArrayLoader as Twig_ArrayLoader;
@@ -49,10 +38,7 @@ function warning($message, $return = false) {
return message($message, 'warning', $return); return message($message, 'warning', $return);
} }
function note($message, $return = false) { function note($message, $return = false) {
return info($message, $return); return message($message, 'note', $return);
}
function info($message, $return = false) {
return message($message, 'info', $return);
} }
function error($message, $return = false) { function error($message, $return = false) {
return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return); return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return);
@@ -105,7 +91,7 @@ function getPlayerLink($name, $generate = true): string
function getMonsterLink($name, $generate = true): string function getMonsterLink($name, $generate = true): string
{ {
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'monsters/' . urlencode($name); $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'creatures/' . urlencode($name);
if(!$generate) return $url; if(!$generate) return $url;
return generateLink($url, $name); return generateLink($url, $name);
@@ -113,15 +99,16 @@ function getMonsterLink($name, $generate = true): string
function getHouseLink($name, $generate = true): string function getHouseLink($name, $generate = true): string
{ {
global $db;
if(is_numeric($name)) if(is_numeric($name))
{ {
$house = House::find(intval($name), ['name']); $house = $db->query(
if ($house) { 'SELECT `name` FROM `houses` WHERE `id` = ' . (int)$name);
$name = $house->name; if($house->rowCount() > 0)
} $name = $house->fetchColumn();
} }
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses/' . urlencode($name); $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses/' . urlencode($name);
if(!$generate) return $url; if(!$generate) return $url;
@@ -131,8 +118,10 @@ function getHouseLink($name, $generate = true): string
function getGuildLink($name, $generate = true): string function getGuildLink($name, $generate = true): string
{ {
if(is_numeric($name)) { if(is_numeric($name)) {
$guild = Guild::find(intval($name), ['name']); $name = getGuildNameById($name);
$name = $guild->name ?? 'Unknown'; if ($name === false) {
$name = 'Unknown';
}
} }
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'guilds/' . urlencode($name); $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'guilds/' . urlencode($name);
@@ -142,6 +131,7 @@ function getGuildLink($name, $generate = true): string
} }
function getItemNameById($id) { function getItemNameById($id) {
require_once LIBS . 'items.php';
$item = Items::get($id); $item = Items::get($id);
return !empty($item['name']) ? $item['name'] : ''; return !empty($item['name']) ? $item['name'] : '';
} }
@@ -159,7 +149,8 @@ function getItemImage($id, $count = 1)
if($count > 1) if($count > 1)
$file_name .= '-' . $count; $file_name .= '-' . $count;
return '<img src="' . setting('core.item_images_url') . $file_name . setting('core.item_images_extension') . '"' . $tooltip . ' width="32" height="32" border="0" alt="' .$id . '" />'; global $config;
return '<img src="' . $config['item_images_url'] . $file_name . config('item_images_extension') . '"' . $tooltip . ' width="32" height="32" border="0" alt="' .$id . '" />';
} }
function getItemRarity($chance) { function getItemRarity($chance) {
@@ -201,7 +192,7 @@ function getFlagImage($country): string
* @param mixed $v Variable to check. * @param mixed $v Variable to check.
* @return bool Value boolean status. * @return bool Value boolean status.
*/ */
function getBoolean(mixed $v): bool function getBoolean($v): bool
{ {
if(is_bool($v)) { if(is_bool($v)) {
return $v; return $v;
@@ -210,10 +201,6 @@ function getBoolean(mixed $v): bool
if(is_numeric($v)) if(is_numeric($v))
return (int)$v > 0; return (int)$v > 0;
if (is_null($v)) {
return false;
}
$v = strtolower($v); $v = strtolower($v);
return $v === 'yes' || $v === 'true'; return $v === 'yes' || $v === 'true';
} }
@@ -261,7 +248,7 @@ function generateRandomString($length, $lowCase = true, $upCase = false, $numeri
function getForumBoards() function getForumBoards()
{ {
global $db, $canEdit; global $db, $canEdit;
$sections = $db->query('SELECT `id`, `name`, `description`, `closed`, `guild`, `access`' . ($canEdit ? ', `hide`, `ordering`' : '') . ' FROM `' . TABLE_PREFIX . 'forum_boards` ' . (!$canEdit ? ' WHERE `hide` != 1' : '') . $sections = $db->query('SELECT `id`, `name`, `description`, `closed`, `guild`, `access`' . ($canEdit ? ', `hidden`, `ordering`' : '') . ' FROM `' . TABLE_PREFIX . 'forum_boards` ' . (!$canEdit ? ' WHERE `hidden` != 1' : '') .
' ORDER BY `ordering`;'); ' ORDER BY `ordering`;');
if($sections) if($sections)
return $sections->fetchAll(); return $sections->fetchAll();
@@ -285,12 +272,13 @@ function getForumBoards()
*/ */
function fetchDatabaseConfig($name, &$value) function fetchDatabaseConfig($name, &$value)
{ {
$config = Config::select('value')->where('name', '=', $name)->first(); global $db;
if (!$config) {
return false;
}
$value = $config->value; $query = $db->query('SELECT `value` FROM `' . TABLE_PREFIX . 'config` WHERE `name` = ' . $db->quote($name));
if($query->rowCount() <= 0)
return false;
$value = $query->fetchColumn();
return true; return true;
} }
@@ -315,7 +303,8 @@ function getDatabaseConfig($name)
*/ */
function registerDatabaseConfig($name, $value) function registerDatabaseConfig($name, $value)
{ {
Config::create(compact('name', 'value')); global $db;
$db->insert(TABLE_PREFIX . 'config', array('name' => $name, 'value' => $value));
} }
/** /**
@@ -326,9 +315,8 @@ function registerDatabaseConfig($name, $value)
*/ */
function updateDatabaseConfig($name, $value) function updateDatabaseConfig($name, $value)
{ {
Config::where('name', '=', $name)->update([ global $db;
'value' => $value $db->update(TABLE_PREFIX . 'config', array('value' => $value), array('name' => $name));
]);
} }
/** /**
@@ -355,55 +343,47 @@ function encrypt($str)
//delete player with name //delete player with name
function delete_player($name) function delete_player($name)
{ {
// DB::beginTransaction(); global $db;
global $capsule; $player = new OTS_Player();
$player = Player::where(compact('name'))->first(); $player->find($name);
if (!$player) { if($player->isLoaded()) {
return false; try { $db->exec("DELETE FROM player_skills WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM guild_invites WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_items WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_depotitems WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_spells WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_storage WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_viplist WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_deaths WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
try { $db->exec("DELETE FROM player_deaths WHERE killed_by = '".$player->getId()."';"); } catch(PDOException $error) {}
$rank = $player->getRank();
if($rank->isLoaded()) {
$guild = $rank->getGuild();
if($guild->getOwner()->getId() == $player->getId()) {
$rank_list = $guild->getGuildRanksList();
if(count($rank_list) > 0) {
$rank_list->orderBy('level');
foreach($rank_list as $rank_in_guild) {
$players_with_rank = $rank_in_guild->getPlayersList();
$players_with_rank->orderBy('name');
$players_with_rank_number = count($players_with_rank);
if($players_with_rank_number > 0) {
foreach($players_with_rank as $player_in_guild) {
$player_in_guild->setRank();
$player_in_guild->save();
}
}
$rank_in_guild->delete();
}
$guild->delete();
}
}
}
$player->delete();
return true;
} }
return false; return false;
// global $db;
// $player = new OTS_Player();
// $player->find($name);
// if($player->isLoaded()) {
// try { $db->exec("DELETE FROM player_skills WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM guild_invites WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_items WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_depotitems WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_spells WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_storage WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_viplist WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_deaths WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {}
// try { $db->exec("DELETE FROM player_deaths WHERE killed_by = '".$player->getId()."';"); } catch(PDOException $error) {}
// $rank = $player->getRank();
// if($rank->isLoaded()) {
// $guild = $rank->getGuild();
// if($guild->getOwner()->getId() == $player->getId()) {
// $rank_list = $guild->getGuildRanksList();
// if(count($rank_list) > 0) {
// $rank_list->orderBy('level');
// foreach($rank_list as $rank_in_guild) {
// $players_with_rank = $rank_in_guild->getPlayersList();
// $players_with_rank->orderBy('name');
// $players_with_rank_number = count($players_with_rank);
// if($players_with_rank_number > 0) {
// foreach($players_with_rank as $player_in_guild) {
// $player_in_guild->setRank();
// $player_in_guild->save();
// }
// }
// $rank_in_guild->delete();
// }
// $guild->delete();
// }
// }
// }
// $player->delete();
// return true;
// }
// return false;
} }
//delete guild with id //delete guild with id
@@ -418,10 +398,7 @@ function delete_guild($id)
if(count($rank_list) > 0) { if(count($rank_list) > 0) {
$rank_list->orderBy('level'); $rank_list->orderBy('level');
global $db; global $db, $ots;
/**
* @var OTS_GuildRank $rank_in_guild
*/
foreach($rank_list as $rank_in_guild) { foreach($rank_list as $rank_in_guild) {
if($db->hasTable('guild_members')) if($db->hasTable('guild_members'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;'); $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;');
@@ -480,30 +457,20 @@ function tickers()
*/ */
function template_place_holder($type): string function template_place_holder($type): string
{ {
global $twig, $template_place_holders, $debugBar; global $twig, $template_place_holders;
$ret = ''; $ret = '';
if (isset($debugBar)) {
$debugBarRenderer = $debugBar->getJavascriptRenderer();
}
if(array_key_exists($type, $template_place_holders) && is_array($template_place_holders[$type])) if(array_key_exists($type, $template_place_holders) && is_array($template_place_holders[$type]))
$ret = implode($template_place_holders[$type]); $ret = implode($template_place_holders[$type]);
if($type === 'head_start') { if($type === 'head_start') {
$ret .= template_header(); $ret .= template_header();
if (isset($debugBar)) {
$ret .= $debugBarRenderer->renderHead();
}
} }
elseif ($type === 'body_start') { elseif ($type === 'body_start') {
$ret .= $twig->render('browsehappy.html.twig'); $ret .= $twig->render('browsehappy.html.twig');
} }
elseif($type === 'body_end') { elseif($type === 'body_end') {
$ret .= template_ga_code(); $ret .= template_ga_code();
if (isset($debugBar)) {
$ret .= $debugBarRenderer->render();
}
} }
return $ret; return $ret;
@@ -514,8 +481,8 @@ function template_place_holder($type): string
*/ */
function template_header($is_admin = false): string function template_header($is_admin = false): string
{ {
global $title_full, $twig; global $title_full, $config, $twig;
$charset = setting('core.charset') ?? 'utf-8'; $charset = isset($config['charset']) ? $config['charset'] : 'utf-8';
return $twig->render('templates.header.html.twig', return $twig->render('templates.header.html.twig',
[ [
@@ -713,8 +680,11 @@ function getSkillName($skillId, $suffix = true)
/** /**
* Performs flag check on the current logged in user. * Performs flag check on the current logged in user.
* Table in database: accounts, field: website_flags * Table in database: accounts, field: website_flags
*
* @param int @flag Flag to be verified.
* @return bool If user got flag.
*/ */
function hasFlag(int $flag): bool { function hasFlag($flag) {
global $logged, $logged_flags; global $logged, $logged_flags;
return ($logged && ($logged_flags & $flag) == $flag); return ($logged && ($logged_flags & $flag) == $flag);
} }
@@ -787,7 +757,7 @@ function get_browser_languages()
$languages = str_replace(' ', '', $languages); $languages = str_replace(' ', '', $languages);
foreach(explode(',', $languages) as $language_list) foreach(explode(',', $languages) as $language_list)
$ret[] = substr($language_list, 0, 2); $ret[] .= substr($language_list, 0, 2);
return $ret; return $ret;
} }
@@ -806,10 +776,6 @@ function get_templates()
$ret[] = $file; $ret[] = $file;
} }
foreach (Plugins::getThemes() as $name => $path) {
$ret[] = $name;
}
return $ret; return $ret;
} }
@@ -881,6 +847,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
else else
$tmp_body = $body . '<br/><br/>' . $signature_html; $tmp_body = $body . '<br/><br/>' . $signature_html;
define('MAIL_MAIL', 0);
define('MAIL_SMTP', 1);
$mailOption = setting('core.mail_option'); $mailOption = setting('core.mail_option');
if($mailOption == MAIL_SMTP) if($mailOption == MAIL_SMTP)
{ {
@@ -891,6 +860,10 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->Username = setting('core.smtp_user'); $mailer->Username = setting('core.smtp_user');
$mailer->Password = setting('core.smtp_pass'); $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'); $security = setting('core.smtp_security');
$tmp = ''; $tmp = '';
@@ -1054,36 +1027,14 @@ function get_browser_real_ip() {
return '0'; return '0';
} }
function setSession($key, $data) { function setSession($key, $data) {
$_SESSION[setting('core.session_prefix') . $key] = $data; $_SESSION[config('session_prefix') . $key] = $data;
} }
function getSession($key) { function getSession($key) {
$key = setting('core.session_prefix') . $key; $key = config('session_prefix') . $key;
return isset($_SESSION[$key]) ? $_SESSION[$key] : false; return isset($_SESSION[$key]) ? $_SESSION[$key] : false;
} }
function unsetSession($key) { function unsetSession($key) {
unset($_SESSION[setting('core.session_prefix') . $key]); unset($_SESSION[config('session_prefix') . $key]);
}
function csrf(bool $return = false): string {
return CsrfToken::create($return);
}
function csrfToken(): string {
return CsrfToken::get();
}
function isValidToken(): bool {
$token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null;
return (!isRequestMethod('post') || (isset($token) && CsrfToken::isValid($token)));
}
function csrfProtect(): void
{
if (!isValidToken()) {
$lastUri = BASE_URL . str_replace_first('/', '', getSession('last_uri'));
echo 'Request has been cancelled due to security reasons - token is invalid. Go <a href="' . $lastUri . '">back</a>';
exit();
}
} }
function getTopPlayers($limit = 5) { function getTopPlayers($limit = 5) {
@@ -1098,38 +1049,26 @@ function getTopPlayers($limit = 5) {
} }
if (!isset($players)) { if (!isset($players)) {
$columns = [ $deleted = 'deleted';
'id', 'name', 'level', 'vocation', 'experience', if($db->hasColumn('players', 'deletion'))
'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet' $deleted = 'deletion';
];
if ($db->hasColumn('players', 'lookaddons')) { $is_tfs10 = $db->hasTable('players_online');
$columns[] = 'lookaddons'; $players = $db->query('SELECT `id`, `name`, `level`, `vocation`, `experience`, `looktype`' . ($db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `lookhead`, `lookbody`, `looklegs`, `lookfeet`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . setting('core.highscores_groups_hidden') . ' AND `id` NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll();
if($is_tfs10) {
foreach($players as &$player) {
$query = $db->query('SELECT `player_id` FROM `players_online` WHERE `player_id` = ' . $player['id']);
$player['online'] = ($query->rowCount() > 0 ? 1 : 0);
}
unset($player);
} }
if ($db->hasColumn('players', 'online')) { $i = 0;
$columns[] = 'online'; foreach($players as &$player) {
$player['rank'] = ++$i;
} }
unset($player);
$players = Player::query()
->select($columns)
->withOnlineStatus()
->notDeleted()
->where('group_id', '<', setting('core.highscores_groups_hidden'))
->whereNotIn('id', setting('core.highscores_ids_hidden'))
->where('account_id', '!=', 1)
->orderByDesc('experience')
->limit($limit)
->get()
->map(function ($e, $i) {
$row = $e->toArray();
$row['online'] = $e->online_status;
$row['rank'] = $i + 1;
unset($row['online_table']);
return $row;
})->toArray();
if($cache->enabled()) { if($cache->enabled()) {
$cache->set('top_' . $limit . '_level', serialize($players), 120); $cache->set('top_' . $limit . '_level', serialize($players), 120);
@@ -1203,113 +1142,119 @@ function setting($key)
function clearCache() function clearCache()
{ {
require_once LIBS . 'news.php';
News::clearCache(); News::clearCache();
$cache = Cache::getInstance(); $cache = Cache::getInstance();
if($cache->enabled()) { if($cache->enabled()) {
$keysToClear = [ $tmp = '';
'status', 'templates',
'config_lua',
'towns', 'groups', 'vocations',
'visitors', 'views_counter', 'failed_logins',
'template_menus',
'last_kills',
'hooks', 'plugins_hooks', 'plugins_routes', 'plugins_settings', 'plugins_themes', 'plugins_commands',
'settings',
];
foreach (get_templates() as $template) { if ($cache->fetch('status', $tmp))
$keysToClear[] = 'template_ini_' . $template; $cache->delete('status');
}
// highscores cache if ($cache->fetch('templates', $tmp))
$configHighscoresPerPage = setting('core.highscores_per_page'); $cache->delete('templates');
$skills = [POT::SKILL_FIST, POT::SKILL_CLUB, POT::SKILL_SWORD, POT::SKILL_AXE, POT::SKILL_DIST, POT::SKILL_SHIELD, POT::SKILL_FISH, POT::SKILL_LEVEL, POT::SKILL__MAGLEVEL, SKILL_FRAGS, SKILL_BALANCE];
foreach ($skills as $skill) {
// config('vocations') may be empty after previous cache clear
$vocations = (config('vocations') ?? []) + ['all'];
foreach ($vocations as $vocation) {
for($page = 0; $page < 10; $page++) {
$cacheKey = 'highscores_' . $skill . '_' . strtolower($vocation) . '_' . $page . '_' . $configHighscoresPerPage;
$keysToClear[] = $cacheKey;
}
}
}
foreach ($keysToClear as $item) { if ($cache->fetch('config_lua', $tmp))
$tmp = ''; $cache->delete('config_lua');
if ($cache->fetch($item, $tmp)) {
$cache->delete($item);
}
}
global $db; if ($cache->fetch('vocations', $tmp))
$db->setClearCacheAfter(true); $cache->delete('vocations');
if ($cache->fetch('towns', $tmp))
$cache->delete('towns');
if ($cache->fetch('groups', $tmp))
$cache->delete('groups');
if ($cache->fetch('visitors', $tmp))
$cache->delete('visitors');
if ($cache->fetch('views_counter', $tmp))
$cache->delete('views_counter');
if ($cache->fetch('failed_logins', $tmp))
$cache->delete('failed_logins');
global $template_name;
if ($cache->fetch('template_ini' . $template_name, $tmp))
$cache->delete('template_ini' . $template_name);
if ($cache->fetch('plugins_hooks', $tmp))
$cache->delete('plugins_hooks');
if ($cache->fetch('plugins_routes', $tmp))
$cache->delete('plugins_routes');
} }
deleteDirectory(CACHE . 'signatures', ['index.html'], true); deleteDirectory(CACHE . 'signatures', ['index.html'], true);
deleteDirectory(CACHE . 'twig', ['index.html'], true); deleteDirectory(CACHE . 'twig', ['index.html'], true);
deleteDirectory(CACHE . 'plugins', ['index.html'], true); deleteDirectory(CACHE . 'plugins', ['index.html'], true);
deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html', 'persistent'], true); deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html'], true);
// routes cache // routes cache
clearRouteCache();
global $hooks;
$hooks->trigger(HOOK_CACHE_CLEAR, ['cache' => Cache::getInstance()]);
return true;
}
function clearRouteCache(): void
{
$routeCacheFile = CACHE . 'route.cache'; $routeCacheFile = CACHE . 'route.cache';
if (file_exists($routeCacheFile)) { if (file_exists($routeCacheFile)) {
unlink($routeCacheFile); unlink($routeCacheFile);
} }
return true;
} }
function getCustomPageInfo($name) function getCustomPageInfo($page)
{ {
global $logged_access; global $db, $logged_access;
$page = Pages::isPublic() $query =
->where('name', 'LIKE', $name) $db->query(
->where('access', '<=', $logged_access) 'SELECT `id`, `title`, `body`, `php`, `hidden`' .
->first(); ' FROM `' . TABLE_PREFIX . 'pages`' .
' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access));
if (!$page) { if($query->rowCount() > 0) // found page
return null; {
return $query->fetch(PDO::FETCH_ASSOC);
} }
return $page->toArray(); return null;
} }
function getCustomPage($name, &$success): string function getCustomPage($page, &$success): string
{ {
global $twig, $title, $ignore; global $db, $twig, $title, $ignore, $logged_access;
$success = false; $success = false;
$content = ''; $content = '';
$page = getCustomPageInfo($name); $query =
$db->query(
if($page) // found page 'SELECT `id`, `title`, `body`, `php`, `hidden`' .
' FROM `' . TABLE_PREFIX . 'pages`' .
' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access));
if($query->rowCount() > 0) // found page
{ {
$success = $ignore = true; $success = $ignore = true;
$title = $page['title']; $query = $query->fetch();
$title = $query['title'];
if($page['php'] == '1') // execute it as php code if($query['php'] == '1') // execute it as php code
{ {
$tmp = substr($page['body'], 0, 10); $tmp = substr($query['body'], 0, 10);
if(($pos = strpos($tmp, '<?php')) !== false) { if(($pos = strpos($tmp, '<?php')) !== false) {
$tmp = preg_replace('/<\?php/', '', $page['body'], 1); $tmp = preg_replace('/<\?php/', '', $query['body'], 1);
} }
else if(($pos = strpos($tmp, '<?')) !== false) { else if(($pos = strpos($tmp, '<?')) !== false) {
$tmp = preg_replace('/<\?/', '', $page['body'], 1); $tmp = preg_replace('/<\?/', '', $query['body'], 1);
} }
else else
$tmp = $page['body']; $tmp = $query['body'];
$php_errors = array();
function error_handler($errno, $errstr) {
global $php_errors;
$php_errors[] = array('errno' => $errno, 'errstr' => $errstr);
}
set_error_handler('error_handler');
global $config; global $config;
if(setting('core.backward_support')) { if($config['backward_support']) {
global $SQL, $main_content, $subtopic; global $SQL, $main_content, $subtopic;
} }
@@ -1317,12 +1262,17 @@ function getCustomPage($name, &$success): string
eval($tmp); eval($tmp);
$content .= ob_get_contents(); $content .= ob_get_contents();
ob_end_clean(); ob_end_clean();
restore_error_handler();
if(isset($php_errors[0]) && superAdmin()) {
var_dump($php_errors);
}
} }
else { else {
$oldLoader = $twig->getLoader(); $oldLoader = $twig->getLoader();
$twig_loader_array = new Twig_ArrayLoader(array( $twig_loader_array = new Twig_ArrayLoader(array(
'content.html' => $page['body'] 'content.html' => $query['body']
)); ));
$twig->setLoader($twig_loader_array); $twig->setLoader($twig_loader_array);
@@ -1437,42 +1387,39 @@ function getChangelogWhere($v)
return 'unknown'; return 'unknown';
} }
function getPlayerNameByAccount($id)
function getPlayerNameByAccountId($id)
{ {
if (!is_numeric($id)) { global $vowels, $ots, $db;
return ''; if(is_numeric($id))
} {
$player = new OTS_Player();
$player->load($id);
if($player->isLoaded())
return $player->getName();
else
{
$playerQuery = $db->query('SELECT `id` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;')->fetch();
$account = \MyAAC\Models\Account::find(intval($id), ['id']); $tmp = "*Error*";
if ($account) { /*
$player = \MyAAC\Models\Player::where('account_id', $account->id)->orderByDesc('lastlogin')->select('name')->first(); $acco = new OTS_Account();
if (!$player) { $acco->load($id);
return ''; if(!$acco->isLoaded())
return "Unknown name";
foreach($acco->getPlayersList() as $p)
{
$player= new OTS_Player();
$player->find($p);*/
$player->load($playerQuery['id']);
//echo 'id gracza = ' . $p . '<br/>';
if($player->isLoaded())
$tmp = $player->getName();
// break;
//}
return $tmp;
} }
return $player->name;
}
return '';
}
function getPlayerNameByAccount($account) {
if (is_numeric($account)) {
return getPlayerNameByAccountId($account);
}
return '';
}
function getPlayerNameById($id)
{
if (!is_numeric($id)) {
return '';
}
$player = \MyAAC\Models\Player::find((int)$id, ['name']);
if ($player) {
return $player->name;
} }
return ''; return '';
@@ -1480,13 +1427,13 @@ function getPlayerNameById($id)
function echo_success($message) function echo_success($message)
{ {
echo '<div class="col-12 alert alert-success mb-2">' . $message . '</div>'; echo '<div class="col-12 success mb-2">' . $message . '</div>';
} }
function echo_error($message) function echo_error($message)
{ {
global $error; global $error;
echo '<div class="col-12 alert alert-danger mb-2">' . $message . '</div>'; echo '<div class="col-12 error mb-2">' . $message . '</div>';
$error = true; $error = true;
} }
@@ -1560,19 +1507,18 @@ function right($str, $length) {
return substr($str, -$length); return substr($str, -$length);
} }
function getMonsterImgPath($monster): string function getCreatureImgPath($creature){
{ $creature_path = config('monsters_images_url');
$monster_path = setting('core.monsters_images_url'); $creature_gfx_name = trim(strtolower($creature)) . config('monsters_images_extension');
$monster_gfx_name = trim(strtolower($monster)) . setting('core.monsters_images_extension'); if (!file_exists($creature_path . $creature_gfx_name)) {
if (!file_exists($monster_path . $monster_gfx_name)) { $creature_gfx_name = str_replace(" ", "", $creature_gfx_name);
$monster_gfx_name = str_replace(" ", "", $monster_gfx_name); if (file_exists($creature_path . $creature_gfx_name)) {
if (file_exists($monster_path . $monster_gfx_name)) { return $creature_path . $creature_gfx_name;
return $monster_path . $monster_gfx_name;
} else { } else {
return $monster_path . 'nophoto.png'; return $creature_path . 'nophoto.png';
} }
} else { } else {
return $monster_path . $monster_gfx_name; return $creature_path . $creature_gfx_name;
} }
} }
@@ -1628,9 +1574,12 @@ function escapeHtml($html) {
function getGuildNameById($id) function getGuildNameById($id)
{ {
$guild = Guild::where('id', intval($id))->select('name')->first(); global $db;
if ($guild) {
return $guild->name; $guild = $db->query('SELECT `name` FROM `guilds` WHERE `id` = ' . (int)$id);
if($guild->rowCount() > 0) {
return $guild->fetchColumn();
} }
return false; return false;
@@ -1638,11 +1587,15 @@ function getGuildNameById($id)
function getGuildLogoById($id) function getGuildLogoById($id)
{ {
global $db;
$logo = 'default.gif'; $logo = 'default.gif';
$guild = Guild::where('id', intval($id))->select('logo_name')->first(); $query = $db->query('SELECT `logo_name` FROM `guilds` WHERE `id` = ' . (int)$id);
if ($guild) { if ($query->rowCount() == 1) {
$guildLogo = $guild->logo_name;
$query = $query->fetch(PDO::FETCH_ASSOC);
$guildLogo = $query['logo_name'];
if (!empty($guildLogo) && file_exists(GUILD_IMAGES_DIR . $guildLogo)) { if (!empty($guildLogo) && file_exists(GUILD_IMAGES_DIR . $guildLogo)) {
$logo = $guildLogo; $logo = $guildLogo;
@@ -1660,15 +1613,8 @@ function displayErrorBoxWithBackButton($errors, $action = null) {
]); ]);
} }
function makeLinksClickable($text, $blank = true) {
return preg_replace('!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9@:%_+.~#?&;//=]+)!i', '<a href="$1"' . (!$blank ?: ' target="_blank"') . '>$1</a>', $text);
}
function isRequestMethod(string $method): bool {
return strtolower($_SERVER['REQUEST_METHOD']) == strtolower($method);
}
// validator functions // validator functions
require_once LIBS . 'validator.php';
require_once SYSTEM . 'compat/base.php'; require_once SYSTEM . 'compat/base.php';
// custom functions // custom functions

View File

@@ -1,10 +1,15 @@
<?php <?php
/**
const SKILL_FRAGS = -1; * Events system
const SKILL_BALANCE = -2; *
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$i = 0; $i = 0;
define('HOOK_STARTUP', ++$i); define('HOOK_STARTUP', ++$i);
define('HOOK_BEFORE_PAGE', ++$i); define('HOOK_BEFORE_PAGE', ++$i);
define('HOOK_AFTER_PAGE', ++$i); define('HOOK_AFTER_PAGE', ++$i);
@@ -53,7 +58,6 @@ define('HOOK_ACCOUNT_LOGIN_AFTER_PASSWORD', ++$i);
define('HOOK_ACCOUNT_LOGIN_AFTER_REMEMBER_ME', ++$i); define('HOOK_ACCOUNT_LOGIN_AFTER_REMEMBER_ME', ++$i);
define('HOOK_ACCOUNT_LOGIN_AFTER_PAGE', ++$i); define('HOOK_ACCOUNT_LOGIN_AFTER_PAGE', ++$i);
define('HOOK_ACCOUNT_LOGIN_POST', ++$i); define('HOOK_ACCOUNT_LOGIN_POST', ++$i);
define('HOOK_ACCOUNT_CREATE_CHARACTER_AFTER', ++$i);
define('HOOK_ADMIN_HEAD_END', ++$i); define('HOOK_ADMIN_HEAD_END', ++$i);
define('HOOK_ADMIN_HEAD_START', ++$i); define('HOOK_ADMIN_HEAD_START', ++$i);
define('HOOK_ADMIN_BODY_START', ++$i); define('HOOK_ADMIN_BODY_START', ++$i);
@@ -64,44 +68,83 @@ define('HOOK_ADMIN_LOGIN_AFTER_ACCOUNT', ++$i);
define('HOOK_ADMIN_LOGIN_AFTER_PASSWORD', ++$i); define('HOOK_ADMIN_LOGIN_AFTER_PASSWORD', ++$i);
define('HOOK_ADMIN_LOGIN_AFTER_SIGN_IN', ++$i); define('HOOK_ADMIN_LOGIN_AFTER_SIGN_IN', ++$i);
define('HOOK_ADMIN_ACCOUNTS_SAVE_POST', ++$i); define('HOOK_ADMIN_ACCOUNTS_SAVE_POST', ++$i);
define('HOOK_ADMIN_SETTINGS_BEFORE_SAVE', ++$i);
define('HOOK_CRONJOB', ++$i);
define('HOOK_EMAIL_CONFIRMED', ++$i); define('HOOK_EMAIL_CONFIRMED', ++$i);
define('HOOK_GUILDS_BEFORE_GUILD_HEADER', ++$i); define('HOOK_GUILDS_BEFORE_GUILD_HEADER', ++$i);
define('HOOK_GUILDS_AFTER_GUILD_HEADER', ++$i); define('HOOK_GUILDS_AFTER_GUILD_HEADER', ++$i);
define('HOOK_GUILDS_AFTER_GUILD_INFORMATION', ++$i); define('HOOK_GUILDS_AFTER_GUILD_INFORMATION', ++$i);
define('HOOK_GUILDS_AFTER_GUILD_MEMBERS', ++$i); define('HOOK_GUILDS_AFTER_GUILD_MEMBERS', ++$i);
define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i); define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i);
define('HOOK_TWIG', ++$i);
define('HOOK_CACHE_CLEAR', ++$i);
const HOOK_FIRST = HOOK_STARTUP; const HOOK_FIRST = HOOK_STARTUP;
define('HOOK_LAST', $i); define('HOOK_LAST', $i);
function is_sub_dir($path = NULL, $parent_folder = BASE): bool|string require_once LIBS . 'plugins.php';
class Hook
{ {
//Get directory path minus last folder private $_name, $_type, $_file;
$dir = dirname($path);
$folder = substr($path, strlen($dir));
//Check the base dir is valid public function __construct($name, $type, $file) {
$dir = realpath($dir); $this->_name = $name;
$this->_type = $type;
//Only allow valid filename characters $this->_file = $file;
$folder = preg_replace('/[^a-z0-9\.\-_]/i', '', $folder);
//If this is a bad path or a bad end folder name
if( !$dir OR !$folder OR $folder === '.') {
return false;
} }
//Rebuild path public function execute($params)
$path = $dir. '/' . $folder; {
extract($params);
/*if(is_callable($this->_callback))
{
$tmp = $this->_callback;
$ret = $tmp($params);
}*/
//If this path is higher than the parent folder global $db, $config, $template_path, $ots, $content, $twig;
if( strcasecmp($path, $parent_folder) > 0 ) { $ret = include BASE . $this->_file;
return $path;
return !isset($ret) || $ret == 1 || $ret;
} }
return false; public function name() {return $this->_name;}
public function type() {return $this->_type;}
}
class Hooks
{
private static $_hooks = array();
public function register($hook, $type = '', $file = null) {
if(!($hook instanceof Hook))
$hook = new Hook($hook, $type, $file);
self::$_hooks[$hook->type()][] = $hook;
}
public function trigger($type, $params = array())
{
$ret = true;
if(isset(self::$_hooks[$type]))
{
foreach(self::$_hooks[$type] as $name => $hook) {
/** @var $hook Hook */
if (!$hook->execute($params)) {
$ret = false;
}
}
}
return $ret;
}
public function exist($type) {
return isset(self::$_hooks[$type]);
}
public function load()
{
foreach(Plugins::getHooks() as $hook) {
$this->register($hook['name'], $hook['type'], $hook['file']);
}
Plugins::clearWarnings();
}
} }

View File

@@ -7,14 +7,6 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use DebugBar\StandardDebugBar;
use MyAAC\Cache\Cache;
use MyAAC\CsrfToken;
use MyAAC\Hooks;
use MyAAC\Settings;
use MyAAC\Towns;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
if(!isset($config['installed']) || !$config['installed']) { if(!isset($config['installed']) || !$config['installed']) {
@@ -25,10 +17,6 @@ if(config('env') === 'dev') {
require SYSTEM . 'exception.php'; require SYSTEM . 'exception.php';
} }
if (config('env') === 'dev' || getBoolean(config('enable_debugbar'))) {
$debugBar = new StandardDebugBar();
}
if(empty($config['server_path'])) { if(empty($config['server_path'])) {
throw new RuntimeException('Server Path has been not set. Go to config.php and set it.'); throw new RuntimeException('Server Path has been not set. Go to config.php and set it.');
} }
@@ -42,12 +30,9 @@ if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HT
ob_start('ob_gzhandler'); ob_start('ob_gzhandler');
// cache // cache
require_once SYSTEM . 'libs/cache.php';
$cache = Cache::getInstance(); $cache = Cache::getInstance();
// event system
$hooks = new Hooks();
$hooks->load();
// twig // twig
require_once SYSTEM . 'twig.php'; require_once SYSTEM . 'twig.php';
@@ -55,24 +40,28 @@ require_once SYSTEM . 'twig.php';
$action = $_REQUEST['action'] ?? ''; $action = $_REQUEST['action'] ?? '';
define('ACTION', $action); define('ACTION', $action);
// errors, is also often used
$errors = [];
// trim values we receive // trim values we receive
foreach($_POST as $var => $value) { if(isset($_POST))
if(is_string($value)) { {
$_POST[$var] = trim($value); foreach($_POST as $var => $value) {
if(is_string($value)) {
$_POST[$var] = trim($value);
}
} }
} }
if(isset($_GET))
foreach($_GET as $var => $value) { {
if(is_string($value)) foreach($_GET as $var => $value) {
$_GET[$var] = trim($value); if(is_string($value))
$_GET[$var] = trim($value);
}
} }
if(isset($_REQUEST))
foreach($_REQUEST as $var => $value) { {
if(is_string($value)) foreach($_REQUEST as $var => $value) {
$_REQUEST[$var] = trim($value); if(is_string($value))
$_REQUEST[$var] = trim($value);
}
} }
// load otserv config file // load otserv config file
@@ -131,42 +120,22 @@ unset($foundValue);
// POT // POT
require_once SYSTEM . 'libs/pot/OTS.php'; require_once SYSTEM . 'libs/pot/OTS.php';
$ots = POT::getInstance(); $ots = POT::getInstance();
$eloquentConnection = null;
require_once SYSTEM . 'database.php'; require_once SYSTEM . 'database.php';
if ($config_lua_reload) {
clearCache();
}
// verify myaac tables exists in database
if(!defined('MYAAC_INSTALL') && !$db->hasTable('myaac_account_actions')) {
throw new RuntimeException('Seems that the table myaac_account_actions of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting ' . BASE_URL . 'install');
}
// execute migrations // execute migrations
require SYSTEM . 'migrate.php'; require SYSTEM . 'migrate.php';
// settings // settings
require_once LIBS . 'Settings.php';
$settings = Settings::getInstance(); $settings = Settings::getInstance();
$settings->load(); $settings->load();
// csrf protection
$token = getSession('csrf_token');
if (!isset($token) || !$token) {
CsrfToken::generate();
}
// deprecated config values // deprecated config values
require_once SYSTEM . 'compat/config.php'; require_once SYSTEM . 'compat/config.php';
date_default_timezone_set(setting('core.date_timezone')); date_default_timezone_set(setting('core.date_timezone'));
setting( $config['account_create_character_create'] = config('account_create_character_create') && (!setting('core.mail_enabled') || !config('account_mail_verify'));
[
'core.account_create_character_create',
setting('core.account_create_character_create') && (!setting('core.mail_enabled') || !setting('core.account_mail_verify'))
]
);
$settingsItemImagesURL = setting('core.item_images_url'); $settingsItemImagesURL = setting('core.item_images_url');
if($settingsItemImagesURL[strlen($settingsItemImagesURL) - 1] !== '/') { if($settingsItemImagesURL[strlen($settingsItemImagesURL) - 1] !== '/') {
@@ -177,4 +146,5 @@ define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name'));
define('USE_ACCOUNT_NUMBER', $db->hasColumn('accounts', 'number')); define('USE_ACCOUNT_NUMBER', $db->hasColumn('accounts', 'number'));
define('USE_ACCOUNT_SALT', $db->hasColumn('accounts', 'salt')); define('USE_ACCOUNT_SALT', $db->hasColumn('accounts', 'salt'));
require LIBS . 'Towns.php';
Towns::load(); Towns::load();

60
system/item.php Normal file
View File

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

View File

@@ -1,9 +1,4 @@
<?php <?php
namespace MyAAC;
use MyAAC\Models\Player;
/** /**
* CreateCharacter * CreateCharacter
* *
@@ -52,12 +47,14 @@ class CreateCharacter
return false; return false;
} }
if(!admin() && !\Validator::newCharacterName($name)) { if(!admin() && !Validator::newCharacterName($name)) {
$errors['name'] = \Validator::getLastError(); $errors['name'] = Validator::getLastError();
return false; return false;
} }
if(Player::where('name', '=', $name)->exists()) { $player = new OTS_Player();
$player->find($name);
if($player->isLoaded()) {
$errors['name'] = 'Character with this name already exist.'; $errors['name'] = 'Character with this name already exist.';
return false; return false;
} }
@@ -73,7 +70,7 @@ class CreateCharacter
* @param array $errors * @param array $errors
* @return bool * @return bool
*/ */
public function check($name, $sex, ?int &$vocation, ?int &$town, &$errors) public function check($name, $sex, &$vocation, &$town, &$errors)
{ {
$this->checkName($name, $errors); $this->checkName($name, $errors);
@@ -125,13 +122,13 @@ class CreateCharacter
* @param int $sex * @param int $sex
* @param int $vocation * @param int $vocation
* @param int $town * @param int $town
* @param \OTS_Account $account * @param OTS_Account $account
* @param array $errors * @param array $errors
* @return bool * @return bool
* @throws \E_OTS_NotLoaded * @throws E_OTS_NotLoaded
* @throws \Twig_Error_Loader * @throws Twig_Error_Loader
* @throws \Twig_Error_Runtime * @throws Twig_Error_Runtime
* @throws \Twig_Error_Syntax * @throws Twig_Error_Syntax
*/ */
public function doCreate($name, $sex, $vocation, $town, $account, &$errors) public function doCreate($name, $sex, $vocation, $town, $account, &$errors)
{ {
@@ -142,14 +139,14 @@ class CreateCharacter
if(empty($errors)) if(empty($errors))
{ {
$number_of_players_on_account = $account->getPlayersList(true)->count(); $number_of_players_on_account = $account->getPlayersList(true)->count();
if($number_of_players_on_account >= setting('core.characters_per_account')) 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 . '/' . setting('core.characters_per_account') . ')</b>!'; $errors[] = 'You have too many characters on your account <b>('.$number_of_players_on_account.'/'.config('characters_per_account').')</b>!';
} }
if(empty($errors)) if(empty($errors))
{ {
$char_to_copy_name = config('character_samples')[$vocation]; $char_to_copy_name = config('character_samples')[$vocation];
$char_to_copy = new \OTS_Player(); $char_to_copy = new OTS_Player();
$char_to_copy->find($char_to_copy_name); $char_to_copy->find($char_to_copy_name);
if(!$char_to_copy->isLoaded()) if(!$char_to_copy->isLoaded())
$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.'; $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.';
@@ -164,7 +161,7 @@ class CreateCharacter
if($sex == "0") if($sex == "0")
$char_to_copy->setLookType(136); $char_to_copy->setLookType(136);
$player = new \OTS_Player(); $player = new OTS_Player();
$player->setName($name); $player->setName($name);
$player->setAccount($account); $player->setAccount($account);
$player->setGroupId(1); $player->setGroupId(1);
@@ -196,7 +193,7 @@ class CreateCharacter
$player->setManaSpent($char_to_copy->getManaSpent()); $player->setManaSpent($char_to_copy->getManaSpent());
$player->setSoul($char_to_copy->getSoul()); $player->setSoul($char_to_copy->getSoul());
for($skill = \POT::SKILL_FIRST; $skill <= \POT::SKILL_LAST; $skill++) { for($skill = POT::SKILL_FIRST; $skill <= POT::SKILL_LAST; $skill++) {
$value = 10; $value = 10;
if (setting('core.use_character_sample_skills')) { if (setting('core.use_character_sample_skills')) {
$value = $char_to_copy->getSkill($skill); $value = $char_to_copy->getSkill($skill);
@@ -233,7 +230,7 @@ class CreateCharacter
$player->save(); $player->save();
$player->setCustomField('created', time()); $player->setCustomField('created', time());
$player = new \OTS_Player(); $player = new OTS_Player();
$player->find($name); $player->find($name);
if(!$player->isLoaded()) { if(!$player->isLoaded()) {
@@ -242,7 +239,7 @@ class CreateCharacter
} }
if($db->hasTable('player_skills')) { if($db->hasTable('player_skills')) {
for($skill = \POT::SKILL_FIRST; $skill <= \POT::SKILL_LAST; $skill++) { for($skill = POT::SKILL_FIRST; $skill <= POT::SKILL_LAST; $skill++) {
$value = 10; $value = 10;
if (setting('core.use_character_sample_skills')) { if (setting('core.use_character_sample_skills')) {
$value = $char_to_copy->getSkill($skill); $value = $char_to_copy->getSkill($skill);
@@ -262,20 +259,6 @@ class CreateCharacter
} }
} }
global $hooks;
if (!$hooks->trigger(HOOK_ACCOUNT_CREATE_CHARACTER_AFTER,
[
'account' => $account,
'player' => $player,
'name' => $name,
'sex' => $sex,
'vocation' => $vocation,
'town' => $town,
]
)) {
return false;
}
global $twig; global $twig;
$twig->display('success.html.twig', array( $twig->display('success.html.twig', array(
'title' => 'Character Created', 'title' => 'Character Created',

View File

@@ -23,8 +23,9 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
namespace MyAAC; /**
* Class DataLoader
*/
class DataLoader class DataLoader
{ {
private static $locale; private static $locale;
@@ -37,6 +38,7 @@ class DataLoader
{ {
self::$startTime = microtime(true); self::$startTime = microtime(true);
require LIBS . 'items.php';
if(Items::loadFromXML()) { if(Items::loadFromXML()) {
success(self::$locale['step_database_loaded_items'] . self::getLoadedTime()); success(self::$locale['step_database_loaded_items'] . self::getLoadedTime());
} }
@@ -46,20 +48,22 @@ class DataLoader
self::$startTime = microtime(true); self::$startTime = microtime(true);
if(Monsters::loadFromXML()) { require LIBS . 'creatures.php';
if(Creatures::loadFromXML()) {
success(self::$locale['step_database_loaded_monsters'] . self::getLoadedTime()); success(self::$locale['step_database_loaded_monsters'] . self::getLoadedTime());
if(Monsters::getMonstersList()->hasErrors()) { if(Creatures::getMonstersList()->hasErrors()) {
self::$locale['step_database_error_monsters'] = str_replace('$LOG$', 'system/logs/error.log', self::$locale['step_database_error_monsters']); self::$locale['step_database_error_monsters'] = str_replace('$LOG$', 'system/logs/error.log', self::$locale['step_database_error_monsters']);
warning(self::$locale['step_database_error_monsters']); warning(self::$locale['step_database_error_monsters']);
} }
} }
else { else {
error(Monsters::getLastError()); error(Creatures::getLastError());
} }
self::$startTime = microtime(true); self::$startTime = microtime(true);
require_once LIBS . 'npc.php';
if(NPCs::loadFromXML()) { if(NPCs::loadFromXML()) {
success(self::$locale['step_database_loaded_npcs'] . self::getLoadedTime()); success(self::$locale['step_database_loaded_npcs'] . self::getLoadedTime());
} }
@@ -69,6 +73,7 @@ class DataLoader
self::$startTime = microtime(true); self::$startTime = microtime(true);
require LIBS . 'spells.php';
if(Spells::loadFromXML()) { if(Spells::loadFromXML()) {
success(self::$locale['step_database_loaded_spells'] . self::getLoadedTime()); success(self::$locale['step_database_loaded_spells'] . self::getLoadedTime());
} }
@@ -87,6 +92,7 @@ class DataLoader
self::$startTime = microtime(true); self::$startTime = microtime(true);
require LIBS . 'weapons.php';
if(Weapons::loadFromXML()) { if(Weapons::loadFromXML()) {
success(self::$locale['step_database_loaded_weapons'] . self::getLoadedTime()); success(self::$locale['step_database_loaded_weapons'] . self::getLoadedTime());
} }

View File

@@ -0,0 +1,3 @@
<?php
class SensitiveException extends Exception {}

View File

@@ -1,11 +1,14 @@
<?php <?php
/**
* CreateCharacter
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
namespace MyAAC; class Settings implements ArrayAccess
use MyAAC\Cache\Cache;
use MyAAC\Models\Settings as ModelsSettings;
class Settings implements \ArrayAccess
{ {
static private $instance; static private $instance;
private $settingsFile = []; private $settingsFile = [];
@@ -37,9 +40,13 @@ class Settings implements \ArrayAccess
} }
} }
$settings = ModelsSettings::all(); global $db;
foreach ($settings as $setting) { $settings = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'settings`');
$this->settingsDatabase[$setting->name][$setting->key] = $setting->value;
if($settings->rowCount() > 0) {
foreach ($settings->fetchAll(PDO::FETCH_ASSOC) as $setting) {
$this->settingsDatabase[$setting['name']][$setting['key']] = $setting['value'];
}
} }
if ($cache->enabled()) { if ($cache->enabled()) {
@@ -47,25 +54,14 @@ class Settings implements \ArrayAccess
} }
} }
public function save($pluginName, $values) public function save($pluginName, $values) {
{ global $db;
$this->loadPlugin($pluginName);
if (!isset($this->settingsFile[$pluginName])) { if (!isset($this->settingsFile[$pluginName])) {
throw new \RuntimeException("Error on save settings: plugin $pluginName does not exist"); throw new RuntimeException('Error on save settings: plugin does not exist');
} }
$settings = $this->settingsFile[$pluginName]; $settings = $this->settingsFile[$pluginName];
global $hooks;
if (!$hooks->trigger(HOOK_ADMIN_SETTINGS_BEFORE_SAVE, [
'name' => $pluginName,
'values' => $values,
'settings' => $settings,
])) {
return false;
}
if (isset($settings['callbacks']['beforeSave'])) { if (isset($settings['callbacks']['beforeSave'])) {
if (!$settings['callbacks']['beforeSave']($settings, $values)) { if (!$settings['callbacks']['beforeSave']($settings, $values)) {
return false; return false;
@@ -73,7 +69,7 @@ class Settings implements \ArrayAccess
} }
$this->errors = []; $this->errors = [];
ModelsSettings::where('name', $pluginName)->delete(); $db->query('DELETE FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($pluginName) . ';');
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$errorMessage = ''; $errorMessage = '';
if (isset($settings['settings'][$key]['callbacks']['beforeSave']) && !$settings['settings'][$key]['callbacks']['beforeSave']($key, $value, $errorMessage)) { if (isset($settings['settings'][$key]['callbacks']['beforeSave']) && !$settings['settings'][$key]['callbacks']['beforeSave']($key, $value, $errorMessage)) {
@@ -82,48 +78,52 @@ class Settings implements \ArrayAccess
} }
try { try {
ModelsSettings::create([ $db->insert(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key, 'value' => $value]);
'name' => $pluginName, } catch (PDOException $error) {
'key' => $key,
'value' => $value
]);
} catch (\PDOException $error) {
$this->errors[] = 'Error while saving setting (' . $pluginName . ' - ' . $key . '): ' . $error->getMessage(); $this->errors[] = 'Error while saving setting (' . $pluginName . ' - ' . $key . '): ' . $error->getMessage();
} }
} }
$this->clearCache(); $cache = Cache::getInstance();
if ($cache->enabled()) {
$cache->delete('settings');
}
return true; return true;
} }
public function updateInDatabase($pluginName, $key, $value) public function updateInDatabase($pluginName, $key, $value)
{ {
if (ModelsSettings::where(['name' => $pluginName, 'key' => $key])->exists()) { global $db;
ModelsSettings::where(['name' => $pluginName, 'key' => $key])->update(['value' => $value]); $db->update(TABLE_PREFIX . 'settings', ['value' => $value], ['name' => $pluginName, 'key' => $key]);
}
else {
// insert new
ModelsSettings::create(['name' => $pluginName, 'key' => $key, 'value' => $value]);
}
$this->clearCache();
} }
public function deleteFromDatabase($pluginName, $key = null) public function deleteFromDatabase($pluginName, $key = null)
{ {
global $db;
if (!isset($key)) { if (!isset($key)) {
ModelsSettings::where('name', $pluginName)->delete(); $db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName], -1);
} }
else { else {
ModelsSettings::where('name', $pluginName)->where('key', $key)->delete(); $db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key]);
} }
$this->clearCache();
} }
public static function display($plugin, $settings): array public static function display($plugin, $settings): array
{ {
$settingsDb = ModelsSettings::where('name', $plugin)->pluck('value', 'key')->toArray(); 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 = []; $config = [];
require BASE . 'config.local.php'; require BASE . 'config.local.php';
@@ -131,9 +131,6 @@ class Settings implements \ArrayAccess
if (is_bool($value)) { if (is_bool($value)) {
$settingsDb[$key] = $value ? 'true' : 'false'; $settingsDb[$key] = $value ? 'true' : 'false';
} }
elseif (is_array($value)) {
$settingsDb[$key] = $value;
}
else { else {
$settingsDb[$key] = (string)$value; $settingsDb[$key] = (string)$value;
} }
@@ -251,10 +248,6 @@ class Settings implements \ArrayAccess
} }
else if($setting['type'] === 'textarea') { else if($setting['type'] === 'textarea') {
if (isset($settingsDb[$key]) && is_array($settingsDb[$key])) {
$settingsDb[$key] = implode(',', $settingsDb[$key]);
}
$value = ($settingsDb[$key] ?? ($setting['default'] ?? '')); $value = ($settingsDb[$key] ?? ($setting['default'] ?? ''));
$valueWithSpaces = array_map('trim', preg_split('/\r\n|\r|\n/', trim($value))); $valueWithSpaces = array_map('trim', preg_split('/\r\n|\r|\n/', trim($value)));
$rows = count($valueWithSpaces); $rows = count($valueWithSpaces);
@@ -289,7 +282,7 @@ class Settings implements \ArrayAccess
} }
else if ($setting['options'] == '$timezones') { else if ($setting['options'] == '$timezones') {
$timezones = []; $timezones = [];
foreach (\DateTimeZone::listIdentifiers() as $value) { foreach (DateTimeZone::listIdentifiers() as $value) {
$timezones[$value] = $value; $timezones[$value] = $value;
} }
@@ -328,7 +321,7 @@ class Settings implements \ArrayAccess
</td> </td>
<td> <td>
<div class="well setting-default"><?php <div class="well setting-default"><?php
echo (isset($setting['desc']) ? makeLinksClickable($setting['desc']) : ''); echo ($setting['desc'] ?? '');
echo '<br/>'; echo '<br/>';
echo '<strong>Default:</strong> '; echo '<strong>Default:</strong> ';
@@ -339,7 +332,7 @@ class Settings implements \ArrayAccess
echo $setting['default']; echo $setting['default'];
} }
else if ($setting['type'] === 'options') { else if ($setting['type'] === 'options') {
if (is_int($setting['default']) || !empty($setting['default'])) { if (!empty($setting['default'])) {
echo $setting['options'][$setting['default']]; echo $setting['options'][$setting['default']];
} }
} }
@@ -382,6 +375,7 @@ class Settings implements \ArrayAccess
} }
$this->settingsDatabase[$pluginKeyName][$key] = $value; $this->settingsDatabase[$pluginKeyName][$key] = $value;
$this->updateInDatabase($pluginKeyName, $key, $value);
} }
#[\ReturnTypeWillChange] #[\ReturnTypeWillChange]
@@ -422,6 +416,7 @@ class Settings implements \ArrayAccess
unset($this->settingsFile[$pluginKeyName]['settings'][$key]); unset($this->settingsFile[$pluginKeyName]['settings'][$key]);
unset($this->settingsDatabase[$pluginKeyName][$key]); unset($this->settingsDatabase[$pluginKeyName][$key]);
$this->deleteFromDatabase($pluginKeyName, $key);
} }
/** /**
@@ -448,7 +443,7 @@ class Settings implements \ArrayAccess
// return specified plugin settings (all) // return specified plugin settings (all)
if(!isset($key)) { if(!isset($key)) {
if (!isset($this->settingsFile[$pluginKeyName]['settings'])) { if (!isset($this->settingsFile[$pluginKeyName]['settings'])) {
throw new \RuntimeException('Unknown plugin settings: ' . $pluginKeyName); throw new RuntimeException('Unknown plugin settings: ' . $pluginKeyName);
} }
return $this->settingsFile[$pluginKeyName]['settings']; return $this->settingsFile[$pluginKeyName]['settings'];
} }
@@ -464,15 +459,9 @@ class Settings implements \ArrayAccess
$ret['value'] = $value; $ret['value'] = $value;
} }
else { else {
if (!isset($this->settingsFile[$pluginKeyName]['settings'][$key])) {
return null;
}
$ret['value'] = $this->settingsFile[$pluginKeyName]['settings'][$key]['default']; $ret['value'] = $this->settingsFile[$pluginKeyName]['settings'][$key]['default'];
} }
$ret['key'] = $key;
if(isset($ret['type'])) { if(isset($ret['type'])) {
switch($ret['type']) { switch($ret['type']) {
case 'boolean': case 'boolean':
@@ -545,11 +534,8 @@ class Settings implements \ArrayAccess
public static function saveConfig($config, $filename, &$content = '') public static function saveConfig($config, $filename, &$content = '')
{ {
$content = "<?php" . PHP_EOL; $content = "<?php" . PHP_EOL .
"\$config['installed'] = true;" . PHP_EOL;
unset($config['installed']);
$content .= "\$config['installed'] = true;" . PHP_EOL;
foreach ($config as $key => $value) { foreach ($config as $key => $value) {
$content .= "\$config['$key'] = "; $content .= "\$config['$key'] = ";
@@ -557,10 +543,10 @@ class Settings implements \ArrayAccess
$content .= ';' . PHP_EOL; $content .= ';' . PHP_EOL;
} }
$success = @file_put_contents($filename, $content); $success = file_put_contents($filename, $content);
// we saved new config.php, need to revalidate cache (only if opcache is enabled) // we saved new config.php, need to revalidate cache (only if opcache is enabled)
if ($success && function_exists('opcache_invalidate')) { if (function_exists('opcache_invalidate')) {
opcache_invalidate($filename); opcache_invalidate($filename);
} }
@@ -594,10 +580,10 @@ class Settings implements \ArrayAccess
} }
try { try {
$connectionTest = new \PDO('mysql:' . implode(';', $dns), $user, $password); $connectionTest = new PDO('mysql:' . implode(';', $dns), $user, $password);
$connectionTest->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $connectionTest->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} }
catch(\PDOException $error) { catch(PDOException $error) {
error('MySQL connection failed. Settings has been reverted.'); error('MySQL connection failed. Settings has been reverted.');
error($error->getMessage()); error($error->getMessage());
return false; return false;
@@ -606,15 +592,7 @@ class Settings implements \ArrayAccess
return true; return true;
} }
public function getErrors(): array { public function getErrors() {
return $this->errors; return $this->errors;
} }
public function clearCache(): void
{
$cache = Cache::getInstance();
if ($cache->enabled()) {
$cache->delete('settings');
}
}
} }

View File

@@ -23,16 +23,15 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
namespace MyAAC; /**
* Class Towns
use MyAAC\Models\Town; */
class Towns class Towns
{ {
/** /**
* @var string * @var string
*/ */
private static $filename = CACHE . 'persistent/' . 'towns.php'; private static $filename = CACHE . 'towns.php';
/** /**
* Determine towns * Determine towns
@@ -108,6 +107,7 @@ class Towns
if (file_exists($mapFile)) { if (file_exists($mapFile)) {
ini_set('memory_limit', '-1'); ini_set('memory_limit', '-1');
require LIBS . 'TownsReader.php';
$townsReader = new TownsReader($mapFile); $townsReader = new TownsReader($mapFile);
$townsReader->load(); $townsReader->load();
@@ -124,6 +124,15 @@ class Towns
*/ */
public static function getFromDatabase() public static function getFromDatabase()
{ {
return Town::pluck('name', 'id')->toArray(); global $db;
$query = $db->query('SELECT `id`, `name` FROM `towns`;')->fetchAll(PDO::FETCH_ASSOC);
$towns = [];
foreach($query as $town) {
$towns[$town['id']] = $town['name'];
}
return $towns;
} }
} }

View File

@@ -19,10 +19,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
namespace MyAAC;
/* /*
This code bases on original OTServ code for .otbm files - file iomapotbm.cpp rev.2141 This code bases on oryginal OTServ code for .otbm files - file iomapotbm.cpp rev.2141
*/ */
class TownsReader class TownsReader
{ {

View File

@@ -8,8 +8,7 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC\Cache;
/** /**
* Class Cache * Class Cache
@@ -42,30 +41,40 @@ class Cache
*/ */
public static function generateInstance($engine = '', $prefix = '') public static function generateInstance($engine = '', $prefix = '')
{ {
if (config('env') === 'dev') { if(config('env') === 'dev') {
self::$instance = new self(); self::$instance = new self();
return self::$instance; return self::$instance;
} }
switch (strtolower($engine)) { switch(strtolower($engine)) {
case 'apc': case 'apc':
self::$instance = new APC($prefix); require 'cache_apc.php';
self::$instance = new Cache_APC($prefix);
break; break;
case 'apcu': case 'apcu':
self::$instance = new APCu($prefix); require 'cache_apcu.php';
self::$instance = new Cache_APCu($prefix);
break;
case 'eaccelerator':
require 'cache_eaccelerator.php';
self::$instance = new Cache_eAccelerator($prefix);
break; break;
case 'xcache': case 'xcache':
self::$instance = new XCache($prefix); require 'cache_xcache.php';
self::$instance = new Cache_XCache($prefix);
break; break;
case 'file': case 'file':
self::$instance = new File($prefix, CACHE); require 'cache_file.php';
self::$instance = new Cache_File($prefix, CACHE);
break; break;
case 'php': case 'php':
self::$instance = new PHP($prefix, CACHE); require 'cache_php.php';
self::$instance = new Cache_PHP($prefix, CACHE);
break; break;
case 'auto': case 'auto':
@@ -85,11 +94,13 @@ class Cache
*/ */
public static function detect() public static function detect()
{ {
if (function_exists('apc_fetch')) if(function_exists('apc_fetch'))
return 'apc'; return 'apc';
else if (function_exists('apcu_fetch')) else if(function_exists('apcu_fetch'))
return 'apcu'; return 'apcu';
else if (function_exists('xcache_get') && ini_get('xcache.var_size')) else if(function_exists('eaccelerator_get'))
return 'eaccelerator';
else if(function_exists('xcache_get') && ini_get('xcache.var_size'))
return 'xcache'; return 'xcache';
return 'file'; return 'file';
@@ -98,15 +109,12 @@ class Cache
/** /**
* @return bool * @return bool
*/ */
public function enabled() public function enabled() {return false;}
{
return false;
}
public static function remember($key, $ttl, $callback) public static function remember($key, $ttl, $callback)
{ {
$cache = self::getInstance(); $cache = self::getInstance();
if (!$cache->enabled()) { if(!$cache->enabled()) {
return $callback(); return $callback();
} }
@@ -116,7 +124,7 @@ class Cache
} }
$value = $callback(); $value = $callback();
$cache->set($key, serialize($value), $ttl); $cache->set($key, serialize($value),$ttl);
return $value; return $value;
} }
} }

View File

@@ -8,10 +8,9 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC\Cache; class Cache_APC
class APC
{ {
private $prefix; private $prefix;
private $enabled; private $enabled;
@@ -32,25 +31,22 @@ class APC
public function get($key) public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($this->prefix . $key, $tmp)) { if($this->fetch($this->prefix . $key, $tmp)) {
return $tmp; return $tmp;
} }
return ''; return '';
} }
public function fetch($key, &$var) public function fetch($key, &$var) {
{
return ($var = apc_fetch($this->prefix . $key)) !== false; return ($var = apc_fetch($this->prefix . $key)) !== false;
} }
public function delete($key) public function delete($key) {
{
apc_delete($this->prefix . $key); apc_delete($this->prefix . $key);
} }
public function enabled() public function enabled() {
{
return $this->enabled; return $this->enabled;
} }
} }

View File

@@ -8,10 +8,9 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC\Cache; class Cache_APCu
class APCu
{ {
private $prefix; private $prefix;
private $enabled; private $enabled;
@@ -32,25 +31,22 @@ class APCu
public function get($key) public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($this->prefix . $key, $tmp)) { if($this->fetch($this->prefix . $key, $tmp)) {
return $tmp; return $tmp;
} }
return ''; return '';
} }
public function fetch($key, &$var) public function fetch($key, &$var) {
{
return ($var = apcu_fetch($this->prefix . $key)) !== false; return ($var = apcu_fetch($this->prefix . $key)) !== false;
} }
public function delete($key) public function delete($key) {
{
apcu_delete($this->prefix . $key); apcu_delete($this->prefix . $key);
} }
public function enabled() public function enabled() {
{
return $this->enabled; return $this->enabled;
} }
} }

View File

@@ -0,0 +1,51 @@
<?php
/**
* Cache eAccelerator class
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @author Mark Samman (Talaturen) <marksamman@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
class Cache_eAccelerator
{
private $prefix;
private $enabled;
public function __construct($prefix = '') {
$this->prefix = $prefix;
$this->enabled = function_exists('eaccelerator_get');
}
public function set($key, $var, $ttl = 0)
{
$key = $this->prefix . $key;
eaccelerator_rm($key);
eaccelerator_put($key, $var, $ttl);
}
public function get($key)
{
$tmp = '';
if($this->fetch($this->prefix . $key, $tmp)) {
return $tmp;
}
return '';
}
public function fetch($key, &$var) {
return ($var = eaccelerator_get($this->prefix . $key)) !== null;
}
public function delete($key) {
eaccelerator_rm($this->prefix . $key);
}
public function enabled() {
return $this->enabled;
}
}

View File

@@ -7,17 +7,15 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC\Cache; class Cache_File
class File
{ {
private $prefix; private $prefix;
private $dir; private $dir;
private $enabled; private $enabled;
public function __construct($prefix = '', $dir = '') public function __construct($prefix = '', $dir = '') {
{
$this->prefix = $prefix; $this->prefix = $prefix;
$this->dir = $dir; $this->dir = $dir;
$this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir)); $this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir));
@@ -38,7 +36,7 @@ class File
public function get($key) public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($key, $tmp)) { if($this->fetch($key, $tmp)) {
return $tmp; return $tmp;
} }
@@ -48,7 +46,7 @@ class File
public function fetch($key, &$var) public function fetch($key, &$var)
{ {
$file = $this->_name($key); $file = $this->_name($key);
if (!file_exists($file) || filemtime($file) < time()) { if(!file_exists($file) || filemtime($file) < time()) {
return false; return false;
} }
@@ -59,18 +57,16 @@ class File
public function delete($key) public function delete($key)
{ {
$file = $this->_name($key); $file = $this->_name($key);
if (file_exists($file)) { if(file_exists($file)) {
unlink($file); unlink($file);
} }
} }
public function enabled() public function enabled() {
{
return $this->enabled; return $this->enabled;
} }
private function _name($key) private function _name($key) {
{
return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key)); return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key));
} }
} }

View File

@@ -7,17 +7,15 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC\Cache; class Cache_PHP
class PHP
{ {
private $prefix; private $prefix;
private $dir; private $dir;
private $enabled; private $enabled;
public function __construct($prefix = '', $dir = '') public function __construct($prefix = '', $dir = '') {
{
$this->prefix = $prefix; $this->prefix = $prefix;
$this->dir = $dir; $this->dir = $dir;
$this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir)); $this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir));
@@ -44,7 +42,7 @@ class PHP
public function get($key) public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($key, $tmp)) { if($this->fetch($key, $tmp)) {
return $tmp; return $tmp;
} }
@@ -54,7 +52,7 @@ class PHP
public function fetch($key, &$var) public function fetch($key, &$var)
{ {
$file = $this->_name($key); $file = $this->_name($key);
if (!file_exists($file) || filemtime($file) < time()) { if(!file_exists($file) || filemtime($file) < time()) {
return false; return false;
} }
@@ -66,18 +64,16 @@ class PHP
public function delete($key) public function delete($key)
{ {
$file = $this->_name($key); $file = $this->_name($key);
if (file_exists($file)) { if(file_exists($file)) {
unlink($file); unlink($file);
} }
} }
public function enabled() public function enabled() {
{
return $this->enabled; return $this->enabled;
} }
private function _name($key) private function _name($key) {
{
return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key) . '.php'); return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key) . '.php');
} }
} }

View File

@@ -8,16 +8,14 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC\Cache; class Cache_XCache
class XCache
{ {
private $prefix; private $prefix;
private $enabled; private $enabled;
public function __construct($prefix = '') public function __construct($prefix = '') {
{
$this->prefix = $prefix; $this->prefix = $prefix;
$this->enabled = function_exists('xcache_get') && ini_get('xcache.var_size'); $this->enabled = function_exists('xcache_get') && ini_get('xcache.var_size');
} }
@@ -32,7 +30,7 @@ class XCache
public function get($key) public function get($key)
{ {
$tmp = ''; $tmp = '';
if ($this->fetch($this->prefix . $key, $tmp)) { if($this->fetch($this->prefix . $key, $tmp)) {
return $tmp; return $tmp;
} }
@@ -42,7 +40,7 @@ class XCache
public function fetch($key, &$var) public function fetch($key, &$var)
{ {
$key = $this->prefix . $key; $key = $this->prefix . $key;
if (!xcache_isset($key)) { if(!xcache_isset($key)) {
return false; return false;
} }
@@ -50,13 +48,11 @@ class XCache
return true; return true;
} }
public function delete($key) public function delete($key) {
{
xcache_unset($this->prefix . $key); xcache_unset($this->prefix . $key);
} }
public function enabled() public function enabled() {
{
return $this->enabled; return $this->enabled;
} }
} }

View File

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

View File

@@ -8,22 +8,20 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC; require_once LIBS . 'items.php';
class Creatures {
use MyAAC\Models\Monster;
class Monsters {
/** /**
* @var \OTS_MonstersList * @var OTS_MonstersList
*/ */
private static $monstersList; private static $monstersList;
private static $lastError = ''; private static $lastError = '';
public static function loadFromXML($show = false) { public static function loadFromXML($show = false) {
try { global $db;
Monster::query()->delete();
} catch(\Exception $error) {} try { $db->exec('DELETE FROM `' . TABLE_PREFIX . 'monsters`;'); } catch(PDOException $error) {}
if($show) { if($show) {
echo '<h2>Reload monsters.</h2>'; echo '<h2>Reload monsters.</h2>';
@@ -31,9 +29,9 @@ class Monsters {
} }
try { try {
self::$monstersList = new \OTS_MonstersList(config('data_path') . 'monster/'); self::$monstersList = new OTS_MonstersList(config('data_path') . 'monster/');
} }
catch(\Exception $e) { catch(Exception $e) {
self::$lastError = $e->getMessage(); self::$lastError = $e->getMessage();
return false; return false;
} }
@@ -118,7 +116,7 @@ class Monsters {
$summons = $monster->getSummons(); $summons = $monster->getSummons();
$loot = $monster->getLoot(); $loot = $monster->getLoot();
foreach($loot as &$item) { foreach($loot as &$item) {
if(!\Validator::number($item['id'])) { if(!Validator::number($item['id'])) {
if(isset($items[$item['id']])) { if(isset($items[$item['id']])) {
$item['id'] = $items[$item['id']]; $item['id'] = $items[$item['id']];
} }
@@ -126,7 +124,7 @@ class Monsters {
} }
if(!in_array($name, $names_added)) { if(!in_array($name, $names_added)) {
try { try {
Monster::create(array( $db->insert(TABLE_PREFIX . 'monsters', array(
'name' => $name, 'name' => $name,
'mana' => empty($mana) ? 0 : $mana, 'mana' => empty($mana) ? 0 : $mana,
'exp' => $monster->getExperience(), 'exp' => $monster->getExperience(),
@@ -160,7 +158,7 @@ class Monsters {
success('Added: ' . $name . '<br/>'); success('Added: ' . $name . '<br/>');
} }
} }
catch(\Exception $error) { catch(PDOException $error) {
if($show) { if($show) {
warning('Error while adding monster (' . $name . '): ' . $error->getMessage()); warning('Error while adding monster (' . $name . '): ' . $error->getMessage());
} }

View File

@@ -7,8 +7,7 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC;
class Data class Data
{ {

View File

@@ -8,16 +8,15 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC; $configForumTablePrefix = setting('core.forum_table_prefix');
if(null !== $configForumTablePrefix && !empty(trim($configForumTablePrefix))) {
$settingForumTablePrefix = setting('core.forum_table_prefix'); if(!in_array($configForumTablePrefix, array('myaac_', 'z_'))) {
if(null !== $settingForumTablePrefix && !empty(trim($settingForumTablePrefix))) { throw new RuntimeException('Invalid value for forum_table_prefix in config.php. Can be only: "myaac_" or "z_".');
if(!in_array($settingForumTablePrefix, array('myaac_', 'z_'))) {
throw new \RuntimeException('Invalid value for forum_table_prefix in config.php. Can be only: "myaac_" or "z_".');
} }
define('FORUM_TABLE_PREFIX', $settingForumTablePrefix); define('FORUM_TABLE_PREFIX', $configForumTablePrefix);
} }
else { else {
if($db->hasTable('z_forum')) { if($db->hasTable('z_forum')) {
@@ -31,9 +30,9 @@ else {
class Forum class Forum
{ {
/** /**
* @param \OTS_Account $account * @param OTS_Account $account
* @return bool * @return bool
* @throws \E_OTS_NotLoaded * @throws E_OTS_NotLoaded
*/ */
public static function canPost($account) public static function canPost($account)
{ {
@@ -155,14 +154,14 @@ class Forum
return !count($errors); return !count($errors);
} }
public static function toggleHide_board($id, &$errors) public static function toggleHidden_board($id, &$errors)
{ {
global $db; global $db;
if(isset($id)) if(isset($id))
{ {
$query = self::get_board($id); $query = self::get_board($id);
if($query !== false) if($query !== false)
$db->update(TABLE_PREFIX . 'forum_boards', array('hide' => ($query['hide'] == 1 ? 0 : 1)), array('id' => $id)); $db->update(TABLE_PREFIX . 'forum_boards', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
else else
$errors[] = 'Forum board with id ' . $id . ' does not exists.'; $errors[] = 'Forum board with id ' . $id . ' does not exists.';
} }
@@ -295,7 +294,7 @@ class Forum
$section = $sections[$board_id]; $section = $sections[$board_id];
if($section['guild'] > 0) { if($section['guild'] > 0) {
if($logged) { if($logged) {
$guild = new \OTS_Guild(); $guild = new OTS_Guild();
$guild->load($section['guild']); $guild->load($section['guild']);
$status = false; $status = false;
if($guild->isLoaded()) { if($guild->isLoaded()) {
@@ -323,3 +322,4 @@ class Forum
return $hasAccess; return $hasAccess;
} }
} }
?>

View File

@@ -8,11 +8,7 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!');
namespace MyAAC;
use MyAAC\Cache\PHP as CachePHP;
use MyAAC\Models\Spell;
class Items class Items
{ {
@@ -27,7 +23,7 @@ class Items
return false; return false;
} }
$xml = new \DOMDocument; $xml = new DOMDocument;
$xml->load($file_path); $xml->load($file_path);
$items = array(); $items = array();
@@ -43,7 +39,8 @@ class Items
} }
} }
$cache_php = new CachePHP(config('cache_prefix'), CACHE . 'persistent/'); require_once LIBS . 'cache_php.php';
$cache_php = new Cache_PHP(config('cache_prefix'), CACHE);
$cache_php->set('items', $items, 5 * 365 * 24 * 60 * 60); $cache_php->set('items', $items, 5 * 365 * 24 * 60 * 60);
return true; return true;
} }
@@ -70,7 +67,8 @@ class Items
return; return;
} }
$cache_php = new CachePHP(config('cache_prefix'), CACHE . 'persistent/'); require_once LIBS . 'cache_php.php';
$cache_php = new Cache_PHP(config('cache_prefix'), CACHE);
self::$items = $cache_php->get('items'); self::$items = $cache_php->get('items');
} }
@@ -80,6 +78,8 @@ class Items
} }
public static function getDescription($id, $count = 1) { public static function getDescription($id, $count = 1) {
global $db;
$item = self::get($id); $item = self::get($id);
$attr = $item['attributes']; $attr = $item['attributes'];
@@ -112,15 +112,17 @@ class Items
$s .= 'an item of type ' . $item['id']; $s .= 'an item of type ' . $item['id'];
if(isset($attr['type']) && strtolower($attr['type']) == 'rune') { if(isset($attr['type']) && strtolower($attr['type']) == 'rune') {
$item = Spell::where('item_id', $id)->first(); $query = $db->query('SELECT `level`, `maglevel`, `vocations` FROM `' . TABLE_PREFIX . 'spells` WHERE `item_id` = ' . $id);
if($item) { if($query->rowCount() == 1) {
if($item->level > 0 && $item->maglevel > 0) { $query = $query->fetch();
if($query['level'] > 0 && $query['maglevel'] > 0) {
$s .= '. ' . ($count > 1 ? "They" : "It") . ' can only be used by '; $s .= '. ' . ($count > 1 ? "They" : "It") . ' can only be used by ';
} }
$configVocations = config('vocations'); $configVocations = config('vocations');
if(!empty(trim($item->vocations))) { if(!empty(trim($query['vocations']))) {
$vocations = json_decode($item->vocations); $vocations = json_decode($query['vocations']);
if(count($vocations) > 0) { if(count($vocations) > 0) {
foreach($vocations as $voc => $show) { foreach($vocations as $voc => $show) {
$vocations[$configVocations[$voc]] = $show; $vocations[$configVocations[$voc]] = $show;

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