Compare commits

..

644 Commits

Author SHA1 Message Date
slawkens
0342293847 Merge branch 'develop' into feature/settings 2023-08-05 20:52:35 +02:00
slawkens
c802d427eb Merge branch '0.9' into develop 2023-08-05 20:52:26 +02:00
slawkens
aacc120360 Remove deprecated utf8_decode 2023-08-05 20:52:01 +02:00
slawkens
757ec28028 Removed deprecated functions: utf8_encode & decode 2023-08-05 20:51:18 +02:00
slawkens
41fa695d8b Add some functions to compatibility layer of gesioraac 2023-08-05 20:50:33 +02:00
slawkens
b12c30982d Merge branch '0.9' into develop 2023-08-05 11:57:38 +02:00
slawkens
fcb2fc3002 Add .htaccess to .gitignore 2023-08-05 11:57:27 +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
bb0e621308 Merge branch '0.9' into develop 2023-07-29 07:27:26 +02:00
slawkens
53221a9fd1 There is no more info. That never worked. 2023-07-29 07:27:07 +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
d3b15a0a3e Fix multiple redirects error in browser 2023-07-22 14:46:28 +02:00
slawkens
23047aa608 Fix multiple redirects error in browser 2023-07-22 14:46:20 +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
beff3e3aa6 Merge branch '0.9' into develop 2023-07-22 14:05:01 +02:00
slawkens
4a629b4418 Add protection, nothing important - thrown exception before 2023-07-22 14:03:57 +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
Gabriel Pedro
3c3ddc4578 feat: custom words blocked (#190)
* Update config.php

* Update validator.php

* Update config.php
2023-07-22 09:54:03 +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
0788dc8848 Merge branch '0.9' into develop 2023-07-21 21:22:41 +02:00
slawkens
5791d1e7f9 Update template.php 2023-07-21 21:22:23 +02:00
slawkens
a9cb017def Fix menu highlighting & opening 2023-07-21 21:22:13 +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
eaa9d6be43 Merge branch '0.9' into develop 2023-07-21 16:38:22 +02:00
slawkens
7588904372 Remove debugging var_dump 2023-07-21 16:38:10 +02:00
slawkens
712ca30293 Merge branch '0.9' into develop 2023-07-21 15:54:43 +02:00
slawkens
5fa4890b70 Add support for menu_default_color 2023-07-21 15:54:22 +02:00
slawkens
ca56b4f101 Fix menu cannot remove 2023-07-21 15:12:07 +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
707aea18db Merge branch '0.9' into develop 2023-07-21 11:58:51 +02:00
slawkens
848c5c0887 Change default timezone 2023-07-21 11:58:18 +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
e14df529c0 Revert some change 2023-07-19 22:40:39 +02:00
slawkens
9f67cab503 Add twig context for twig hook() function
Allows to use variables from template inside the hook file with usage of $context variable
2023-07-19 22:40:11 +02:00
slawkens
99c53c75f2 New guild hooks, for some upcoming big feature ;) 2023-07-19 22:26:47 +02:00
slawkens
df7c82c571 Fix highscores if there is only 1 record 2023-07-19 11:57:32 +02:00
slawkens
ddb093ec48 Fix highscores if there is only 1 record 2023-07-19 11:57:26 +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
714476bf29 Merge branch '0.9' into develop 2023-07-13 11:08:30 +02:00
slawkens
e49690b52b Thanks @anyeor for previous fix 2023-07-13 11:03:37 +02:00
slawkens
f9d35b719b Fix: cannot create topic on this board (check wasn't working) 2023-07-11 11:17:34 +02:00
slawkens
c886384f2c Merge branch 'develop' into feature/settings 2023-07-08 19:16:22 +02:00
slawkens
a61cd43c3c Forum: nothing important, just formatting 2023-07-07 17:43:28 +02:00
slawkens
6d1b3235d2 Merge branch '0.9' into develop 2023-07-07 17:29:02 +02:00
slawkens
e7e9d8e3b9 Shorten some forum code about length 2023-07-07 17:20:50 +02:00
slawkens
8cf0e80019 Forum: better error messages (Suggested by @anyeor) 2023-07-07 17:20:23 +02:00
slawkens
c392fa7272 Fix guild description on guilds page 2023-07-02 13:48:57 +02:00
slawkens
082884baa0 Fix guild description not shown 2023-07-02 00:26:44 +02:00
slawkens
3a31a0326c Fix guild description not shown 2023-07-02 00:26:33 +02:00
slawkens
2d561f267d Fix guild description not shown on guilds page 2023-06-30 19:52:20 +02:00
slawkens
5eafff737a Guilds & Characters: Use CSS word-break: break-all instead of PHP wordwrap
Suggested by @anyeor
2023-06-30 19:52:05 +02:00
slawkens
8cf4d0cb0f Add word-break on forum thread & reply
When someone inserts long word, is will break into multiple lines
2023-06-30 19:43:36 +02:00
slawkens
d1953470d9 Add word-break on forum thread & reply
When someone inserts long word, is will break into multiple lines
2023-06-30 19:43:31 +02:00
slawkens
3a52f2c403 nothing important 2023-06-30 17:35:39 +02:00
slawkens
ac40922957 Merge branch '0.9' into develop 2023-06-30 17:32:40 +02:00
slawkens
5aed9ee1a4 Forum: Fix quote and edit post buttons not being shown 2023-06-30 17:30:29 +02:00
slawkens
8318169c39 Fix twig exception thrown when player does not exist 2023-06-30 17:30:01 +02:00
slawkens
ad00cf3fc3 Fix BASE_DIR when accessing /tools 2023-06-30 17:29:49 +02:00
slawkens
3ff7b21287 Move <base href> above, so it works, thanks @Leesneaks 2023-06-30 17:28:34 +02:00
slawkens
36fbae850d Revert "<base> is not working properly, use full URL instead"
This reverts commit fa015b8d39.
2023-06-30 17:28:19 +02:00
slawkens
24ff5684cd More changes to deleted characters (Account, guilds)
Account: Cannot change name, comment, gender
+ Cannot be deleted if owns a guild
Guilds: Cannot create, cannot be invited, cannot accept invite, cannot be passed leadership to
2023-06-30 17:27:31 +02:00
slawkens
aab62fb724 Important fix: Not allow create char if limit is exceeded (by @anyeor )
Could have been used to spam database, now it doesn't ignore deleted characters

He is not my brother :P Just same last name
2023-06-30 17:25:32 +02:00
slawkens
a810890614 code formatting 2023-06-30 17:25:21 +02:00
slawkens
a3bfdc1ec8 small adjustments 2023-06-25 08:54:36 +02:00
slawkens
a7dc719934 small adjustments 2023-06-25 08:54:22 +02:00
slawkens
74433303fb Better Gesior support 2023-06-23 21:52:23 +02:00
slawkens
30d62bda3b Better Gesior support 2023-06-23 21:52:11 +02:00
slawkens
cc7703766e Patching some changes from master 2023-06-19 08:05:58 +02:00
SRNT-GG
9d664d3577 WIP - Removing unneccessary closing tags to prevent potential issues. (#223)
* Part 1

Removing closing tags when no HTML or other output comes after the last PHP codeblock.

* Further removals

* nothing

---------

Co-authored-by: slawkens <slawkens@gmail.com>
2023-06-15 21:08:20 +02:00
SRNT-GG
76bfab1303 WIP - Removing unneccessary closing tags to prevent potential issues. (#223)
* Part 1

Removing closing tags when no HTML or other output comes after the last PHP codeblock.

* Further removals

* nothing

---------

Co-authored-by: slawkens <slawkens@gmail.com>
2023-06-15 21:06:22 +02:00
slawkens
7d2fc48437 Fix links to edit/delete/hide directly from page 2023-06-11 18:57:57 +02:00
slawkens
171c114b0f Fix links to edit/delete/hide directly from page 2023-06-11 18:57:52 +02:00
slawkens
b1d2ac34a2 Update branch name 2023-06-03 18:51:57 +02:00
slawkens
c7ce87c4b6 do not report if CI test 2 2023-06-03 18:50:43 +02:00
slawkens
4e22c42b10 test dump env 2023-06-03 18:50:34 +02:00
slawkens
eabe789bbb Disable reporting on CI 2023-06-03 18:50:22 +02:00
slawkens
aa1403480c Update to 0.10.0-dev 2023-06-03 18:50:14 +02:00
slawkens
91c8f1f5bc do not report if CI test 2 2023-06-03 18:41:16 +02:00
slawkens
b421bf3931 test dump env 2023-06-03 18:38:30 +02:00
slawkens
6e6f4679f4 Disable reporting on CI 2023-06-03 12:24:18 +02:00
slawkens
5bb3e57b7b Rename to .htaccess.dist
Causes problems on default setup
2023-06-03 09:04:30 +02:00
slawkens
17221f5369 Rename to .htaccess.dist
Causes problems on default setup
2023-06-03 09:04:24 +02:00
slawkens
98d4d3fcf0 Install composer deps with --no-dev 2023-06-03 06:47:16 +02:00
slawkens
82092338d6 Install composer deps with --no-dev 2023-06-03 06:47:06 +02:00
slawkens
9868b41a61 <base> is not working properly, use full URL instead 2023-06-02 15:24:14 +02:00
slawkens
c247789adf <base> is not working properly, use full URL instead 2023-06-02 15:24:10 +02:00
slawkens
48822b6561 Use Whoops only if installed, otherwise use myaac exception handler 2023-06-02 15:20:13 +02:00
slawkens
cd22f8def5 Use Whoops only if installed, otherwise use myaac exception handler 2023-06-02 15:20:07 +02:00
slawkens
0f30ebbcea change branch name in release.sh 2023-06-02 08:05:13 +02:00
slawkens
1a2e46f09b Ignore cypress in git-export + install composer deps on release 2023-06-02 08:04:17 +02:00
slawkens
52ac011556 Ignore cypress in git-export + install composer deps on release 2023-06-02 08:04:13 +02:00
slawkens
f34e5f2ac0 Release 0.9.0-alpha 2023-06-02 06:37:25 +02:00
slawkens
ca8db22639 Better news back button 2023-06-01 11:23:36 +02:00
slawkens
1846bf5255 Change button style (characters - view)
was causing issues in other templates
2023-06-01 09:57:27 +02:00
slawkens
dce0ac2f8f nothing important 2023-05-29 10:09:21 +02:00
slawkens
9cc60983d0 Update CHANGELOG.md 2023-05-29 08:55:41 +02:00
slawkens
7c2c88f780 Add Whoops exception handler (nicer debug info in dev mode)
On production = no errors
2023-05-29 08:55:26 +02:00
slawkens
7690811da3 Update install.php 2023-05-29 08:46:07 +02:00
slawkens
7dc2e404ed Fixed many links to admin panel, if ADMIN_PANEL_FOLDER is changed 2023-05-29 00:00:34 +02:00
slawkens
080ab56ea9 Update functions.php 2023-05-28 23:56:35 +02:00
slawkens
83915f080c Fixed when page is hidden 2023-05-28 23:56:26 +02:00
slawkens
2841f17729 fix images base url, uploaded by tinymce 2023-05-28 23:54:36 +02:00
slawkens
0187ba4938 New hook: HOOK_ACCOUNT_CREATE_AFTER_PASSWORD
for password strength meter
2023-05-26 22:49:24 +02:00
slawkens
bedfc0a2e0 Update bootstrap to v5.2.3 in install 2023-05-26 17:50:38 +02:00
slawkens
ea08c04963 nothing important 2023-05-26 16:49:28 +02:00
slawkens
067f2af3e5 Wait for success, then screenshot 2023-05-26 16:15:39 +02:00
slawkens
8d98306f8e optimize workflow 2023-05-26 16:12:50 +02:00
slawkens
09a045334c Update cypress.yml 2023-05-26 14:53:33 +02:00
slawkens
bc8e5fc144 Update .gitattributes 2023-05-26 14:51:33 +02:00
slawkens
77e0d28a9d Delete .travis.yml 2023-05-26 14:09:10 +02:00
slawkens
480a054f0c Fixed ADMIN_PANEL_FOLDER, can be 100% custom now 2023-05-26 14:04:52 +02:00
slawkens
26c895d475 Block access to some files [skip ci] 2023-05-26 13:51:05 +02:00
slawkens
5cbb55cfb1 Upload videos too 2023-05-26 13:11:39 +02:00
slawkens
dcb9506a1b admin is already created during install 2023-05-26 13:10:14 +02:00
slawkens
2acec4df12 bring back matrix, wasn't the issue 2023-05-26 13:05:35 +02:00
slawkens
4bd761c726 remove typo 2023-05-26 13:05:29 +02:00
slawkens
2f732b8411 wrong position 2023-05-26 13:00:26 +02:00
slawkens
5aa02055bf fix path 2023-05-26 12:58:28 +02:00
slawkens
6ed15565c8 Import TFS Schema 2023-05-26 12:55:08 +02:00
slawkens
77a2c55c87 Update cypress.yml 2023-05-26 12:50:37 +02:00
slawkens
4a9fa01eb7 Update cypress.yml 2023-05-26 12:49:11 +02:00
slawkens
bd031d8980 create database manually 2023-05-26 12:46:03 +02:00
slawkens
b76a037a94 last try to fix mysql 2023-05-26 12:22:06 +02:00
slawkens
e71daa2520 Update cypress.yml 2023-05-26 12:18:51 +02:00
slawkens
f372aeb067 Update cypress.yml 2023-05-26 12:13:23 +02:00
slawkens
ef37bbcb81 Update cypress.yml 2023-05-26 11:49:24 +02:00
slawkens
944457463e Update cypress.yml 2023-05-26 11:01:44 +02:00
slawkens
6f7f25bb46 Update cypress.yml 2023-05-26 10:54:57 +02:00
slawkens
d60d7f2250 test 5.7 mysql 2023-05-26 10:48:47 +02:00
slawkens
2b8c4b3eca test connect with root 2023-05-26 10:44:02 +02:00
slawkens
7039bda359 Update cypress.yml 2023-05-26 10:38:30 +02:00
slawkens
d346a8f73f Update cypress.yml 2023-05-26 10:27:38 +02:00
slawkens
523f2dee7c mysqlPass 2023-05-26 10:21:05 +02:00
slawkens
b33e39491b MySQL needs to be started manually 2023-05-26 10:19:13 +02:00
slawkens
317ebf4387 Update cypress.yml 2023-05-26 10:12:28 +02:00
slawkens
31ba780099 Update cypress.yml 2023-05-26 10:08:51 +02:00
slawkens
d1b30619e2 fix path to config.lua 2023-05-26 09:56:49 +02:00
slawkens
3fab52296a Update cypress.yml 2023-05-26 09:52:11 +02:00
slawkens
a6e109799a Update cypress.yml 2023-05-26 09:48:55 +02:00
slawkens
80af2cd691 cypress-workflow: config.lua move + replace values 2023-05-26 09:47:39 +02:00
slawkens
d911b55e25 Update cypress.yml 2023-05-26 09:24:49 +02:00
slawkens
eb73fc4538 try fix cypress 2023-05-26 09:19:46 +02:00
slawkens
75f77ec7a3 Fix: Run PHP Server 2023-05-26 09:11:04 +02:00
slawkens
a1d969bbfd fix env 2023-05-26 09:00:21 +02:00
slawkens
11f1ad6d76 fix path 2023-05-26 08:53:49 +02:00
slawkens
7facf0adad fix branch 2023-05-26 08:52:05 +02:00
slawkens
2b739c2b40 Add Cypress workflow 2023-05-26 08:49:28 +02:00
slawkens
269ae323e0 Add Cypress tests: install + create account 2023-05-26 08:49:04 +02:00
slawkens
0d0e5812dd Change step to $_REQUEST 2023-05-26 08:36:20 +02:00
slawkens
61c2661377 Fix warning when no header language set 2023-05-25 11:39:45 +02:00
slawkens
de710dff94 Add cypress/e2e/2-advanced-examples to .gitignore 2023-05-25 11:39:02 +02:00
slawkens
8c524171fb Add cypress.env.json to .gitignore 2023-05-25 09:31:29 +02:00
slawkens
946d24690c Update common.php 2023-05-25 09:30:44 +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
bf137189c5 Update CHANGELOG.md 2023-05-15 00:22:51 +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
da4e18cb69 Fixes to routing 2023-05-13 12:49:17 +02:00
slawkens
7723f87bbf Merge branch 'develop' into feature/settings 2023-05-13 12:06:36 +02:00
slawkens
85769c1439 Empty URL = show news 2023-05-13 11:34:51 +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
4d3ad4b6b9 Update jQuery to v3.6.4 and jQuery UI to v1.13.2 2023-04-19 23:15:28 +02:00
slawkens
e900a62e75 Print more info if character cannot be created 2023-04-12 12:52:14 +02:00
slawkens
c3969364aa Fix default news route if friendly_urls is disabled 2023-04-01 22:13:24 +02:00
slawkens
e9df9f10dc Add check for player_deaths columns 2023-04-01 15:11:12 +02:00
slawkens
f78f5b5361 OK, so phplint is working! 2023-03-31 10:23:10 +02:00
slawkens
c061438a35 test phplint 2023-03-31 10:21:27 +02:00
slawkens
8441dbe007 Add actions/checkout@v3 2023-03-31 10:18:48 +02:00
slawkens
e21a741a78 Use overtrue/phplint@8.2 for phplint 2023-03-31 10:17:21 +02:00
slawkens
955f437e6c test github actions 2023-03-31 09:35:05 +02:00
Matheus Collier
fd419076c2 [UPDATE] Adding monster looks to db (#220)
* [UPDATE] Adding monster looks to db

* small adjustments

add into schema.sql + change position in table

* add DEFAULT = ''

---------

Co-authored-by: slawkens <slawkens@gmail.com>
2023-03-31 09:04:13 +02:00
slawkens
7569536d56 Fix when server uses another items serializer 2023-03-26 00:27:16 +01:00
slawkens
3a6102900f fix small bug on install - please fill all input 2023-03-26 00:24:57 +01:00
slawkens
6dbc694409 Do not allow continue install when there is no server database imported 2023-03-26 00:23:50 +01:00
slawkens
7a3dcc4dc6 small fixes to account_login_by_email 2023-03-25 19:17:55 +01:00
slawkens
23393b5d3e Fix cannot go forward when config.local.php cannot be saved 2023-03-22 09:15:32 +01:00
slawkens
863f3ad510 Change from warning to error (config.local.php save error) 2023-03-22 09:15:05 +01:00
slawkens
e6d86ca280 plugins folder should be accessible from public 2023-03-15 17:51:24 +01:00
slawkens
c22e25e3d2 Update nginx-sample.conf 2023-03-06 08:26:29 +01:00
slawkens
52ffb195ec fix account/lost links 2023-02-19 08:01:02 +01:00
slawkens
92a51af638 Fix account number show 2023-02-19 07:31:51 +01:00
slawkens
d7a9158cf2 Update routes.php 2023-02-18 21:45:09 +01:00
slawkens
f0f84090d2 fix creatures post route, back button 2023-02-18 21:26:22 +01:00
slawkens
9d78a3b5cf more php 8.x compatibility 2023-02-18 21:22:54 +01:00
slawkens
2fc163af5a Update tables.headline.html.twig 2023-02-18 21:12:08 +01:00
slawkens
10be98e371 Create account.back_button.html.twig 2023-02-18 21:11:55 +01:00
slawkens
e0eb083e44 new buttons code for tibiacom template, can create button with any text 2023-02-18 21:11:35 +01:00
slawkens
e17cd78153 fix player save on tfs 1.5 with new ipv6 2023-02-18 20:57:44 +01:00
slawkens
0015f511f8 Preparation v0.9.0-alpha release (Updated CHANGELOG) 2023-02-18 13:05:53 +01:00
slawkens
f0f71c9f85 fixes 2023-02-18 09:33:04 +01:00
slawkens
0002543cca feature: Cache::remember($key, $ttl, $callback) + example usage 2023-02-18 08:53:42 +01:00
slawkens
c1096415aa Add check for tables in admin panel 2023-02-18 07:15:11 +01:00
slawkens
6625768228 Remove accounts.blocked 2023-02-18 07:14:51 +01:00
slawkens
a27f601fe8 feature: new functions: getGuildNameById + geGuildLogoById 2023-02-17 20:05:43 +01:00
slawkens
72a877d9ca Show more info about bot 2023-02-17 19:06:13 +01:00
slawkens
b7ba09a551 small fix 2023-02-17 18:48:01 +01:00
slawkens
a98cb66c53 feature: visitors counter shows now user browser, and also if its bot 2023-02-17 18:41:25 +01:00
slawkens
6785ecad1d Ignore case on plugin route method 2023-02-17 17:54:38 +01:00
slawkens
937af536b6 patch from master - long player ip caused error 2023-02-17 17:17:19 +01:00
slawkens
5487314230 preparation for guild wars 2023-02-17 17:10:01 +01:00
slawkens
51e9bb2a7f set default for optional parameter (twig functions) 2023-02-17 17:09:38 +01:00
slawkens
376bb981ae string is also spaces, lets admin that 2023-02-17 13:35:05 +01:00
slawkens
ed9d78d2f3 Fixes for config.account_create_auto_login 2023-02-17 13:15:13 +01:00
slawkens
3c4e50dbda formatting 2023-02-16 11:24:19 +01:00
slawkens
523f9dd95a New hook: HOOK_ACCOUNT_CHANGE_PASSWORD_POST 2023-02-16 11:24:00 +01:00
slawkens
a43742c8b1 rename hook 2023-02-16 11:22:12 +01:00
slawkens
c49e4fd63d add hook for disable accounts edit for next.my-aac.org (security) 2023-02-16 11:07:00 +01:00
slawkens
905cce7021 Update mailer.php 2023-02-16 10:53:15 +01:00
slawkens
7a49b5dedc Disable add php pages in admin panel for security. Option to disable plugins upload 2023-02-16 10:53:06 +01:00
slawkens
3a2870a6bb 760 is correct permission 2023-02-16 10:06:08 +01:00
slawkens
9a475f2c57 fix for othire where size is saved in houses.tiles 2023-02-16 08:44:17 +01:00
slawkens
58598742e8 change spaces to tabs 2023-02-16 08:43:21 +01:00
slawkens
d04e44f52f add info which plugin is going to be uninstalled 2023-02-16 07:21:38 +01:00
slawkens
c7ec1f44e9 Option to enable/disable plugin by renaming file + cleanup
new function: getAllPluginsJson
removeComments removed - json doesnt allow for comments anyway
2023-02-16 06:57:46 +01:00
slawkens
3ed9a5d3d8 add hook: HOOK_GUILDS_AFTER_INVITED_CHARACTERS, for guild wars 2023-02-16 05:16:22 +01:00
slawkens
61285b6b8c small fix to routes with string 2023-02-15 17:32:48 +01:00
slawkens
d17c547bca add $params as optional parameter to hook twig function 2023-02-15 17:12:56 +01:00
slawkens
7bc20b0993 change spaces to tabs 2023-02-15 17:12:30 +01:00
slawkens
6c4b3dea96 Delete autoload.php 2023-02-15 08:06:57 +01:00
slawkens
6ae1bf5814 Add missing header to some files 2023-02-15 08:06:08 +01:00
slawkens
8503135ce0 add some notice 2023-02-14 23:22:17 +01:00
slawkens
590fe0762d small fixes 2023-02-14 22:03:22 +01:00
slawkens
d565b90736 Update accounts.php 2023-02-14 21:51:54 +01:00
slawkens
c88156802a fix pages not found 2023-02-14 21:51:46 +01:00
slawkens
7d8dbcbde7 fixes to account number part 3 2023-02-14 19:40:55 +01:00
slawkens
66ec66b291 Allow TinyMCE to resize horizontally and vertically 2023-02-14 18:47:56 +01:00
slawkens
fc0eb0e793 add missing hook 2023-02-14 18:40:46 +01:00
slawkens
ed7e9e1eae fixes to account number part 2 2023-02-14 18:40:31 +01:00
slawkens
8985917a96 Fixes to account number 2023-02-14 18:28:31 +01: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
3a3411c117 New hooks for admin page, for head, body, and before_page
+move LOGIN_POST to correct place
2023-02-07 16:27:02 +01:00
slawkens
1166ddfe87 Remove google recaptcha from code
will be included as plugin. This allows for custom recaptcha's
2023-02-07 15:20:24 +01:00
slawkens
574e361f90 fix warning 2023-02-07 12:03:18 +01:00
slawkens
f3745a2752 Feature/new router (#165)
* Remove unneeded escape

* Fix guild back buttons (change logo & motd)

* small adjustment in news.php

* Fix create character when admin (any case is allowed now)

* Fix forum table style (boards & thread view)

* Small improvement to plugins.enabled check

* [WIP] nikic/fast-route implementation

I will describe it more in Pull Request

* Optimisations & fixes.

* Fix path - should not be absolute

* Add PLUGINS to Twig path

* Don't hide "Install Plugin" Box by default

* Update package-lock.json

* nothing important, just early exit & fixes

Fix creature display

* fix premium_ends_at for tfs 1.3+

* Move pages

* Move pages tbc

* $db->select: make $where parameter optional, allows to get all records

* Add some error box to error

* fix parse error

* Rewriting the router v2

To be more flexible

* small fixes

* fix & add admin icons

* Move mass_* pages to correct folder

* fix logout hook 2

* Delete accountmanagement.php

* This code wasn't used

* Add missing var

* Add redirect_from && redirect_to to router options

+ Also add * for all methods shortcut

* Remove comments

Not allowed in normal json

* Allow admin pages included into plugins dir

* block access to some files

* Fix admin logout

* Fix #178

* feature: mail confirmed reward

Suggested by @EPuncker

# Conflicts:
#	system/hooks.php

* remove misleading comment

* adjust required version according to composer.json

* fix duplicated word

* Adjustments & fixed to mass actions

* Add password confirm, and change text type to password

* Add list of Open Source Software MyAAC is using

* Fix signature

* Show First, Second instead of numbers

* fix base dir detection

* fix double ACTION define + undefined URI in template

* new function> escapeHtml + fix css in admin menus

* fix changelog add

* fix news adding, rename const to NEWS_*

* Add verify to pages, add messages, limits, fix add

* fix "Please fill all input"

* add required input to admin pages

* shorten some expressions with ??

* shorten code + fix conversion (int)

* Move account_types to config, account.web_flags to common.php

* Update example.json

* feature: router aliases

* shorten some code + const convert

* remove wrong char

* fix signature on custom basedir

* fix: mass teleport position validation (#214)

* fix: mass teleport position validation

* fix: max position

* Fix execute in CLI

* fix warning in reload cache in dev mode

* Configurable admin panel folder

* feature: plugin require more options with comma

* $config_account_salt -> USE_ACCOUNT_SALT

* fix forum show_thread

* Update show_thread.php

---------

Co-authored-by: Gabriel Pedro <gpedro@users.noreply.github.com>
2023-02-07 11:41:05 +01:00
slawkens
a2fb9a183b add some notice 2023-02-02 21:22:50 +01:00
slawkens
295c5de0d6 change spaces to tabs 2023-02-02 21:21:05 +01:00
slawkens
d4650afa0e increase increase max file upload for nginx 2023-02-02 21:20:22 +01:00
slawkens
07da4ca028 Update twig to v2.0 2023-02-02 20:52:27 +01:00
slawkens
feffdd1837 fix logout hook 2023-02-02 20:52:16 +01:00
slawkens
979532d3df Display warning if file included by hook does not exist 2023-02-02 20:51:55 +01:00
slawkens
3c77c54c8e my fault 2023-02-02 18:55:16 +01:00
slawkens
74d013049d Made so it's possible to configure more directories as constants
More flexibility for the user.
2023-02-02 18:53:56 +01:00
slawkens
708aa2d72f Just save images into images/editor 2023-02-02 18:29:41 +01:00
slawkens
dd6581f7f7 Update .gitignore 2023-02-02 16:24:34 +01:00
slawkens
8c801dddec PHP 8.1 compatibility 2023-02-02 16:16:06 +01:00
slawkens
9de8145f82 TineMCE refactoring
Unified all tinyMCE instances used across AAC, now they are initiated in one single file
+ added option to upload images within editor (CTRL-C CTRL-V)
+ there is new folder: user/, which will be used for all user generated data, like image uploads, guild images, etc.
2023-02-02 15:41:33 +01:00
slawkens
77460b0832 Revert "Fix compatibility with PHP 8.1"
This reverts commit 1d1e927d56.
2023-02-02 15:39:20 +01:00
slawkens
1fb1fb3ae9 Update tinyMCE to v6.3.1 2023-02-02 15:01:56 +01:00
slawkens
1d1e927d56 Fix compatibility with PHP 8.1 2023-02-02 11:17:48 +01:00
slawkens
036abf83e5 Change GoogleReCAPTCHA.php to require_once
because conflicts with account_create_auto_login
2023-02-01 22:58:31 +01:00
slawkens
e737cf612c fix recaptcha v2-checkbox & v3 2023-02-01 22:54:35 +01:00
slawkens
78622fb47a set ACCOUNT_NUMBER_LENGTH = 8, is more reasonable 2023-02-01 22:53:57 +01:00
Gabriel Pedro
9560494ab0 feat: mounts load from xml (#211) 2023-01-19 20:47:00 +01:00
Gabriel Pedro
8aac3ec2e5 fix: add missing $use_datatable (#210)
* fix: datatables

* fix: datatables
2022-12-07 08:37:35 +01:00
Gabriel Pedro
269ca501f1 feat: mass account tool, mass teleport tool (#209)
* feat: mass account coins, premdays, points. mass teleport town, position

* fix: tab
2022-12-01 08:34:30 +01:00
Gabriel Pedro
20638f430a feat: add hook admin menu (#208)
* feat: add hook admin menu

* fix: removing menu sort

* feat: menu order property

* fix: menu order value

* feat: add main menu order
2022-11-28 18:05:08 +01:00
slawkens
acb551c5b0 Merge branch 'feature/recaptcha-v3-plus-login' into develop 2022-11-28 12:54:34 +01:00
slawkens
44a6400fcf protect this from direct execution 2022-11-28 12:52:03 +01:00
slawkens
847c3db625 Update templates.header.html.twig 2022-11-28 12:49:30 +01:00
slawkens
f30181d485 Merge branch 'develop' into feature/recaptcha-v3-plus-login 2022-11-28 12:46:32 +01:00
slawkens
118e8c487e Fixes for racaptcha 2022-11-28 12:41:29 +01:00
slawkens
c73e476e88 Reverted support only for recaptcha v3
v2 & v3 are now both supported
2022-11-28 12:36:23 +01:00
slawkens
ac5b864ea9 Small fixes 2022-11-28 12:26:34 +01:00
Gabriel Pedro
42d531838c feat: github actions phplint (#206)
* feat: php linter on pull requests

* test: breaking code

* Revert "test: breaking code"

This reverts commit 9d385a3421.
2022-11-24 08:19:09 +01:00
slawkens
2321cf84b0 patch changes & fixes from master branch
remove VERSION file
update rules
add 33 migration
add get_version_for_release.sh script
update schema
add use_character_sample_skills
2022-11-07 09:10:19 +01:00
slawkens
a570363fe0 Update README.md 2022-11-07 09:07:32 +01:00
slawkens
616b8eb61a some not-important changes 2022-10-28 17:16:17 +02:00
slawkens
e1d486c8c8 Add vocation into getTopPlayers 2022-10-28 14:41:59 +02:00
slawkens
b841c9f631 Fix typo in br locale 2022-10-28 14:41:43 +02:00
slawkens
e6c72efd18 Add more client versions 2022-10-28 14:41:28 +02:00
slawkens
9693fd260c Update account.change_mail.html.twig 2022-10-28 14:41:14 +02:00
slawkens
717b5fdd15 Add compat Gesior classes
To allow more custom pages be used with myaac
2022-09-27 10:06:03 +02:00
slawkens
32cf487128 Feature/recaptcha v3 plus login (#202)
* [WIP] New GoogleReCAPTCHA code
Support for v3
v2-invisible doesn't work yet

* Add some notice about recaptchas versions

* Lets support only ReCaptcha v3

Too much mess ;)

* Fixes
2022-08-31 11:16:48 +02:00
slawkens
a9941dea8a Fixes 2022-08-29 19:04:47 +02:00
slawkens
5c9737f281 Merge branch 'develop' into feature/recaptcha-v3-plus-login 2022-08-28 18:28:10 +02:00
slawkens
87a98531d9 Lets support only ReCaptcha v3
Too much mess ;)
2022-08-28 18:13:34 +02:00
slawkens
6d142dcbfe Merge branch 'develop' of https://github.com/otsoft/myaac into develop 2022-08-26 14:05:03 +02:00
slawkens
90f00e9960 Merge branch 'feature/login-by-email' into develop 2022-08-21 16:00:45 +02:00
thatmichaelguy
8711e178e9 Update change_rank.php (#194) 2022-07-04 16:54:19 +02:00
davi costa
eb28b38709 fix guild invite page (#196)
* fix guild invite

* removing var_dump

* sending error
2022-07-04 15:37:49 +02:00
slawkens
afea618867 Optimize code (account number generation)
Thanks kamil-karkus for suggestion
2022-05-31 15:13:59 +02:00
slawkens
0abb9384a6 Fix: create account by email
Now you can at least create an account if account_login_by_email is enabled :)
2022-05-31 15:09:48 +02:00
slawkens
2563583f84 Merge branch 'develop' into feature/login-by-email 2022-05-31 12:25:26 +02:00
slawkens
6acbbe3fa1 patch some changes from master (character name validate) 2022-05-31 12:22:55 +02:00
slawkens
6c157f3f6c Comment useless log line 2022-05-31 10:09:05 +02:00
slawkens
c4737eca72 Update login.php for latest TFS 1.x and otservbr
Works in both.
Thanks for Znote for rfc6238 lib.
2022-05-31 10:08:52 +02:00
thatmichaelguy
5428f5e2cf Update change_rank.php (#194) 2022-05-31 10:08:22 +02:00
slawkens
7d6d77cfbc login.php is now part of official repo
Big thanks to folks from OpenTibiaBR Team
Will be updated in next commits to support latest TFS too
2022-05-31 10:08:10 +02:00
slawkens
87eacd17c5 Add tables.headline
For future reference
2022-05-31 10:07:47 +02:00
slawkens
dd4420dcfd <div> should not be inside of <table> element 2022-05-31 10:07:35 +02:00
slawkens
b8843a29eb Revert "Include tinymce with NPM"
This reverts commit cedcd14550.
2022-03-16 17:27:30 +01:00
slawkens
a12262df55 Add tables.headline
For future reference
2022-03-16 14:30:39 +01:00
slawkens
091828e8f1 Add php_sessions to .gitignore 2022-01-14 19:41:11 +01:00
slawkens
8bca099037 Fix typo 2022-01-07 08:32:18 +01:00
slawkens
a43d641b5f Fixes (config.news_author, group_name|capitalize) 2022-01-02 07:32:15 +01:00
slawkens
46c058df25 Save php sessions in myaac dir
Instead of default PHP location
This fixes problem with permissions
2021-12-28 07:36:38 +01:00
slawkens
fa7c6497e6 Replace define with const 2021-12-27 21:21:24 +01:00
slawkens
82b41d4df5 Add browsehappy code 2021-12-22 07:03:34 +01:00
slawkens
fd2c2d552a Merge branch 'feature/admin-bar' into develop 2021-12-04 21:36:11 +01:00
slawkens
78ae456b45 Finish admin-bar
New ideas welcome. Please open an issue or contact me
2021-12-04 21:34:26 +01:00
slawkens
7e5528b7e1 Merge branch 'develop' into feature/admin-bar 2021-12-04 20:43:00 +01:00
xitobuh
a97f55e189 Add filters (#161)
Added this in what seemed like an empty table above the list. Untested but should work, please elaborate as you see fit
2021-10-28 21:42:33 +02:00
slawkens
50dd65c6de Fix eslint warnings 2021-10-23 15:00:52 +02:00
slawkens
16aeb12111 Comment unused variable 2021-10-23 15:00:30 +02:00
slawkens
96a7c43cb5 Delete cookies.js
was unused
2021-10-23 14:32:42 +02:00
slawkens
ee20ee2ecd Add contributors to credits 2021-10-23 14:25:46 +02:00
slawkens
efdd156d5e Bump twig version to latest release in 1.0 branch 2021-10-23 14:07:14 +02:00
slawkens
be41023005 Bump required PHP Version to ^7.2.5 || ^8.0 2021-10-23 13:59:38 +02:00
slawkens
d143f05bb1 Reorder requirements in composer 2021-10-23 13:57:17 +02:00
slawkens
fdc229b196 php gd extension is optional, so removing it from composer.json 2021-10-23 13:55:24 +02:00
slawkens
f6a5552296 Reorder checks 2021-10-23 13:54:31 +02:00
slawkens
62a4b4d3ec php extension zip is optional now 2021-10-23 13:52:34 +02:00
slawkens
ef24d6739a adjust EditorConfig for composer & npm 2021-10-23 13:35:43 +02:00
slawkens
1831198349 Revert "Adj."
This reverts commit ddf764e308.
2021-10-23 12:15:30 +02:00
slawkens
ddf764e308 Adj. 2021-10-23 11:57:49 +02:00
slawkens
988c757ca6 Small adjustments 2021-10-23 11:46:15 +02:00
slawkens
cedcd14550 Include tinymce with NPM
One will need to run: "npm install" as from now
More info here: https://nodejs.dev/learn/an-introduction-to-the-npm-package-manager
2021-10-23 10:23:37 +02:00
slawkens
0ff290f868 Update .gitignore 2021-10-23 09:52:11 +02:00
slawkens
1764ce0519 Fix: undefined variable notice on database_log enabled 2021-08-30 16:16:33 +02:00
slawkens
f3b49d7cba Experimental: change player_deaths entries on name change 2021-08-30 16:16:13 +02:00
slawkens
6d19d69d20 Fix some undefined notice 2021-07-05 17:15:48 +02:00
slawkens
9ad367370a Support for downgraded TFS 7.72 (with accounts.number)
Part 2
2021-06-09 01:54:22 +02:00
slawkens
eb091e487d Support for downgraded TFS 7.72 (with accounts.number)
Part one
2021-06-09 01:54:05 +02:00
slawkens
a5ccc794bc Add exception class to whoops screen 2021-06-09 01:46:08 +02:00
slawkens
1427dc3ede Move MyAAC table detection to proper place 2021-06-09 01:45:38 +02:00
slawkens
e47bb11883 Suggest account number option 2021-06-09 01:01:18 +02:00
slawkens
6f3ba9c34b Merge branch 'develop' into feature/login-by-email 2021-06-09 00:08:13 +02:00
slawkens
0f3d2424ce Fix release.sh (some warning) 2021-06-08 23:18:31 +02:00
slawkens
4dbcad5ad5 Merge branch 'develop' into feature/settings 2021-06-08 22:06:21 +02:00
slawkens
8ecd8a10c0 Remove unneeded escape 2021-06-08 19:19:12 +02:00
slawkens
3cc3e3a8e9 Fix guild back buttons (change logo & motd) 2021-06-08 19:19:02 +02:00
slawkens
be1086bcba small adjustment in news.php 2021-06-08 19:18:45 +02:00
slawkens
f9abe9a8e3 Fix create character when admin (any case is allowed now) 2021-06-08 19:18:25 +02:00
slawkens
632ecb6d20 Fix forum table style (boards & thread view) 2021-06-08 19:18:13 +02:00
slawkens
db554df041 Small improvement to plugins.enabled check 2021-06-08 19:18:01 +02:00
slawkens
7300e4f1ad Cleaning unused variable 2021-06-08 07:44:16 +02:00
slawkens
9b84532e57 Reformatting code (moving javascript to own file) 2021-06-08 07:43:06 +02:00
slawkens
14870d74df This was wrong.. 2021-06-08 07:41:28 +02:00
slawkens
9c7794fe13 Reformatting code 2021-06-08 07:29:04 +02:00
anyeor
d9526d4021 Update 404 response (#163)
Updating for new SPL standard.
2021-06-05 05:19:00 +02:00
slawkens
454e09ec3d Use reference instead of new array 2021-05-23 22:59:49 +02:00
slawkens
c687f64ced Fix color style for different templates 2021-05-23 03:14:17 +02:00
slawkens
80623580f2 Fix creating account if $npcCheck is enabled 2021-05-23 02:55:27 +02:00
slawkens
135f393fc4 Change team page title 2021-05-23 02:54:33 +02:00
slawkens
e03da2876c Fix forum boards white color style
So it works on all templates
2021-05-23 02:53:57 +02:00
slawkens
44fff9dcd1 Merge branch 'develop' into feature/admin-bar 2021-05-01 15:04:04 +02:00
slawkens
02f993baea feat: Login By Email 2021-05-01 10:16:43 +02:00
slawkens
f9302d4f9d Require Parsedown class through composer 2021-05-01 08:54:46 +02:00
slawkens
780f8d193f bcsub is not needed here
bcmath module is not required anymore
2021-05-01 01:21:11 +02:00
slawkens
4e85f857a4 Fix #158 Thanks @Misztrz 2021-05-01 01:04:42 +02:00
czbadaro
ea035136e1 Gratis premium account (#156)
* skip premdays and lastdays calculation when premdays = 65535 (gratis premium in TFS)

* TFS consider 65535 as gratis premium account and PHP_INT_MAX does not assume this value

* adds condition of premdays=65535 and standardize the label "gratis premium account" with tibia client

* adjust the label "days" when there is only one day of premium account

* adjusted premium account status

* Some small adjustment

* Sorry, typo.

Co-authored-by: slawkens <slawkens@gmail.com>

(cherry picked from commit 9d7854dda6)
2021-04-23 01:14:32 +02:00
Lee
9d8f398d9f update validator name check
-added character_name_npc_check to config.php
-added npc name check to validator
2021-03-09 23:42:21 +00:00
Lee
31f0050f4e Admin - Dataloader updates
-Npc Lib added
-Admin Dataloader updated to load NPC names into a cached array.
-Spinner Updated to a loading button.
2021-03-09 23:38:23 +00:00
Lee
7ce005341e Twig filter (timeago)
Added twig filter timeago for dates.
2021-03-09 23:17:24 +00: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
84447ef178 Remove unsupported versions from travis 2021-02-23 23:22:03 +01:00
slawkens
b99d3b4960 Forgot this 2021-02-23 18:57:03 +01:00
slawkens
0fc64478e0 PHP 7.1 is now required
Older versions are outdated anyways
2021-02-23 15:15:34 +01:00
slawkens
e7a3d563aa Update .travis.yml
(cherry picked from commit 856507fb66)
2021-02-16 01:41:00 +01:00
slawkens
bda020ef93 Attempt to fix travis build
(cherry picked from commit d019fbc050)
2021-02-16 01:40:55 +01:00
slawkens
f0c136c421 More fixes for PHP 8.0 2021-02-16 01:40:24 +01:00
slawkens
5fa1321619 Fixes to database version and monsters table 2021-02-16 01:12:45 +01:00
slawkens
792ec17d18 Increase size of myaac_visitors.page column to 2048
Thanks to OtLand user kaleuui (https://otland.net/threads/myaac-v0-8-3.268654/page-11#post-2643853)
2021-02-16 00:56:25 +01:00
slawkens
19ffd57b34 Minimum PHP 5.6 is now required (composer part) 2021-02-16 00:32:16 +01:00
slawkens
ebda456862 Minimum PHP 5.6 is now required 2021-02-16 00:31:13 +01:00
slawkens
5bd5aa0edf Fix compatibility with PHP 8.0 (latest XAMPP)
Solution by doctrine developers
2021-02-16 00:28:54 +01:00
slawkens
6b07d56627 Fix setPremDays for latest TFS
Fixes editing account in admin panel
2021-02-15 21:05:08 +01:00
slawkens
15d381adfd Fixed account getPremDays() function for latest TFS
This fixes account management + signature
2021-02-15 20:57:24 +01:00
Lee
23b44d6c8a #142 Guildnick fix
Fixes the Guildnick not showing in the guild pages.
2021-02-14 12:50:10 +00:00
slawkens
e3f2abc06e Fix parsing empty strings in config.lua (with comments)
(cherry picked from commit eed490507c)
2021-02-13 22:57:11 +01:00
slawkens
3d73de13d8 Fix headling.php cannot find font 2021-02-13 22:34:46 +01:00
slawkens
71f7bb2e75 Fix typo 2021-02-13 22:07:54 +01:00
slawkens
ebe900fca8 Ignore arrays in config.lua (fixes experienceStages loading)
In future we want to parse arrays too, this is just a temporary solution
Thread: https://otland.net/threads/myacc-problem.274795/
2021-02-13 21:53:40 +01:00
slawkens
5a8bcec014 Fix installer choosing name, when config.php is not loaded yet
It has been almost 1 month there, seems no one is using develop branch ;)
2021-02-13 21:44:49 +01:00
Lee
a1c7c2768c Delete char with house #149
oops, didn't mean to submit that last push, I hadn't added the empty check. (noob moment)
quick fix for #149
2021-02-02 14:42:30 +00:00
Lee
565e6e3a3d Delete char with house #149
Patch to stop players deleting themselves if they have a house
Fixes #149
2021-02-02 14:13:36 +00:00
slawkens
855e9aa3b9 Fix: do not count deleted characters
On create new character page
2021-01-20 19:46:07 +01:00
slawkens
a271edec47 Forgot this.. 2021-01-20 18:03:30 +01:00
slawkens
81b293a5a6 Fixes to character name validation
Admin should be able to create any name
Also fixes to config.character_name_min_length being ignored
2021-01-20 18:02:07 +01:00
slawkens
8b41e144f8 Open/Closed Website Status now changes dynamically 2021-01-18 02:17:39 +01:00
slawkens
a41f653e05 Move Admin module statistics to Twig 2021-01-18 02:00:46 +01:00
slawkens
f24ff295e8 Add alt="icon"
Don't like those warnings in IDE :P
2021-01-18 01:48:21 +01:00
slawkens
b399bee3ac Cancel button should return to menus main screen 2021-01-18 01:47:56 +01:00
slawkens
8f88c82a13 Add "table-responsive d-md-table" class
Makes tables in admin panel responsive
2021-01-18 01:47:11 +01:00
slawkens
d8ac88b7d9 Add more clients to clients.conf.php 2021-01-18 01:45:52 +01:00
slawkens
443c5a80b4 Add ext-dom to composer.json 2021-01-17 20:10:21 +01:00
slawkens
ba56ef5e33 Add some badges to README.md
(cherry picked from commit d3850280f4)
2021-01-17 17:45:32 +01:00
slawkens
b24370e7ed Fixed the check if vocations.xml were correctly loaded 2021-01-17 17:44:30 +01:00
slawkens
b2b0b31168 Remove facebook.js, replace with direct live link
This fixes some console errors
2021-01-07 23:37:47 +01:00
slawkens
1e969f8d8a Update index.php 2021-01-07 22:43:25 +01:00
slawkens
bca098e074 Use local storage for saving menu items
Fixes a bug when visiting with browser: www.wykop.pl, and then navigating back to myaac (browser freeze)
2021-01-07 22:43:15 +01:00
slawkens
98bd51436b Unified naming 2021-01-07 11:47:57 +01:00
slawkens
1fa4b1e660 Remove some useless maxlength attribute 2021-01-04 22:06:50 +01:00
slawkens
04a36b1d11 Rename to Recovery Key 2021-01-04 22:06:26 +01:00
slawkens
611d6f505d Add option to send mail to account with Mailer
"Send Mail" link next to Email input in account editor
2021-01-04 21:34:52 +01:00
slawkens
62b485abf9 Update .gitignore 2021-01-04 19:28:18 +01:00
slawkens
61eae7d7c4 Add ./login.php to .gitignore 2021-01-04 19:17:30 +01:00
slawkens
af161b5143 Fix: PHPMailer is included through composer now 2021-01-04 19:17:07 +01:00
slawkens
d5880eac8c Use BASE_URL instead of template_path for icons
Cause they are located in images/news folder
2021-01-04 16:35:01 +01:00
slawkens
02d6ab5fe7 Add lastCheck full date to Server Status panel 2021-01-04 16:32:25 +01:00
Lee
5547ccffd6 Twig updates
Moved non-global functions from twig back into PHP.
2021-01-04 13:11:18 +00:00
Lee
8c06bd1738 function Truncate added
missing function added to functions lib.
2021-01-04 12:42:13 +00:00
Lee
469a8c1017 AdminPanel - Template Fix
Fixed a bug with $status['online'] not being filled and showing invalid badge due to error.
2021-01-04 12:24:23 +00:00
Lee
bb3602073c AdminPanel updates - changelog
-Admin menu updates
-Moved getchangelogtype/where to functions file and added to twig
-Added changelog editor to admin panel and updated changelog page
-Renamed the changelog md reader to clmd and edited the version file.
2021-01-04 12:23:36 +00:00
slawkens
6c6af59b22 Add ext-gd to composer.json 2021-01-04 08:27:45 +01:00
slawkens
a8a36c73e6 Fix notice about premend 2020-12-30 00:27:42 +01:00
slawkens
98b1d854f9 Refactor some line 2020-12-30 00:24:14 +01:00
slawkens
1ada2317fd Add support for accounts.premium_ends_at (Latest tfs 1.x) 2020-12-30 00:10:49 +01:00
slawkens
40722c8c30 Password can now contain any characters
Also added limit of 29 characters (client limitation)
2020-12-30 00:10:11 +01:00
slawkens
ff9e255f1b On prod it won't display any PHP errors
As suggested by PHP Manual
2020-12-29 22:11:40 +01:00
Lee
fbe9c31d10 config update
renamed and cleaned up the settings names for easier comprehension
2020-12-29 17:50:10 +00:00
Lee
0aed705a6a migration 31 fix.
Some mysql dbs won't allow text to have a default value.
2020-12-29 17:43:17 +00:00
Lee
06e864c954 added between()
Added missing function from creature update.
2020-12-29 17:36:16 +00:00
slawkens
1d68d013df Add json as required extension 2020-12-29 15:00:06 +01:00
Lee
8e6bc73ca6 Creature page overhaul
Updates the creature pages to show more information.
You will need to reload your creatures.
-modifies database with migration 31
-small customisations are allowed via config file.
-functions added, getMonsterLink, getItemRarity, getCreatureImgPath, left, right,
-added functions to twig.
-view elements, immunities, summons, voices, loot, pushables, canpush, canwalk, runonhealth,hostile,attackable,rewardboss,defense,armor
-filter bosses
-show list as picture preview or names list
2020-12-28 16:37:03 +00:00
Lee
7e0fded595 gitignore functions_custom
Adds system/functions_custom.php to the git ignore list.
2020-12-28 16:24:25 +00:00
Lee
c8443228fb Allow template pages
Checks if page exists in template directory and loads that page first instead of system/pages/
This allows users to make their own changes without modifying the original files for when doing updates.
2020-12-28 16:22:41 +00:00
slawkens
64fe0062ee Merge pull request #146 from fernandomatos/template/tibiacom
Fixes and improvements at template's network box
2020-12-26 23:33:44 +01:00
Fernando Matos
3b78516ef2 Add SSL on external image requests of items and outfits (#145) 2020-12-26 23:32:17 +01:00
Fernando Matos
8f345126f7 Add conditional script loading for social networks 2020-12-26 18:30:26 -03:00
Fernando Matos
daaa472dfe Remove unnecessary top player retrievement at network box 2020-12-26 18:14:36 -03:00
Fernando Matos
87f35da3b6 Fix network box showing without social networks specified 2020-12-26 18:04:22 -03:00
Fernando Matos
6f42a60e59 Add a brand new charming installation (for version 0.9) (#144)
* Add a brand new charming installation

* Fix alert position in setup requirements validation

* Add some missing definitions

* A distinction between bootstrap CSS classes and myaac classes

For CSS-styled messages

* Remove unused functions for messages

Co-authored-by: slawkens <slawkens@gmail.com>
2020-12-22 07:47:47 +01:00
slawkens
3beedc1747 New configurable: outfit_images_wrong_looktypes 2020-12-21 01:59:32 +01:00
slawkens
6603815a81 Update bans.php 2020-12-21 01:54:17 +01:00
slawkens
c1027d3663 Fixes on new highscores
Fixed link to next page on first visit default highscores
Fixed position of "No records yet."
Also count pages is starting from 1 now (not from 0 like before)
2020-12-21 01:54:00 +01:00
slawkens
6cec5ba5bf Add required extensions and PHP version to composer.json 2020-12-20 12:13:13 +01:00
slawkens
d70b70b63c Update .editorconfig 2020-12-20 12:12:41 +01:00
slawkens
7d73e3cd98 Refactor code in delete_character.php 2020-12-19 23:25:46 +01:00
slawkens
5087fc4a00 You cannot delete character more than twice (Thanks Okke)
(cherry picked from commit 7fd784b2f6)
2020-11-24 18:12:49 +01:00
Lee
30cdb1ba73 Dashboard modules updated
More flexibility and additions on the dashboard modules.

-Statistics: Accounts, Players, Monsters, Guilds, Houses
-Website Status: Maintenance
-Server Status: name, client, map, monsters loaded, MOTD,

default:
'admin_panel_modules' => 'statistics,web_status,server_status,lastlogin,created,points,coins,balance',
2020-11-07 14:36:12 +00:00
Lee
0f6612904e Updated Admin
Updated the frameworks to latest git versions
-AdminLTE v3.1.0-pre
-Bootstrap v4.5.2
No major changes just bug fixes
2020-11-07 14:13:20 +00:00
Lee
e5b5b4d3ef Template update
Adds server name to the side menu, this hides when the side menu collapses.
2020-11-07 13:56:59 +00:00
Lee
9bc63bb55c Datatables update
I noticed if the datatables files wasn't cached some pages that didn't use it would take slightly longer to load whilst it downloaded it.
This will only write the js and css files onto the page if $use_datatable = true;  is set on the page.
See accounts/news/players pages for examples.

It wasn't a massive performance loss for the user but not needed if those pages are hardly ever used.
2020-11-07 13:53:11 +00:00
Lee
dcf83d5608 Update functions.php
Moved to bottom of the page so users can call functions code from custom_functions.
2020-11-06 14:42:13 +00:00
Lee
8fe82bb5c0 adminmenus update
moved visitors links to the logs section.
2020-11-06 14:20:34 +00:00
Lee
6f74029d76 Update spells.php
$canEdit was removed in a previous git.
Removing this fixes the error.
2020-11-06 14:18:08 +00:00
Lee
01e3d366ba Update admin.menus.js.html.twig
replaced del.png with a font awesome icon to go with the style of the rest of the icons on page.
2020-11-06 14:17:40 +00:00
Lee
41d5b4a22f Update basic.css
edited focus as browsers are displaying a thick black line. this is now a thing dotted outline.
2020-11-06 14:17:19 +00:00
Lee
7814636caf Added custom_functions file
Added a custom functions file for users to include any of their custom functions.
2020-11-06 14:16:54 +00:00
slawkens
cf2c5e36bc Feature/better highscores (#141)
* Move highscores to twig

* Add highscores frags for TFS 1.x

* Change $config to config()

* Cache highscores

The most asked and long awaited feature? :>

* Fix highscores_per_page and rename configurable

* Fix next page link (some typo)

* Fix too many players being shown

* Fix when changing config.highscores_per_page

* Update system/pages/highscores.php

Co-authored-by: whiteblXK <krzys16001@gmail.com>

Co-authored-by: whiteblXK <krzys16001@gmail.com>
2020-11-02 23:34:29 +01:00
slawkens
5d5875d540 Bans page working for TFS 1.x + move to Twig (#140)
* Bans page working for TFS 1.x + move to Twig

* Remove some debug code

* Add some protection

* Better check.
2020-10-30 06:52:50 +01:00
slawkens
95c2adc02e Remove twig, phpmailer & semver 2020-10-27 07:35:00 +01:00
slawkens
73f1ba10f9 Use composer for some libraries (twig, phpmailer, semver) 2020-10-27 07:34:05 +01:00
slawkens
9fe419cfe7 Creatures and monsters are now reloaded in Admin Panel 2020-10-27 07:33:21 +01:00
slawkens
41e24ca535 Remove .gz extension if found in map file 2020-10-27 07:25:38 +01:00
slawkens
42a628731d move characters link to twig 2020-10-27 07:24:21 +01:00
slawkens
2ba702df21 Update .editorconfig 2020-10-26 23:44:25 +01:00
slawkens
0171962306 SET @myaac_database_version in schema.sql 2020-10-24 05:40:58 +02:00
slawkens
2daa42e124 Add accept=".zip" to plugin upload file 2020-10-24 05:30:04 +02:00
slawkens
abfd2c94f5 Move template_header and change_template to twig 2020-10-18 06:54:54 +02:00
slawkens
fd51fa7779 Add some notice about recaptchas versions 2020-10-16 20:28:05 +02:00
slawkens
1a36aa8904 [WIP] New GoogleReCAPTCHA code
Support for v3
v2-invisible doesn't work yet
2020-10-15 19:55:12 +02:00
slawkens
881a28138a More compress .png 2020-10-15 08:09:40 +02:00
slawkens
26fb1698b8 Compress .png files (Almost 40% savings) 2020-10-15 07:59:48 +02:00
slawkens
13d7dd98bd Remove unused files 2020-10-15 07:53:24 +02:00
slawkens
672a9f1712 Remove unused files 2020-10-15 07:37:32 +02:00
slawkens
2e560ac081 Added some var annotations 2020-10-14 13:11:03 +02:00
slawkens
39d1127cf1 You can now disable status checking for testing purposes
Useful for local testing when there is no server running
2020-10-14 13:10:22 +02:00
slawkens
13586e664f config.status_timeout can be floating number 2020-10-14 13:08:39 +02:00
slawkens
6e6db543f7 Compress background-artwork.jpg (from 534 KB to 275 KB)
Without losing the quality
2020-10-14 13:07:46 +02:00
slawkens
ea8ae2372e This is better inline solution to not displaying Admin Menus
by @Leesneaks
2020-10-12 22:46:44 +02:00
slawkens
928de13459 Fix two boxes being show on email_change_cancel
(cherry picked from commit 8518afe70d)
2020-10-12 22:31:31 +02:00
slawkens
e213c3e7d8 Fix when adding poll = template tibiacom broken
With Exception and red message
2020-10-12 21:58:20 +02:00
slawkens
65b4b2d183 Rename file to admin.data.html.twig 2020-10-09 23:38:33 +02:00
slawkens
94b145b215 New class: DataLoader (loads data from server)
Also combined some code responsible for loading server data
2020-10-09 23:37:24 +02:00
slawkens
6c9e6af154 Move installer.js to main tools 2020-10-09 23:18:22 +02:00
slawkens
b5736ad559 Rename items.php to server data.php 2020-10-09 22:29:19 +02:00
slawkens
ab3912b378 Save towns as plain PHP File in cache folder
+ Also load them on install + on reload items
= better performance when in dev mode
2020-10-09 22:27:48 +02:00
slawkens
3090989dea Fixed accounts editor for OTServ, which dont have accounts.group_id 2020-10-09 00:37:28 +02:00
slawkens
92314b8dac Fix some PhpStorm editor error message 2020-10-09 00:36:47 +02:00
slawkens
a52396008d Automatically load towns from .OTBM file
Takes up to 10 seconds for otservbr on my PC
Taken from old Smart AAC - class SpawnsReader.php
2020-10-09 00:12:07 +02:00
slawkens
ae7350e3a0 Fix typo: length 2020-10-08 00:15:50 +02:00
slawkens
c30300c368 New configurable: item_images_extension 2020-10-08 00:13:35 +02:00
slawkens
ed3d415c05 Change wrong table header: Description -> Version 2020-10-08 00:03:53 +02:00
slawkens
bb353d617a Admin Panel: Show Mailer menu only if config.mail_enabled 2020-10-07 23:54:03 +02:00
slawkens
d7f41748ad Forgot to translate requirements 2020-10-07 23:46:14 +02:00
slawkens
915ae47971 Add missing polish timezone translation on install 2020-10-07 23:40:33 +02:00
slawkens
40b151b4c5 Remove whitespaces 2020-10-07 23:36:21 +02:00
slawkens
1992410a7b This info is useless 2020-10-07 23:36:10 +02:00
slawkens
48874f5b07 Disable mail_enabled by default on clean install
Causes too many issues when no smpt server available and other options are not configured
2020-10-07 23:22:02 +02:00
slawkens
2144a4eb7c Add success message on config.local.php save 2020-10-07 23:19:10 +02:00
slawkens
cbdbf11edc Remove config.local.php from optional dirs 2020-10-07 23:09:33 +02:00
slawkens
515db04023 Some changes in installation optional and required dirs
system/logs and system/cache are required to be writable

config.local.php, images/guilds and images/gallery are optionally writable, without them some feature will not work
2020-10-07 22:48:06 +02:00
slawkens
d3811f1bf1 Forgot to remove 2020-10-07 22:44:57 +02:00
slawkens
815fedf8e7 Add 'gd' as optional extension
Without it player signature will not work
2020-10-07 22:44:43 +02:00
slawkens
929a7b9cfa Add pdo_mysql as required extension
+ Some code refactoring
2020-10-07 22:43:17 +02:00
slawkens
f85361dbc5 Some optimisations in Plugins::installMenus 2020-09-25 07:49:26 +02:00
slawkens
cb6509d09d Cache for 365 days if $ttl not set 2020-09-25 07:26:30 +02:00
slawkens
f09c129c6d Remove duplicated line (in $db->select)
Caused some errors when using $db->select function (news editing for example)
2020-09-17 23:17:59 +02:00
slawkens
602a4aa835 Feature/experience stages twig (#135)
* Move Experience Stages to Twig

* Change name to underline (standard)

* Update system/pages/experiencestages.php

Co-authored-by: whiteblXK <krzys16001@gmail.com>

Co-authored-by: whiteblXK <krzys16001@gmail.com>
2020-08-24 19:36:43 +02:00
slawkens
14d5c6311b Update config.php 2020-07-14 01:05:21 +02:00
slawkens
289dd3c170 New configurable: guild_description_default 2020-07-14 01:05:09 +02:00
slawkens
60eac97945 Fix creating very uncommon (bugged) account names
(cherry picked from commit 0326657d60)
2020-07-07 01:23:53 +02:00
slawkens
de1d6b9629 Fix #131
(cherry picked from commit fcff820858)
2020-07-07 00:54:34 +02:00
whiteblXK
722264a083 Added limit to search characters (#134)
* Update characters.php

* Update config.php

* Variable name change, better use LIMIT in query instead in loop

* Just to be sure. Security first :)

* use config function

Co-authored-by: slawkens <slawkens@gmail.com>
(cherry picked from commit dc536f0fc0)
2020-07-07 00:54:29 +02:00
slawkens
357d487af7 Change hasTable -> hasColumn 2020-07-07 00:15:54 +02:00
whiteblXK
1b802b040d Fixed bug with showing hidden character
(cherry picked from commit f3061a0e74)
2020-07-07 00:02:33 +02:00
slawkens
25afbd935c Fix #132
(cherry picked from commit d4222e98e6)
2020-07-03 23:25:08 +02:00
slawkens
e61bfd2722 My fault (wrong email) forgot to change :P 2020-07-03 22:51:58 +02:00
slawkens
fe571cbef3 Fix account create when account_mail_verify is enabled 2020-07-03 22:43:53 +02:00
slawkens
a7c5cb8f5a Add some notice about Email validation 2020-07-03 22:15:04 +02:00
slawkens
dedb96ef4a Fix for CloudFlare IP detection
(cherry picked from commit b3b6d0ff5d)
2020-07-03 20:39:20 +02:00
slawkens
ee49efd215 This is better way of doing the check for blank & color 2020-06-26 23:47:14 +02:00
slawkens
56a35eb864 Fix network_twitter link in tibiacom template 2020-06-20 08:50:29 +02: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
d478fe0c71 Move $menus to menus.php
Also fix active link when menu item has subpage
2020-06-09 01:32:00 +02:00
slawkens
7b1aed7a94 Remove useless title_separator from config 2020-06-09 00:48:19 +02:00
slawkens
03467ea64e Update change_password email to be more informal 2020-06-06 19:51:17 +02:00
slawkens
3368fbd058 New config: account_mail_block_plus_sign
Block emails with '+' signs like test+box@gmail.com (help protect against spamming accounts)
2020-06-06 19:37:05 +02:00
slawkens
e84c6f7a24 Fix XSS in character search
(cherry picked from commit dfc70c098f)
2020-06-06 18:33:38 +02:00
slawkens
a0006bad73 CHANGELOG.md cleanup for 0.9.0 2020-06-06 18:05:10 +02:00
slawkens
2458393d22 Add Plugins::installMenus function 2020-06-06 17:33:34 +02:00
slawkens
787416e552 Remove useless title_separator from config 2020-06-06 17:15:55 +02:00
slawkens
1c6b241239 Add $limit parameter to $db->select method 2020-06-06 17:13:55 +02:00
slawkens
7469d520c9 Add $member var annotation 2020-06-06 17:13:51 +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
7e00e62427 Update version to 0.9.0-dev 2020-06-06 09:08:40 +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
0e39a969c3 Move register DATABASE_VERSION into schema.sql
Caused migrations being fired when user manually imported database
2020-06-06 07:33:05 +02:00
slawkens
0ad1647930 Remove unused myaac_videos table 2020-06-06 07:21:35 +02:00
slawkens
d7fc45a72d Very first version of admin bar 2020-06-06 07:17:09 +02:00
slawkens
54dfb642b1 Fix #123 Guild Invite not working on otservbr-global 2020-06-03 21:38:17 +02:00
slawkens
40626d0f42 Revert some change I did
Causing "'" and "-" being accepted as first character in player name
2020-06-03 21:22:14 +02:00
slawkens
523afccb51 Avoid ERR_TOO_MANY_REDIRECTS on template change 2020-06-03 20:01:26 +02:00
slawkens
1087aefe0a One more hook 2020-06-01 23:09:27 +02:00
slawkens
9b66edc148 Add some additional hooks to characters.html.twig 2020-06-01 22:41:32 +02:00
slawkens
2c09b0ae86 Fix #128 (Remove MyISAM engine) from migration scripts 2020-06-01 09:47:53 +02:00
slawkens
8de8ad13bf Fix message() function when executed in CLI 2020-06-01 08:39:13 +02:00
slawkens
70bd442bb0 Add new constant: IS_CLI
Also fixed some warnings when running in CLI mode
2020-06-01 08:34:11 +02:00
slawkens
5250b3189b Fix #126 (Max count and chance not shown) 2020-05-27 22:21:45 +02:00
slawkens
2534651e20 dummy me.. thanks @gerotib 2020-05-27 01:32:15 +02:00
Lee
f46a42023f Update admin.login.html.twig
- fix for label not ticking the box when remember me text clicked
2020-05-25 23:34:04 +01:00
Lee
e2ab301340 Update version.php
- removed extra line that is added when using a newer version than official release.
2020-05-25 23:33:06 +01:00
slawkens
700f835243 Fix #125 (wrong mana of character samples)
Should be 90.
2020-05-26 00:15:28 +02:00
slawkens
9ce7162a04 Remove duplicated code 2020-05-25 09:03:40 +02:00
slawkens
af85a8b711 Display "Unknown Town" when town not found 2020-05-25 00:15:30 +02:00
slawkens
cd58008a0f Rewrite towns support for TFS 1.3
Won't show warning anymore
2020-05-25 00:09:06 +02:00
slawkens
1f6bd975d0 Add error_reporting in admin panel
Same as in main page
2020-05-25 00:04:41 +02:00
slawkens
b3556c008e Add note which template menus are being edited 2020-05-24 19:34:48 +02:00
slawkens
dbe83f8a74 Move migration into separate file + add into admin panel
This fixes some rare bugs when database is no up-to-date and someone enters admin panel
2020-05-24 18:43:26 +02:00
Lee
d1c50f00a0 Admin template update
- Reformatted with short array syntax.
- Removed duplicate menu item
- Removed 'menu' from array - use 'link' as the array or link.
- Added logo
2020-05-23 03:03:15 +01:00
Lee
bd9d3154db Code cleanup
-Removed unneeded/duplicate dependency files.
2020-05-23 02:54:58 +01:00
Lee
1f0b4425a4 Code cleanup
- Relocated html5shiv.js (v3.7.3) and respond.js (v1.4.2)
- Removed unneeded/duplicate dependency files.
2020-05-23 02:47:12 +01:00
Lee
47bfea4c56 Dependency Update
Updated:
- AdminLTE (v3.0.4)
- Bootstrap (v4.4.1)
- DataTables (v1.10.21)
-- Split DataTables for admin pages and website to fix layout formatting issues.
2020-05-23 02:28:38 +01: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
slawkens
416de6b584 Update admin.items.html.twig 2020-05-14 23:16:05 +02:00
Lee
3d3d141b25 bootstrap JS fix
-fixes the editor tabs etc not working
2020-05-10 18:11:38 +01:00
slawkens
2ff56c17e3 Added some fancy spinner to items loader 2020-05-10 12:39:06 +02:00
slawkens
fb326d0354 Change input type of account_login to text
This fixes autofill by Chrome and other tools
2020-05-10 11:45:55 +02:00
slawkens
e84933cf26 Ignore index.html in logs viewer 2020-05-10 11:45:04 +02:00
slawkens
8e04328482 Add executing missing migration on install
This fixes missing rules on clean install
2020-05-09 14:07:53 +02:00
slawkens
d148b71f0f Fixes in create new character nick
+ fixed config.character_name_min/max_length being ignored in change_name.php
2020-05-09 14:07:53 +02:00
Lee
4e68838172 CreateChar Fix
-checks if name has double space on create character (#121)
2020-05-07 19:09:56 +01:00
Lee
d281fc588b Fixes
-As requested the datatables and bootstrap files have been moved into the tools folder
-Fixed spells and creatures datatable.
-Double space in name fix.
2020-05-07 01:36:56 +01:00
slawkens
1799ef42a7 Add system/data to .gitignore 2020-05-06 19:55:31 +02:00
slawkens
a0d5a863e0 Remove useless tabbing
Just removed tabs, nothing else..
2020-05-01 13:03:34 +02:00
slawkens
df59b104db Fix cancel change email request
Thanks to OtLand user anyeor
2020-04-21 00:22:50 +02:00
slawkens
e7e327c238 Fix some small typos on admin.menus 2020-04-20 23:31:06 +02:00
slawkens
ee6e68d0bf Fix exception when characters.frags enabled on TFS 1.x 2020-04-20 22:35:41 +02:00
Lee
d7333b3f21 Update accounts.php
Fix for accounts.php type not found.
2020-04-06 15:08:52 +01:00
Lee
375bd58a0c Admin Update
-Account limit fix
-Player editor full player table.
2020-04-02 20:54:20 +01:00
Lee
cddd915adf Admin fixes
-login/logout error fix
-debugging code removed
2020-04-02 18:44:15 +01:00
Lee
9e0ad271f6 Update adminlte.min.css
case sensitive fix
2020-04-02 15:54:16 +01:00
Lee
a0afeb2a7a Update accounts.php
-Bans table error
-Fix for #114
2020-04-02 14:52:38 +01:00
slawkens
7c208b38ed Add example quest 2020-04-02 15:26:39 +02:00
Lee
eaa11c68f3 Admin Panel Updates
- Updated Admin Panel to Bootstrap 4.
- Code cleanup
- Rewrote menu generation code
- Added top 10 coins, top 10 premium points, last 10 logins to modules page.
- Added full account list to Account editor
- Added load outfits from XML to player editor and lists all enabled outfits in editor (will default to textbox if array of outfits do not exist)
- Added tabs to account editor - account, characters,store history, bans(this is based off the bans.php page so will not work on TFS 0.2/1.0)
- Updated datepickers to display the actual date rather than unix time.
- Added last 10 posts to player editor
2020-03-31 02:03:16 +01:00
1093 changed files with 27721 additions and 56352 deletions

View File

@@ -11,4 +11,9 @@ insert_final_newline = true
[*.md] [*.md]
trim_trailing_whitespace = false trim_trailing_whitespace = false
indent_style = tab
[{composer.json,package.json}]
indent_style = space
[package.json]
indent_size = 2

7
.gitattributes vendored
View File

@@ -3,9 +3,12 @@
.gitignore export-ignore .gitignore export-ignore
.github export-ignore .github export-ignore
.editorconfig export-ignore .editorconfig export-ignore
.travis.yml export-ignore
_config.yml export-ignore _config.yml export-ignore
release.sh export-ignore release.sh export-ignore
# cypress
cypress export-ignore
cypress.config.js export-ignore
cypress.env.json
*.sh text eol=lf *.sh text eol=lf
VERSION text eol=lf

120
.github/workflows/cypress.yml vendored Normal file
View File

@@ -0,0 +1,120 @@
name: Cypress
on:
pull_request:
branches: [develop]
push:
branches: [develop]
jobs:
cypress:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: myaac
MYSQL_USER: myaac
MYSQL_PASSWORD: myaac
ports:
- 3306/tcp
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
fail-fast: false
matrix:
php-versions: [ '7.4', '8.0', '8.1' ]
name: MyAAC on PHP ${{ matrix.php-versions }}
steps:
- name: 📌 MySQL Start & init & show db
run: |
sudo /etc/init.d/mysql start
mysql -e 'CREATE DATABASE myaac;' -uroot -proot
mysql -e "SHOW DATABASES" -uroot -proot
- name: Checkout MyAAC
uses: actions/checkout@v3
with:
ref: 0.9
- name: Checkout TFS
uses: actions/checkout@v3
with:
repository: otland/forgottenserver
ref: 1.4
path: tfs
- name: Import TFS Schema
run: |
mysql -uroot -proot myaac < tfs/schema.sql
- name: Rename config.lua
run: mv tfs/config.lua.dist tfs/config.lua
- name: Replace mysqlUser
uses: jacobtomlinson/gha-find-replace@v2
with:
find: 'mysqlUser = "forgottenserver"'
replace: 'mysqlUser = "root"'
regex: false
include: 'tfs/config.lua'
- name: Replace mysqlPass
uses: jacobtomlinson/gha-find-replace@v2
with:
find: 'mysqlPass = ""'
replace: 'mysqlPass = "root"'
regex: false
include: 'tfs/config.lua'
- name: Replace mysqlDatabase
uses: jacobtomlinson/gha-find-replace@v2
with:
find: 'mysqlDatabase = "forgottenserver"'
replace: 'mysqlDatabase = "myaac"'
regex: false
include: 'tfs/config.lua'
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: mbstring, dom, fileinfo, mysql, json, xml, pdo, pdo_mysql
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
# Use composer.json for key, if composer.lock is not committed.
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install Composer dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader
- name: Run PHP server
run: nohup php -S localhost:8080 > php.log 2>&1 &
- name: Cypress Run
uses: cypress-io/github-action@v5
env:
CYPRESS_URL: http://localhost:8080
CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/tfs
- name: Save screenshots
uses: actions/upload-artifact@v3
if: always()
with:
name: cypress-screenshots
path: cypress/screenshots
- name: Upload Cypress Videos
uses: actions/upload-artifact@v3
if: always()
with:
name: cypress-videos
path: cypress/videos

View File

@@ -1,16 +1,16 @@
name: PHP Linting name: PHP Linting
on: on:
pull_request: pull_request:
branches: [master] branches: [develop]
push: push:
branches: [master] branches: [develop]
jobs: jobs:
phplint: phplint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: overtrue/phplint@3.4.0 - uses: overtrue/phplint@8.2
with: with:
path: . path: .
options: --exclude="system/libs/polyfill-mbstring/bootstrap80.php" options: --exclude=*.log

19
.gitignore vendored
View File

@@ -11,12 +11,10 @@ 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
@@ -37,12 +35,6 @@ 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
@@ -50,10 +42,6 @@ system/cache/*
!system/cache/signatures/index.html !system/cache/signatures/index.html
!system/cache/plugins/index.html !system/cache/plugins/index.html
# php sessions
system/php_sessions/*
!system/php_sessions/index.html
# logs # logs
system/logs/* system/logs/*
!system/logs/index.html !system/logs/index.html
@@ -62,6 +50,10 @@ system/logs/*
system/data/* system/data/*
!system/data/index.html !system/data/index.html
# php sessions
system/php_sessions/*
!system/php_sessions/index.html
# plugins # plugins
plugins/* plugins/*
!plugins/.htaccess !plugins/.htaccess
@@ -72,5 +64,8 @@ plugins/*
!plugins/email-confirmed-reward !plugins/email-confirmed-reward
landing landing
# system
system/functions_custom.php
# others/rest # others/rest
system/pages/downloads.php system/pages/downloads.php

View File

@@ -6,11 +6,13 @@
Options -MultiViews Options -MultiViews
</IfModule> </IfModule>
<FilesMatch "^(CHANGELOG\.md|README\.md|composer\.json|composer\.lock|package\.json|package-lock\.json|cypress\.env\.json)$">
Require all denied
</FilesMatch>
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine On RewriteEngine On
# you can put here your myaac root folder
# path relative to web root
#RewriteBase /myaac/ #RewriteBase /myaac/
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f

View File

@@ -1,20 +0,0 @@
language: php
php:
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
- 7.4
- 8.0
cache:
directories:
- $HOME/.composer/cache
before_script:
- composer require php-parallel-lint/php-parallel-lint --no-suggest --no-progress --no-interaction --no-ansi --quiet --optimize-autoloader
script:
- php vendor/bin/parallel-lint --no-progress --no-colors --exclude vendor --exclude "system/libs/pot/OTS_DB_PDOQuery_PHP71.php" .

File diff suppressed because it is too large Load Diff

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
@@ -79,12 +73,6 @@ Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our w
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
This program and all associated files are released under the GNU Public License. This program and all associated files are released under the GNU Public License.

View File

@@ -1,16 +0,0 @@
# Security Policy
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 1.x.y | :white_check_mark: |
| 0.9.x | :x: |
| 0.8.x | :white_check_mark: |
| < 0.7 | :x: |
## Reporting a Vulnerability
If you found a security vulnerability, please write an email to security@my-aac.org
All reports will be taken very seriously, and a fix will be posted as soon as possible.

BIN
admin/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,35 @@
<?php
$order = 10;
$settingsMenu = [];
$settingsMenu[] = [
'name' => 'MyAAC',
'link' => 'settings&plugin=core',
'icon' => 'list',
'order' => $order,
];
foreach (Plugins::getAllPluginsSettings() as $setting) {
$file = BASE . $setting['settingsFilename'];
if (!file_exists($file)) {
warning('Plugin setting: ' . $file . ' - cannot be loaded.');
continue;
}
$order += 10;
$settings = require $file;
$settingsMenu[] = [
'name' => $settings['name'],
'link' => 'settings&plugin=' . $setting['pluginFilename'],
'icon' => 'list',
'order' => $order,
];
}
unset($settings, $file, $order);
return $settingsMenu;

View File

@@ -1,13 +1,10 @@
<?php <?php
// few things we'll need // few things we'll need
require '../common.php'; require '../common.php';
define('ADMIN_PANEL', true); const ADMIN_PANEL = true;
define('MYAAC_ADMIN', true); const MYAAC_ADMIN = true;
if(file_exists(BASE . 'config.local.php')) {
require_once BASE . 'config.local.php';
}
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed'])) if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
{ {
@@ -18,8 +15,8 @@ if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['i
$content = ''; $content = '';
// validate page // validate page
$page = isset($_GET['p']) ? $_GET['p'] : ''; $page = $_GET['p'] ?? '';
if(empty($page) || preg_match("/[^a-zA-Z0-9_\-]/", $page)) if(empty($page) || preg_match("/[^a-zA-Z0-9_\-\/.]/", $page))
$page = 'dashboard'; $page = 'dashboard';
$page = strtolower($page); $page = strtolower($page);
@@ -28,10 +25,9 @@ define('PAGE', $page);
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';
if(config('env') === 'dev') { // verify myaac tables exists in database
ini_set('display_errors', 1); if(!$db->hasTable('myaac_account_actions')) {
ini_set('display_startup_errors', 1); 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.');
error_reporting(E_ALL);
} }
// event system // event system
@@ -41,31 +37,40 @@ $hooks->load();
require SYSTEM . 'status.php'; require SYSTEM . 'status.php';
require SYSTEM . 'login.php'; require SYSTEM . 'login.php';
require SYSTEM . 'migrate.php'; require __DIR__ . '/includes/functions.php';
require ADMIN . 'includes/functions.php';
$twig->addGlobal('config', $config); $twig->addGlobal('config', $config);
$twig->addGlobal('status', $status); $twig->addGlobal('status', $status);
if (ACTION == 'logout') {
require SYSTEM . 'logout.php';
}
// if we're not logged in - show login box // if we're not logged in - show login box
if(!$logged || !admin()) { if(!$logged || !admin()) {
$page = 'login'; $page = 'login';
} }
// include our page // include our page
$file = ADMIN . 'pages/' . $page . '.php'; $file = __DIR__ . '/pages/' . $page . '.php';
if(!@file_exists($file)) { if(!@file_exists($file)) {
if (strpos($page, 'plugins/') !== false) {
$file = BASE . $page;
}
else {
$page = '404'; $page = '404';
$file = SYSTEM . 'pages/404.php'; $file = SYSTEM . 'pages/404.php';
} }
}
ob_start(); ob_start();
include($file); if($hooks->trigger(HOOK_ADMIN_BEFORE_PAGE)) {
require $file;
}
$content .= ob_get_contents(); $content .= ob_get_contents();
ob_end_clean(); ob_end_clean();
// template // template
$template_path = 'template/'; $template_path = 'template/';
require ADMIN . $template_path . 'template.php'; require __DIR__ . '/' . $template_path . 'template.php';

View File

@@ -4,37 +4,21 @@
* *
* @package MyAAC * @package MyAAC
* @author Lee * @author Lee
* @copyright 2019 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Account editor'; $title = 'Account editor';
$base = BASE_URL . 'admin/?p=accounts'; $admin_base = ADMIN_URL . '?p=accounts';
$use_datatable = true;
if ($config['account_country']) if ($config['account_country'])
require SYSTEM . 'countries.conf.php'; require SYSTEM . 'countries.conf.php';
function echo_success($message) $nameOrNumberColumn = 'name';
{ if (USE_ACCOUNT_NUMBER) {
echo '<p class="success">' . $message . '</p>'; $nameOrNumberColumn = 'number';
}
function echo_error($message)
{
global $error;
echo '<p class="error">' . $message . '</p>';
$error = true;
}
function verify_number($number, $name, $max_length)
{
if (!Validator::number($number))
echo_error($name . ' can contain only numbers.');
$number_length = strlen($number);
if ($number_length <= 0 || $number_length > $max_length)
echo_error($name . ' cannot be longer than ' . $max_length . ' digits.');
} }
$hasSecretColumn = $db->hasColumn('accounts', 'secret'); $hasSecretColumn = $db->hasColumn('accounts', 'secret');
@@ -52,6 +36,8 @@ if ($config['account_country']) {
foreach ($config['countries'] as $code => $c) foreach ($config['countries'] as $code => $c)
$countries[$code] = $c; $countries[$code] = $c;
} }
$web_acc = ACCOUNT_WEB_FLAGS;
$acc_type = setting('core.account_types');
?> ?>
<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ > <link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ >
@@ -59,38 +45,41 @@ if ($config['account_country']) {
<?php <?php
$id = 0; $id = 0;
$search_account = '';
if (isset($_REQUEST['id'])) if (isset($_REQUEST['id']))
$id = (int)$_REQUEST['id']; $id = (int)$_REQUEST['id'];
else if (isset($_REQUEST['search_name'])) { else if (isset($_REQUEST['search'])) {
if (strlen($_REQUEST['search_name']) < 3 && !Validator::number($_REQUEST['search_name'])) { $search_account = $_REQUEST['search'];
echo 'Player name is too short.'; if (strlen($search_account) < 3 && !Validator::number($search_account)) {
echo_error('Player name is too short.');
} else { } else {
if (Validator::number($_REQUEST['search_name'])) $query = $db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $db->quote($search_account));
$id = $_REQUEST['search_name'];
else {
$query = $db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $db->quote($_REQUEST['search_name']));
if ($query->rowCount() == 1) { if ($query->rowCount() == 1) {
$query = $query->fetch(); $query = $query->fetch();
$id = $query['id']; $id = (int)$query['id'];
} else { } else {
$query = $db->query('SELECT `id`, `name` FROM `accounts` WHERE `name` LIKE ' . $db->quote('%' . $_REQUEST['search_name'] . '%')); $query = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` LIKE ' . $db->quote('%' . $search_account . '%'));
if ($query->rowCount() > 0 && $query->rowCount() <= 10) { if ($query->rowCount() > 0 && $query->rowCount() <= 10) {
echo 'Do you mean?<ul>'; $str_construct = 'Do you mean?<ul class="mb-0">';
foreach ($query as $row) foreach ($query as $row)
echo '<li><a href="' . $base . '&id=' . $row['id'] . '">' . $row['name'] . '</a></li>'; $str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row[$nameOrNumberColumn] . '</a></li>';
echo '</ul>'; $str_construct .= '</ul>';
echo_error($str_construct);
} else if ($query->rowCount() > 10) } else if ($query->rowCount() > 10)
echo 'Specified name resulted with too many accounts.'; echo_error('Specified name resulted with too many accounts.');
else
echo_error('No entries found.');
} }
} }
} }
} ?>
$groups = new OTS_Groups_List(); <div class="row">
<?php
if ($id > 0) { if ($id > 0) {
$account = new OTS_Account(); $account = new OTS_Account();
$account->load($id); $account->load($id);
if (isset($account, $_POST['save']) && $account->isLoaded()) {// we want to save if (isset($account, $_POST['save']) && $account->isLoaded()) {
$error = false; $error = false;
$_error = ''; $_error = '';
@@ -154,14 +143,14 @@ if ($id > 0) {
verify_number($web_flags, 'Web Flags', 1); verify_number($web_flags, 'Web Flags', 1);
//created //created
$created = $_POST['created']; $created = strtotime($_POST['created']);
verify_number($created, 'Created', 11); verify_number($created, 'Created', 11);
//web last login //web last login
$web_lastlogin = $_POST['web_lastlogin']; $web_lastlogin = strtotime($_POST['web_lastlogin']);
verify_number($web_lastlogin, 'Web Last logout', 11); verify_number($web_lastlogin, 'Web Last login', 11);
if (!$error) { if (!$error && $hooks->trigger(HOOK_ADMIN_ACCOUNTS_SAVE_POST, ['account_id' => $account->getId(), 'account_email' => $account->getEMail()])) {
if (USE_ACCOUNT_NAME) { if (USE_ACCOUNT_NAME) {
$account->setName($name); $account->setName($name);
} }
@@ -201,17 +190,16 @@ if ($id > 0) {
$account->setCustomField('web_lastlogin', $web_lastlogin); $account->setCustomField('web_lastlogin', $web_lastlogin);
if (isset($password)) { if (isset($password)) {
$config_salt_enabled = $db->hasColumn('accounts', 'salt'); if (USE_ACCOUNT_SALT) {
if ($config_salt_enabled) {
$salt = generateRandomString(10, false, true, true); $salt = generateRandomString(10, false, true, true);
$password = $salt . $password; $password = $salt . $password;
$account_logged->setCustomField('salt', $salt); $account->setCustomField('salt', $salt);
} }
$password = encrypt($password); $password = encrypt($password);
$account->setPassword($password); $account->setPassword($password);
if ($config_salt_enabled) if (USE_ACCOUNT_SALT)
$account->setCustomField('salt', $salt); $account->setCustomField('salt', $salt);
} }
@@ -219,165 +207,195 @@ if ($id > 0) {
echo_success('Account saved at: ' . date('G:i')); echo_success('Account saved at: ' . date('G:i'));
} }
} }
} } else if ($id == 0) {
$accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC');
$search_account = '';
if (isset($_REQUEST['search_name']))
$search_account = $_REQUEST['search_name'];
else if (isset($_REQUEST['search_account']))
$search_account = $_REQUEST['search_account'];
else if ($id > 0 && isset($account) && $account->isLoaded()) {
if(USE_ACCOUNT_NAME) {
$search_account = $account->getName();
}
else {
$search_account = $account->getId();
}
}
?> ?>
<div class="row"> <div class="col-12 col-sm-12 col-lg-10">
<?php if (isset($account) && $account->isLoaded()) { ?> <div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0">Accounts</h5>
</div>
<div class="card-body">
<table class="acc_datatable table table-striped table-bordered table-responsive d-md-table">
<thead>
<tr>
<th>ID</th>
<th><?= ($nameOrNumberColumn == 'number' ? 'Number' : 'Name'); ?></th>
<?php if($hasTypeColumn || $hasGroupColumn): ?>
<th>Position</th>
<?php endif; ?>
<th style="width: 40px">Edit</th>
</tr>
</thead>
<tbody>
<?php foreach ($accounts_db as $account_lst): ?>
<tr>
<th><?php echo $account_lst['id']; ?></th>
<td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td>
<?php if($hasTypeColumn || $hasGroupColumn): ?>
<td>
<?php if ($hasTypeColumn) {
echo $acc_type[$account_lst['type']];
} elseif ($hasGroupColumn) {
$group = $groups->getGroups();
echo $group[$account_lst['group_id']];
} ?>
</td>
<?php endif; ?>
<td><a href="?p=accounts&id=<?php echo $account_lst['id']; ?>" class="btn btn-success btn-sm" title="Edit">
<i class="fas fa-pencil-alt"></i>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>
<form action="<?php echo $base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post" <?php if (isset($account) && $account->isLoaded()) { ?>
class="form-horizontal"> <div class="col-12 col-sm-12 col-lg-10">
<div class="col-md-8"> <div class="card card-primary card-outline card-outline-tabs">
<div class="box box-primary"> <div class="card-header p-0 border-bottom-0">
<div class="box-body"> <ul class="nav nav-tabs" id="accounts-tab" role="tablist">
<div class="row"> <li class="nav-item">
<a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a>
</li>
<li class="nav-item">
<a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a>
</li>
<?php if ($db->hasTable('bans')) : ?>
<li class="nav-item">
<a class="nav-link" id="accounts-bans-tab" data-toggle="pill" href="#accounts-bans">Bans</a>
</li>
<?php endif;
if ($db->hasTable('store_history')) : ?>
<li class="nav-item">
<a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a>
</li>
<?php endif; ?>
</ul>
</div>
<div class="card-body">
<div class="tab-content" id="accounts-tabContent">
<div class="tab-pane fade active show" id="accounts-acc">
<form action="<?php echo $admin_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post">
<div class="form-group row">
<?php if (USE_ACCOUNT_NAME): ?> <?php if (USE_ACCOUNT_NAME): ?>
<div class="col-xs-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="name" class="control-label">Account Name:</label> <label for="name">Account Name:</label>
<input type="text" class="form-control" id="name" name="name" <input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getName(); ?>"/>
autocomplete="off" style="cursor: auto;" </div>
value="<?php echo $account->getName(); ?>"/> <?php elseif (USE_ACCOUNT_NUMBER): ?>
<div class="col-12 col-sm-12 col-lg-4">
<label for="name">Account Number:</label>
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getNumber(); ?>"/>
</div> </div>
<?php endif; ?> <?php endif; ?>
<div class="col-xs-5"> <div class="col-12 col-sm-12 col-lg-5">
<label for="c_pass" class="control-label">Password: (check to change)</label> <div class="form-check">
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox" <input type="checkbox"
name="c_pass" name="c_pass"
id="c_pass" id="c_pass"
value="false" value="false"
class="input_control"/> class="form-check-input"/>
</span> <label for="c_pass">Password: (check to change)</label>
<input type="text" class="form-control" id="pass" name="pass" </div>
autocomplete="off" maxlength="20" <div class="input-group">
value=""/> <input type="text" class="form-control" id="pass" name="pass" autocomplete="off" maxlength="20" value=""/>
</div> </div>
</div> </div>
<div class="col-xs-3"> <div class="col-12 col-sm-12 col-lg-3">
<label for="account_id" class="control-label">Account ID:</label> <label for="account_id" class="control-label">Account ID:</label>
<input type="text" class="form-control" id="account_id" name="account_id" <input type="text" class="form-control" id="account_id" name="account_id" autocomplete="off" size="8" maxlength="11" disabled value="<?php echo $account->getId(); ?>"/>
autocomplete="off" style="cursor: auto;" size="8" maxlength="11" disabled
value="<?php echo $account->getId(); ?>"/>
</div> </div>
</div> </div>
<div class="row"> <div class="form-group row">
<?php <?php
$acc_group = $account->getAccGroupId(); $acc_group = $account->getAccGroupId();
if ($hasTypeColumn) { if ($hasTypeColumn) {
$groups = new OTS_Groups_List();
$acc_type = array("Normal", "Tutor", "Senior Tutor", "Gamemaster", "God");
if ($groups->getHighestId() == 6) {
$acc_type = array("Normal", "Tutor", "Senior Tutor", "Gamemaster", "Community Manager", "God");
}
?> ?>
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group" class="control-label">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 + 1); ?>" <?php echo($acc_group == ($id + 1) ? '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>
<?php <?php
} elseif ($hasGroupColumn) { } elseif ($hasGroupColumn) {
?> ?>
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group" class="control-label">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 <?php foreach ($groups->getGroups() as $id => $group): ?>
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>
<?php } ?> <?php } ?>
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="web_flags" class="control-label">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 $web_acc = array("None", "Admin", "Super Admin", "(Admin + Super Admin)"); <?php foreach ($web_acc as $id => $a_type): ?>
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>
</div> </div>
<div class="row"> <div class="form-group row">
<?php if ($hasSecretColumn): ?> <?php if ($hasSecretColumn): ?>
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="secret" class="control-label">Secret:</label> <label for="secret">Secret:</label>
<input type="text" class="form-control" id="secret" name="secret" <input type="text" class="form-control" id="secret" name="secret" autocomplete="off" value="<?php echo $account->getCustomField('secret'); ?>"/>
autocomplete="off" style="cursor: auto;" size="8" maxlength="11"
value="<?php echo $account->getCustomField('secret'); ?>"/>
</div> </div>
<?php endif; ?> <?php endif; ?>
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="key" class="control-label">Key:</label> <label for="key">Recovery Key:</label>
<input type="text" class="form-control" id="key" name="key" <input type="text" class="form-control" id="key" name="key" autocomplete="off" value="<?php echo $account->getCustomField('key'); ?>"/>
autocomplete="off" style="cursor: auto;" size="8" maxlength="11"
value="<?php echo $account->getCustomField('key'); ?>"/>
</div> </div>
</div> </div>
<div class="row"> <div class="form-group row">
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="email" class="control-label">Email:</label> <label for="email">Email:</label><?php echo (setting('core.mail_enabled') ? ' (<a href="' . ADMIN_URL . '?p=mailer&mail_to=' . $account->getEMail() . '">Send Mail</a>)' : ''); ?>
<input type="text" class="form-control" id="email" name="email" <input type="text" class="form-control" id="email" name="email" autocomplete="off" value="<?php echo $account->getEMail(); ?>"/>
autocomplete="off" maxlength="20"
value="<?php echo $account->getEMail(); ?>"/>
</div> </div>
<?php if ($hasCoinsColumn): ?> <?php if ($hasCoinsColumn): ?>
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="t_coins" class="control-label">Tibia Coins:</label> <label for="t_coins">Tibia Coins:</label>
<input type="text" class="form-control" id="t_coins" name="t_coins" <input type="text" class="form-control" id="t_coins" name="t_coins" autocomplete="off" maxlength="11" value="<?php echo $account->getCustomField('coins') ?>"/>
autocomplete="off" maxlength="8"
value="<?php echo $account->getCustomField('coins') ?>"/>
</div> </div>
<?php endif; ?> <?php endif; ?>
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="p_days" class="control-label">Premium Days:</label> <label for="p_days">Premium Days:</label>
<input type="text" class="form-control" id="p_days" name="p_days" <input type="text" class="form-control" id="p_days" name="p_days" autocomplete="off" maxlength="11" value="<?php echo $account->getPremDays(); ?>"/>
autocomplete="off" maxlength="11"
value="<?php echo $account->getPremDays(); ?>"/>
</div> </div>
<?php if ($hasPointsColumn): ?> <?php if ($hasPointsColumn): ?>
<div class="col-xs-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="p_points" class="control-label">Premium Points:</label> <label for="p_points" class="control-label">Premium Points:</label>
<input type="text" class="form-control" id="p_points" name="p_points" <input type="text" class="form-control" id="p_points" name="p_points" autocomplete="off" maxlength="8" value="<?php echo $account->getCustomField('premium_points') ?>"/>
autocomplete="off" maxlength="8"
value="<?php echo $account->getCustomField('premium_points') ?>"/>
</div> </div>
<?php endif; ?> <?php endif; ?>
</div> </div>
<div class="row"> <div class="form-group row">
<div class="col-xs-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="rl_name" class="control-label">RL Name:</label> <label for="rl_name">RL Name:</label>
<input type="text" class="form-control" id="rl_name" name="rl_name" <input type="text" class="form-control" id="rl_name" name="rl_name"
autocomplete="off" maxlength="20" autocomplete="off" maxlength="20"
value="<?php echo $account->getRLName(); ?>"/> value="<?php echo $account->getRLName(); ?>"/>
</div> </div>
<div class="col-xs-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="rl_loca" class="control-label">Location:</label> <label for="rl_loca">Location:</label>
<input type="text" class="form-control" id="rl_loca" name="rl_loca" <input type="text" class="form-control" id="rl_loca" name="rl_loca"
autocomplete="off" maxlength="20" autocomplete="off" maxlength="20"
value="<?php echo $account->getLocation(); ?>"/> value="<?php echo $account->getLocation(); ?>"/>
</div> </div>
<div class="col-xs-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="rl_country" class="control-label">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>
@@ -385,106 +403,197 @@ else if ($id > 0 && isset($account) && $account->isLoaded()) {
</select> </select>
</div> </div>
</div> </div>
<div class="row"> <div class="form-group row">
<div class="col-xs-4"> <div class="col-12 col-sm-12 col-lg-6">
<label for="created" class="control-label">Created:</label> <label for="created" class="control-label">Created:</label>
<input type="text" class="form-control" id="created" name="created" <input type="text" class="form-control" id="created" name="created" autocomplete="off" maxlength="20" value="<?php echo date("M d Y, H:i:s", $account->getCustomField('created')); ?>"/>
autocomplete="off" maxlength="20"
value="<?php echo $account->getCustomField('created'); ?>"/>
</div> </div>
<div class="col-xs-4"> <div class="col-12 col-sm-12 col-lg-6">
<label for="web_lastlogin" class="control-label">Web Last Login:</label> <label for="web_lastlogin" class="control-label">Web Last Login:</label>
<input type="text" class="form-control" id="web_lastlogin" name="web_lastlogin" <input type="text" class="form-control" id="web_lastlogin" name="web_lastlogin" autocomplete="off" maxlength="20" value="<?php echo date("M d Y, H:i:s", $account->getCustomField('web_lastlogin')); ?>"/>
autocomplete="off" maxlength="20"
value="<?php echo $account->getCustomField('web_lastlogin'); ?>"/>
</div> </div>
</div> </div>
<input type="hidden" name="save" value="yes"/> <input type="hidden" name="save" value="yes"/>
<div class="box-footer">
<a href="<?php echo ADMIN_URL; ?>?p=accounts"><span class="btn btn-danger">Cancel</span></a>
<div class="pull-right">
<input type="submit" class="btn btn-primary" value="Update">
</div>
</div>
</div> <button type="submit" class="btn btn-info"><i class="fas fa-update"></i> Update</button>
</div> <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>
<?php } ?> <div class="tab-pane fade" id="accounts-chars">
<div class="col-md-4"> <div class="row">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Search Account:</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
</div>
</div>
<div class="box-body">
<form action="<?php echo $base; ?>" method="post">
<div class="input-group input-group-sm">
<input type="text" class="form-control" name="search_name" value="<?php echo escapeHtml($search_account); ?>"
maxlength="32" size="32">
<span class="input-group-btn">
<button type="submit" type="button" class="btn btn-info btn-flat">Search</button>
</span>
</div>
</form>
</div>
</div>
<?php <?php
if (isset($account) && $account->isLoaded()) { if (isset($account) && $account->isLoaded()) {
$account_players = array(); $account_players = $account->getPlayersList();
$query = $db->query('SELECT `name`,`level`,`vocation` FROM `players` WHERE `account_id` = ' . $account->getId() . ' ORDER BY `name`')->fetchAll(); $account_players->orderBy('id');
if (isset($query)) { if (isset($account_players)) { ?>
?> <table class="table table-striped table-condensed table-responsive d-md-table">
<div class="box"> <thead>
<div class="box-header">
<h3 class="box-title">Character List:</h3>
</div>
<div class="box-body no-padding">
<table class="table table-striped">
<tbody>
<tr> <tr>
<th style="width: 10px">#</th> <th>#</th>
<th>Name</th> <th>Name</th>
<th>Level</th> <th>Level</th>
<th>Vocation</th>
<th style="width: 40px">Edit</th> <th style="width: 40px">Edit</th>
</tr> </tr>
<?php </thead>
$i = 1; <tbody>
foreach ($query as $p) { <?php $i= 0;
$account_players[] = $p; foreach ($account_players as $i => $player):
echo '<tr>
<td>' . $i . '.</td>
<td>' . $p['name'] . '</td>
<td>' . $p['level'] . '</td>
<td><a href="?p=players&search_name=' . $p['name'] . '"><span class="btn btn-success btn-sm edit btn-flat"><i class="fa fa-edit"></i></span></a></span></td>
</tr>';
$i++; $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>
<th><?php echo $i; ?></th>
<td><?php echo $player->getName(); ?></td>
<td><?php echo $player->getLevel(); ?></td>
<td><?php echo $vocation_name; ?></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>
<?php endforeach ?>
</tbody>
</table>
<?php
}
} ?>
</div>
</div>
<?php if ($db->hasTable('bans')) : ?>
<div class="tab-pane fade" id="accounts-bans">
<?php
$bans = $db->query('SELECT * FROM ' . $db->tableName('bans') . ' WHERE ' . $db->fieldName('active') . ' = 1 AND ' . $db->fieldName('id') . ' = ' . $account->getId() . ' ORDER BY ' . $db->fieldName('added') . ' DESC LIMIT 10');
if ($bans->rowCount()) {
?>
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
<tr>
<th>Nick</th>
<th>Type</th>
<th>Expires</th>
<th>Reason</th>
<th>Comment</th>
<th>Added by:</th>
</tr>
</thead>
<tbody>
<?php
foreach ($bans as $ban) {
?>
<tr>
<td><?php
$pName = getPlayerNameByAccount($ban['value']);
echo '<a href="?p=players&search=' . $pName . '">' . $pName . '</a>'; ?>
</td>
<td><?php echo getBanType($ban['type']); ?></td>
<td>
<?php
if ($ban['expires'] == "-1")
echo 'Never';
else
echo date("H:i:s", $ban['expires']) . '<br/>' . date("d M Y", $ban['expires']);
?>
</td>
<td><?php echo getBanReason($ban['reason']); ?></td>
<td><?php echo $ban['comment']; ?></td>
<td>
<?php
if ($ban['admin_id'] == "0")
echo 'Autoban';
else
$aName = getPlayerNameByAccount($ban['admin_id']);
echo '<a href="?p=players&search=' . $aName . '">' . $aName . '</a>';
echo '<br/>' . date("d.m.Y", $ban['added']);
?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
} else {
echo 'No Account bans.';
} ?>
</div>
<?php endif;
if ($db->hasTable('store_history')) { ?>
<div class="tab-pane fade" id="accounts-store">
<?php $store_history = $db->query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?>
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
<tr>
<th>Description</th>
<th>Coins</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<?php foreach ($store_history as $p): ?>
<tr>
<td><?php echo $p['description']; ?></td>
<td><?php echo $p['coin_amount']; ?></td>
<td><?php echo date('d M y H:i:s', $p['time']); ?></td>
</tr>
<?php endforeach; ?>
</tbody> </tbody>
</table> </table>
</div> </div>
<?php } ?>
</div> </div>
<?php
};
};
?>
</div> </div>
</div>
<script type="text/javascript"> </div>
$('#lastlogout').datetimepicker({format: 'unixtime'}); <?php } ?>
$('#created').datetimepicker({format: 'unixtime'}); <div class="col-12 col-sm-12 col-lg-2">
$('#web_lastlogin').datetimepicker({format: 'unixtime'}); <div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0">Search Accounts</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post">
<label for="name">Account Name:</label>
<div class="input-group input-group-sm">
<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>
</div>
</form>
</div>
<div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post">
<label for="name">Account ID:</label>
<div class="input-group input-group-sm">
<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>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () { $(document).ready(function () {
$('.input_control').change(function () { $('#created').datetimepicker({format: "M d Y, H:i:s",});
$('input[name=pass]')[0].disabled = !this.checked; $('#web_lastlogin').datetimepicker({format: 'M d Y, H:i:s'});
$('input[name=pass]')[0].value = '';
$('#c_pass').change(function () {
const ipass = $('input[name=pass]');
ipass[0].disabled = !this.checked;
ipass[0].value = '';
}).change(); }).change();
$('.acc_datatable').DataTable({
"order": [[0, "asc"]]
});
}); });
</script> </script>

View File

@@ -1,26 +1,139 @@
<?php <?php
/** /**
* CHANGELOG viewer * CHANGELOG modifier
* *
* @package MyAAC * @package MyAAC
* @author Slawkens <slawkens@gmail.com> * @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC * @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'MyAAC Changelog';
if (!file_exists(BASE . 'CHANGELOG.md')) { if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'File CHANGELOG.md doesn\'t exist.'; echo 'Access denied.';
return; return;
} }
require LIBS . 'Parsedown.php'; $title = 'Changelog';
$use_datatable = true;
const CL_LIMIT = 600; // maximum changelog body length
?>
$changelog = file_get_contents(BASE . 'CHANGELOG.md'); <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;
require_once LIBS . 'changelog.php';
$Parsedown = new Parsedown(); if(!empty($action))
{
$id = $_REQUEST['id'] ?? null;
$body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null;
$create_date = isset($_REQUEST['createdate']) ? (int)strtotime($_REQUEST['createdate'] ): null;
$player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null;
$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null;
$where = isset($_REQUEST['where']) ? (int)$_REQUEST['where'] : null;
$changelog = $Parsedown->text($changelog); # prints: <p>Hello <em>Parsedown</em>!</p> $errors = array();
echo '<div>' . $changelog . '</div>'; if($action == 'new') {
if(isset($body) && Changelog::add($body, $type, $where, $player_id, $create_date, $errors)) {
$body = '';
$type = $where = $player_id = $create_date = 0;
success("Added successful.");
}
}
else if($action == 'delete') {
Changelog::delete($id, $errors);
success("Deleted successful.");
}
else if($action == 'edit')
{
if(isset($id) && !isset($body)) {
$cl = Changelog::get($id);
$body = $cl['body'];
$type = $cl['type'];
$where = $cl['where'];
$create_date = $cl['date'];
$player_id = $cl['player_id'];
}
else {
if(Changelog::update($id, $body, $type, $where, $player_id, $create_date,$errors)) {
$action = $body = '';
$type = $where = $player_id = $create_date = 0;
success("Updated successful.");
}
}
}
else if($action == 'hide') {
Changelog::toggleHidden($id, $errors, $status);
success(($status == 1 ? 'Show' : 'Hide') . " successful.");
}
if(!empty($errors))
error(implode(", ", $errors));
}
$changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog' . '` ORDER BY `id` DESC')->fetchAll();
$i = 0;
$log_type = [
['id' => 1, 'icon' => 'added'],
['id' => 2, 'icon' => 'removed'],
['id' => 3, 'icon' => 'changed'],
['id' => 4, 'icon' => 'fixed'],
];
$log_where = [
['id' => 1, 'icon' => 'server'],
['id' => 2, 'icon' => 'website'],
];
foreach($changelogs as $key => &$log)
{
$log['type'] = getChangelogType($log['type']);
$log['where'] = getChangelogWhere($log['where']);
}
if($action == 'edit' || $action == 'new') {
if($action == 'edit') {
$player = new OTS_Player();
$player->load($player_id);
}
$account_players = $account_logged->getPlayersList();
$account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.changelog.form.html.twig', array(
'action' => $action,
'cl_link_form' => constant('ADMIN_URL').'?p=changelog&action=' . ($action == 'edit' ? 'edit' : 'new'),
'cl_id' => $id ?? null,
'body' => isset($body) ? escapeHtml($body) : '',
'create_date' => $create_date ?? '',
'player_id' => $player_id ?? null,
'account_players' => $account_players,
'type' => $type ?? 0,
'where' => $where ?? 0,
'log_type' => $log_type,
'log_where' => $log_where,
));
}
$twig->display('admin.changelog.html.twig', array(
'changelogs' => $changelogs,
));
?>
<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>

25
admin/pages/clmd.php Normal file
View File

@@ -0,0 +1,25 @@
<?php
/**
* CHANGELOG viewer
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'MyAAC Changelog';
if (!file_exists(BASE . 'CHANGELOG.md')) {
echo 'File CHANGELOG.md doesn\'t exist.';
return;
}
$changelog = file_get_contents(BASE . 'CHANGELOG.md');
$Parsedown = new Parsedown();
$changelog = $Parsedown->text($changelog); # prints: <p>Hello <em>Parsedown</em>!</p>
echo '<div>' . $changelog . '</div>';

View File

@@ -19,8 +19,10 @@ if (isset($_GET['clear_cache'])) {
} }
if (isset($_GET['maintenance'])) { if (isset($_GET['maintenance'])) {
$_status = (int)$_POST['status']; $message = (!empty($_POST['message']) ? $_POST['message'] : null);
$message = $_POST['message']; $_status = (isset($_POST['status']) && $_POST['status'] == 'true');
$_status = ($_status ? '0' : '1');
if (empty($message)) { if (empty($message)) {
error('Message cannot be empty.'); error('Message cannot be empty.');
} else if (strlen($message) > 255) { } else if (strlen($message) > 255) {
@@ -45,47 +47,15 @@ $tmp = '';
if (fetchDatabaseConfig('site_closed_message', $tmp)) if (fetchDatabaseConfig('site_closed_message', $tmp))
$closed_message = $tmp; $closed_message = $tmp;
$query = $db->query('SELECT count(*) as `how_much` FROM `accounts`;'); $settingAdminPanelModules = setting('core.admin_panel_modules');
$query = $query->fetch(); if (count($settingAdminPanelModules) > 0) {
$total_accounts = $query['how_much'];
$query = $db->query('SELECT count(*) as `how_much` FROM `players`;');
$query = $query->fetch();
$total_players = $query['how_much'];
$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'];
$twig->display('admin.statistics.html.twig', array(
'total_accounts' => $total_accounts,
'total_players' => $total_players,
'total_guilds' => $total_guilds,
'total_houses' => $total_houses
));
$twig->display('admin.dashboard.html.twig', array(
'is_closed' => $is_closed,
'closed_message' => $closed_message,
'status' => $status,
'account_type' => USE_ACCOUNT_NAME ? 'name' : 'number'
));
echo '<div class="row">'; echo '<div class="row">';
$configAdminPanelModules = config('admin_panel_modules');
if(isset($configAdminPanelModules))
$configAdminPanelModules = explode(',', $configAdminPanelModules);
$twig_loader->prependPath(__DIR__ . '/modules/templates'); $twig_loader->prependPath(__DIR__ . '/modules/templates');
foreach($configAdminPanelModules as $box) { foreach ($settingAdminPanelModules as $box) {
$file = __DIR__ . '/modules/' . $box . '.php'; $file = __DIR__ . '/modules/' . $box . '.php';
if (file_exists($file)) { if (file_exists($file)) {
include($file); include($file);
} }
} }
echo '</div>'; echo '</div>';
}

View File

@@ -1,7 +1,6 @@
<?php <?php
/** /**
* Account confirm mail * Load items.xml
* Keept for compatibility
* *
* @package MyAAC * @package MyAAC
* @author Slawkens <slawkens@gmail.com> * @author Slawkens <slawkens@gmail.com>
@@ -9,7 +8,6 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Server Data';
if($action == 'confirm_email') { $twig->display('admin.data.html.twig');
require_once PAGES . 'account/confirm_email.php';
}

View File

@@ -1,35 +0,0 @@
<?php
/**
* Load items.xml
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Load items.xml';
require_once LIBS . 'items.php';
require_once LIBS . 'weapons.php';
$twig->display('admin.items.html.twig');
$reload = isset($_REQUEST['reload']) && (int)$_REQUEST['reload'] === 1;
if ($reload) {
$items_start_time = microtime(true);
if (Items::loadFromXML(true)) {
success('Successfully loaded items (in ' . round(microtime(true) - $items_start_time, 4) . ' seconds).');
}
else {
error(Items::getError());
}
$weapons_start_time = microtime(true);
if (Weapons::loadFromXML(true)) {
success('Successfully loaded weapons (in ' . round(microtime(true) - $weapons_start_time, 4) . ' seconds).');
}
else {
error(Weapons::getError());
}
}

View File

@@ -9,18 +9,16 @@
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Login'; $title = 'Login';
$logout = '';
if ($action == 'logout') { require PAGES . 'account/login.php';
$logout = "You have been logged out!"; if ($logged) {
header('Location: ' . (admin() ? ADMIN_URL : BASE_URL));
return;
} }
if (isset($errors)) { $twig->display('admin.login.html.twig', [
foreach ($errors as $error) { 'logout' => (ACTION == 'logout' ? 'You have been logged out!' : ''),
error($error);
}
}
$twig->display('admin.login.html.twig', array(
'logout' => $logout,
'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', 'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number',
)); 'account_login_by' => getAccountLoginByLabel(),
'errors' => $errors ?? ''
]);

View File

@@ -4,16 +4,17 @@
* *
* @package MyAAC * @package MyAAC
* @author Slawkens <slawkens@gmail.com> * @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Logs Viewer'; $title = 'Logs Viewer';
$use_datatable = true;
$files = array(); $files = array();
$aac_path_logs = BASE . 'system/logs/'; $aac_path_logs = BASE . 'system/logs/';
foreach (scandir($aac_path_logs, SCANDIR_SORT_ASCENDING) as $f) { foreach (scandir($aac_path_logs, SCANDIR_SORT_ASCENDING) as $f) {
if ($f[0] === '.' || is_dir($aac_path_logs . $f)) { if ($f[0] === '.' || is_dir($aac_path_logs . $f) || $f === 'index.html') {
continue; continue;
} }
@@ -53,7 +54,6 @@ foreach ($files as &$f) {
} }
unset($f); unset($f);
$twig->display('admin.logs.html.twig', array('files' => $files));
define('EXIST_NONE', 0); define('EXIST_NONE', 0);
define('EXIST_SERVER_LOG', 1); define('EXIST_SERVER_LOG', 1);
@@ -72,10 +72,12 @@ if (!empty($file)) {
} }
if ($exist !== EXIST_NONE) { if ($exist !== EXIST_NONE) {
$content = nl2br(file_get_contents(($exist === EXIST_SERVER_LOG ? $server_path_logs : $aac_path_logs) . $file)); $file_content = nl2br(file_get_contents(($exist === EXIST_SERVER_LOG ? $server_path_logs : $aac_path_logs) . $file));
$twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $content)); $twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $file_content));
} }
} else { } else {
echo 'Invalid file name specified.'; echo 'Invalid file name specified.';
} }
} }
$twig->display('admin.logs.html.twig', array('files' => $files));

View File

@@ -15,48 +15,55 @@ if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) {
return; return;
} }
if (!$config['mail_enabled']) { if (!setting('core.mail_enabled')) {
echo 'Mail support disabled.'; echo 'Mail support disabled in config.';
return; return;
} }
$mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : 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;
$preview = isset($_REQUEST['preview']); $mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null;
$preview_done = false; if (isset($_POST['submit'])) {
if ($preview) { if (empty($mail_subject)) {
warning('Please enter subject of the message.');
}
if (empty($mail_content)) {
warning('Please enter content of the message.');
}
}
if (!empty($mail_to)) {
if(!Validator::email($mail_to)) {
warning('E-Mail is invalid.');
}
else {
if (!empty($mail_content) && !empty($mail_subject)) { if (!empty($mail_content) && !empty($mail_subject)) {
$preview_done = _mail($account_logged->getCustomField('email'), $mail_subject, $mail_content); if (_mail($mail_to, $mail_subject, $mail_content)) {
success("Successfully mailed <strong>$mail_to</strong>");
if (!$preview_done) }
error('Error while sending preview mail. More info can be found in system/logs/mailer-error.log'); else {
error("Error while sending mail to <strong>$mail_to</strong>. More info can be found in system/logs/mailer-error.log");
}
}
} }
} }
if (!empty($mail_content) && !empty($mail_subject) && empty($mail_to)) {
$twig->display('admin.mailer.html.twig', array(
'mail_subject' => $mail_subject,
'mail_content' => $mail_content,
'preview_done' => $preview_done
));
if (empty($mail_content) || empty($mail_subject) || $preview)
return;
$success = 0; $success = 0;
$failed = 0; $failed = 0;
$add = ''; $add = '';
if ($config['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 ' . $db->fieldName('email_verified') . ' = 1'; $add = ' AND `email_verified` = 1';
} }
$query = $db->query('SELECT ' . $db->fieldName('email') . ' FROM ' . $db->tableName('accounts') . ' WHERE ' . $db->fieldName('email') . ' != ""' . $add); $query = $db->query('SELECT `email` FROM `accounts` WHERE `email` != ""' . $add);
foreach ($query as $email) { foreach ($query as $email) {
if (_mail($email['email'], $mail_subject, $mail_content)) if (_mail($email['email'], $mail_subject, $mail_content)) {
$success++; $success++;
}
else { else {
$failed++; $failed++;
echo '<br />'; echo '<br />';
@@ -67,3 +74,10 @@ foreach ($query as $email) {
success('Mailing finished.'); success('Mailing finished.');
success("$success emails delivered."); success("$success emails delivered.");
warning("$failed emails failed."); warning("$failed emails failed.");
}
$twig->display('admin.mailer.html.twig', [
'mail_to' => $mail_to,
'mail_subject' => $mail_subject,
'mail_content' => $mail_content
]);

View File

@@ -0,0 +1,215 @@
<?php
/**
* Account Admin Tool
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Account Actions';
$hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$freePremium = $config['lua']['freePremium'];
function admin_give_points($points)
{
global $db, $hasPointsColumn;
if (!$hasPointsColumn) {
displayMessage('Points not supported.');
return;
}
$statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points');
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return;
}
if (!$statement->execute([
'points' => $points
])) {
displayMessage('Failed to add points.');
return;
}
displayMessage($points . ' points added to all accounts.', true);
}
function admin_give_coins($coins)
{
global $db, $hasCoinsColumn;
if (!$hasCoinsColumn) {
displayMessage('Coins not supported.');
return;
}
$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.');
return;
}
displayMessage($coins . ' coins added to all accounts.', true);
}
function query_add_premium($column, $value_query, $condition_query = '1=1', $params = [])
{
global $db;
$statement = $db->prepare("UPDATE `accounts` SET `{$column}` = $value_query WHERE $condition_query");
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return false;
}
if (!$statement->execute($params)) {
displayMessage('Failed to add premium days.');
return false;
}
return true;
}
function admin_give_premdays($days)
{
global $db, $freePremium;
if ($freePremium) {
displayMessage('Premium days not supported. Free Premium enabled.');
return;
}
$value = $days * 86400;
$now = time();
// othire
if ($db->hasColumn('accounts', 'premend')) {
// append premend
if (query_add_premium('premend', '`premend` + :value', '`premend` > :now', ['value' => $value, 'now' => $now])) {
// set premend
if (query_add_premium('premend', ':value', '`premend` <= :now', ['value' => $now + $value, 'now' => $now])) {
displayMessage($days . ' premium days added to all accounts.', true);
return;
} else {
displayMessage('Failed to execute set query.');
return;
}
} else {
displayMessage('Failed to execute append query.');
return;
}
return;
}
// tfs 0.x
if ($db->hasColumn('accounts', 'premdays')) {
// append premdays
if (query_add_premium('premdays', '`premdays` + :value', '1=1', ['value' => $days])) {
// append lastday
if (query_add_premium('lastday', '`lastday` + :value', '`lastday` > :now', ['value' => $value, 'now' => $now])) {
// set lastday
if (query_add_premium('lastday', ':value', '`lastday` <= :now', ['value' => $now + $value, 'now' => $now])) {
displayMessage($days . ' premium days added to all accounts.', true);
return;
} else {
displayMessage('Failed to execute set query.');
return;
}
return;
} else {
displayMessage('Failed to execute append query.');
return;
}
} else {
displayMessage('Failed to execute set days query.');
return;
}
return;
}
// tfs 1.x
if ($db->hasColumn('accounts', 'premium_ends_at')) {
// append premium_ends_at
if (query_add_premium('premium_ends_at', '`premium_ends_at` + :value', '`premium_ends_at` > :now', ['value' => $value, 'now' => $now])) {
// set premium_ends_at
if (query_add_premium('premium_ends_at', ':value', '`premium_ends_at` <= :now', ['value' => $now + $value, 'now' => $now])) {
displayMessage($days . ' premium days added to all accounts.', true);
return;
} else {
displayMessage('Failed to execute set query.');
return;
}
} else {
displayMessage('Failed to execute append query.');
return;
}
return;
}
displayMessage('Premium Days not supported.');
}
if (isset($_POST['action']) && $_POST['action']) {
$action = $_POST['action'];
if (preg_match("/[^A-z0-9_\-]/", $action)) {
displayMessage('Invalid action.');
} else {
$value = isset($_POST['value']) ? intval($_POST['value']) : 0;
if (!$value) {
displayMessage('Please fill all inputs');
} else {
switch ($action) {
case 'give-points':
admin_give_points($value);
break;
case 'give-coins':
admin_give_coins($value);
break;
case 'give-premdays':
admin_give_premdays($value);
break;
default:
displayMessage('Action ' . $action . 'not found.');
}
}
}
}
else {
$twig->display('admin.tools.account.html.twig', array(
'hasCoinsColumn' => $hasCoinsColumn,
'hasPointsColumn' => $hasPointsColumn,
'freePremium' => $freePremium,
));
}
function displayMessage($message, $success = false) {
global $twig, $hasCoinsColumn, $hasPointsColumn, $freePremium;
$success ? success($message): error($message);
$twig->display('admin.tools.account.html.twig', array(
'hasCoinsColumn' => $hasCoinsColumn,
'hasPointsColumn' => $hasPointsColumn,
'freePremium' => $freePremium,
));
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* Teleport Admin Tool
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Teleport Actions';
function admin_teleport_position($x, $y, $z) {
global $db;
$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.');
return;
}
displayMessage('Player\'s position updated.', true);
}
function admin_teleport_town($town_id) {
global $db;
$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.');
return;
}
displayMessage('Player\'s town updated.', true);
}
if (isset($_POST['action']) && $_POST['action']) {
$action = $_POST['action'];
if (preg_match("/[^A-z0-9_\-]/", $action)) {
displayMessage('Invalid action.');
} else {
$playersOnline = 0;
if($db->hasTable('players_online')) {// tfs 1.0
$query = $db->query('SELECT count(*) AS `count` FROM `players_online`');
} else {
$query = $db->query('SELECT count(*) AS `count` FROM `players` WHERE `players`.`online` > 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.');
return;
}
$town_id = isset($_POST['town_id']) ? intval($_POST['town_id']) : null;
$posx = isset($_POST['posx']) ? intval($_POST['posx']) : null;
$posy = isset($_POST['posy']) ? intval($_POST['posy']) : null;
$posz = isset($_POST['posz']) ? intval($_POST['posz']) : null;
$to_temple = $_POST['to_temple'] ?? null;
switch ($action) {
case 'set-town':
if (!$town_id) {
displayMessage('Please fill all inputs');
return;
}
if (!isset($config['towns'][$town_id])) {
displayMessage('Specified town does not exist');
return;
}
admin_teleport_town($town_id);
break;
case 'set-position':
if (!$to_temple && ($posx < 0 || $posx > 65535 || $posy < 0 || $posy > 65535|| $posz < 0 || $posz > 16)) {
displayMessage('Invalid Position');
return;
}
admin_teleport_position($posx, $posy, $posz);
break;
default:
displayMessage('Action ' . $action . 'not found.');
}
}
}
else {
$twig->display('admin.tools.teleport.html.twig', array());
}
function displayMessage($message, $success = false) {
global $twig;
$success ? success($message): error($message);
$twig->display('admin.tools.teleport.html.twig', array());
}

View File

@@ -63,64 +63,70 @@ if (isset($_REQUEST['template'])) {
return; return;
} }
echo 'Hint: You can drag menu items.<br/> $title = 'Menus - ' . $template;
?>
<div align="center" class="text-center">
<p class="note">You are editing: <?= $template ?><br/><br/>
Hint: You can drag menu items.<br/>
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.<br/><br/> Not all templates support blank and colorful links.
<div class="row">'; </p>
</div>
<?php
$menus = array(); $menus = array();
$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(); $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();
foreach ($menus_db as $menu) { foreach ($menus_db as $menu) {
$menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']); $menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']);
} }
$last_id = array(); $last_id = array();
echo '<form method="post" id="menus-form" action="?p=menus">'; ?>
echo '<input type="hidden" name="template" value="' . $template . '"/>'; <form method="post" id="menus-form" action="?p=menus">
foreach ($config['menu_categories'] as $id => $cat) { <input type="hidden" name="template" value="<?php echo $template ?>"/>
echo ' <div class="col-md-12 col-lg-6"> <div class="row">
<div class="box box-danger"> <?php foreach ($config['menu_categories'] as $id => $cat): ?>
<div class="box-header with-border"> <div class="col-md-12 col-lg-6">
<h3 class="box-title">' . $cat['name'] . ' <img class="add-button" id="add-button-' . $id . '" src="' . BASE_URL . 'images/plus.png" width="16" height="16"/></h3> <div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0"><?php echo $cat['name'] ?> <i class="far fa-plus-square add-button" id="add-button-<?php echo $id ?>"></i></h5>
</div> </div>
<div class="box-body">'; <div class="card-body">
<ul class="sortable" id="sortable-<?php echo $id ?>">
<?php
echo '<ul class="sortable" id="sortable-' . $id . '">';
if (isset($menus[$id])) { if (isset($menus[$id])) {
$i = 0; $i = 0;
foreach ($menus[$id] as $menu) { foreach ($menus[$id] as $menu):
echo '<li class="ui-state-default" id="list-' . $id . '-' . $i . '"><label>Name:</label><input type="text" name="menu[' . $id . '][]" value="' . escapeHtml($menu['name']) . '"/> ?>
<label>Link:</label><input type="text" name="menu_link[' . $id . '][]" value="' . $menu['link'] . '"/> <li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo escapeHtml($menu['name']); ?>"/>
<input type="hidden" name="menu_blank[' . $id . '][]" value="0" /> <label>Link:</label> <input type="text" name="menu_link[<?php echo $id ?>][]" value="<?php echo $menu['link'] ?>"/>
<label><input class="blank-checkbox" type="checkbox" ' . ($menu['blank'] == 1 ? 'checked' : '') . '/><span title="Open in New Window">Open in New Window</span></label> <input type="hidden" name="menu_blank[<?php echo $id ?>][]" value="0"/>
<label><input class="blank-checkbox" type="checkbox" <?php echo($menu['blank'] == 1 ? 'checked' : '') ?>/><span title="Open in New Window">New Window</span></label>
<input class="color-picker" type="text" name="menu_color[' . $id . '][]" value="#' . $menu['color'] . '" /> <input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo (empty($menu['color']) ? ($config['menu_default_color'] ?? '#ffffff') : $menu['color']); ?>"/>
<a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li>
<a class="remove-button" id="remove-button-' . $id . '-' . $i . '"><img src="' . BASE_URL . 'images/del.png"/></a></li>'; <?php $i++; $last_id[$id] = $i;
endforeach;
$i++; } ?>
$last_id[$id] = $i; </ul>
}
}
echo '</ul>';
echo ' </div>
</div> </div>
</div> </div>
'; </div>
} <?php endforeach ?>
echo ' </div><div class="row"><div class="col-md-6">'; </div>
echo '<input type="submit" class="btn btn-info" value="Save">'; <div class="row pb-2">
echo '<input type="button" class="btn btn-default pull-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus&template=' . $template . '\';">'; <div class="col-md-12">
echo '</div></div>'; <button type="submit" class="btn btn-info"><i class="fas fa-update"></i> Save</button>
echo '</form>'; <?php
echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>';
?>
</div>
</div>
</form>
<?php
$twig->display('admin.menus.js.html.twig', array( $twig->display('admin.menus.js.html.twig', array(
'menus' => $menus, 'menus' => $menus,
'last_id' => $last_id 'last_id' => $last_id,
'menu_default_color' => $config['menu_default_color'] ?? '#ffffff'
)); ));
?> ?>
<?php <?php
} else { } else {
$templates = $db->query('SELECT `template` FROM `' . TABLE_PREFIX . 'menu` GROUP BY `template`;')->fetchAll(); $templates = $db->query('SELECT `template` FROM `' . TABLE_PREFIX . 'menu` GROUP BY `template`;')->fetchAll();

View File

@@ -0,0 +1,8 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
$balance = ($db->hasColumn('players', 'balance') ? $db->query('SELECT `balance`, `id`, `name`,`level` FROM `players` ORDER BY `balance` DESC LIMIT 10;') : 0);
$twig->display('balance.html.twig', array(
'balance' => $balance
));

View File

@@ -1,10 +1,7 @@
<?php <?php
defined('MYAAC') or die('Direct access not allowed!');
if ($db->hasColumn('accounts', 'coins')) { $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);
$coins = $db->query('SELECT `coins`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `coins` DESC LIMIT 10;');
} else {
$coins = 0;
}
$twig->display('coins.html.twig', array( $twig->display('coins.html.twig', array(
'coins' => $coins 'coins' => $coins

View File

@@ -0,0 +1,8 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
$players = ($db->hasColumn('accounts', 'created') ? $db->query('SELECT `created`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `created` DESC LIMIT 10;') : 0);
$twig->display('created.html.twig', array(
'players' => $players,
));

View File

@@ -1,11 +1,7 @@
<?php <?php
defined('MYAAC') or die('Direct access not allowed!');
if ($db->hasColumn('players', 'lastlogin')) { $players = ($db->hasColumn('players', 'lastlogin') ? $db->query('SELECT name, level, lastlogin FROM players ORDER BY lastlogin DESC LIMIT 10;') : 0);
$players = $db->query('SELECT name, level, lastlogin FROM players ORDER BY lastlogin DESC LIMIT 10;');
} else {
$players = 0;
}
$twig->display('lastlogin.html.twig', array( $twig->display('lastlogin.html.twig', array(
'players' => $players, 'players' => $players,
)); ));

View File

@@ -1,9 +1,7 @@
<?php <?php
if ($db->hasColumn('accounts', 'premium_points')) { defined('MYAAC') or die('Direct access not allowed!');
$points = $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;');
} else { $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);
$points = 0;
}
$twig->display('points.html.twig', array( $twig->display('points.html.twig', array(
'points' => $points, 'points' => $points,

View File

@@ -0,0 +1,46 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
if (isset($status)) {
$error_icon = '<i class="fas fa-exclamation-circle text-danger"></i>'; ?>
<div class=" col-md-6 col-lg-6">
<div class="card card-info card-outline">
<div class="card-header border-bottom-0">
<span class="font-weight-bold m-0">Server Status</span> <span class="float-right small"><b>Last checked</b>: <?php echo(isset($status['lastCheck']) ? date("l, d.m.Y H:i:s", $status['lastCheck']) : $error_icon); ?></span>
</div>
<div class="card-body p-0 ">
<table class="table">
<tbody>
<tr>
<th width="30%">Server</th>
<td><?php echo(isset($status['server']) & isset($status['serverVersion']) ? $status['server'] . ' x ' . $status['serverVersion'] : $error_icon) ?></td>
</tr>
<tr>
<th>Client</th>
<td><?php echo(isset($status['clientVersion']) ? $status['clientVersion'] : $error_icon) ?></td>
</tr>
<tr>
<th>Map</th>
<td>
<?php if (isset($status['mapName']) & isset($status['mapAuthor']) & isset($status['mapWidth']) & isset($status['mapHeight'])) {
echo $status['mapName'] . ' by <b>' . $status['mapAuthor'] . '</b><br/>' . $status['mapWidth'] . ' x ' . $status['mapHeight'];
} else {
echo $error_icon;
} ?>
</td>
</tr>
<tr>
<th>Monsters</th>
<td><?php echo (isset($status['monsters']) ? $status['monsters'] : $error_icon); ?></td>
</tr>
<tr>
<th>MOTD:</th>
<td><?php echo(isset($status['motd']) ? $status['motd'] : $error_icon); ?></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<?php } ?>

View File

@@ -0,0 +1,12 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
$count = $db->query('SELECT
(SELECT COUNT(*) FROM `accounts`) as total_accounts,
(SELECT COUNT(*) FROM `players`) as total_players,
(SELECT COUNT(*) FROM `guilds`) as total_guilds,
(SELECT COUNT(*) FROM `' . TABLE_PREFIX . 'monsters`) as total_monsters,
(SELECT COUNT(*) FROM `houses`) as total_houses;')->fetch();
$twig->display('statistics.html.twig', array(
'count' => $count,
));

View File

@@ -0,0 +1,31 @@
{% if balance is iterable %}
<div class=" col-md-6 col-lg-3">
<div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0">Top 10 - Balance</h5>
</div>
<div class="card-body p-0">
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>#</th>
<th>Player</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
{% set i = 0 %}
{% for result in balance %}
{% set i = i + 1 %}
<tr>
<th>{{ i }}</th>
<td><a href="?p=players&search_name={{ result.name }}">{{ result.name }}</a></td>
<td>{{ result.balance }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}

View File

@@ -1,23 +1,25 @@
{% if coins is iterable %} {% if coins is iterable %}
<div class="col-md-3"> <div class=" col-md-6 col-lg-3">
<div class="box"> <div class="card card-info card-outline">
<div class="box-header"> <div class="card-header">
<h3 class="box-title">Top 10 - Most coins</h3> <h5 class="m-0">Top 10 - Most coins</h5>
</div> </div>
<div class="box-body no-padding"> <div class="card-body p-0">
<table class="table table-condensed"> <table class="table table-striped table-condensed">
<tbody> <thead>
<tr> <tr>
<th>#</th> <th>#</th>
<th>Account {{ account_type }}</th> <th>Account</th>
<th>Tibia coins</th> <th>Tibia coins</th>
</tr> </tr>
</thead>
<tbody>
{% set i = 0 %} {% set i = 0 %}
{% for result in coins %} {% for result in coins %}
{% set i = i + 1 %} {% set i = i + 1 %}
<tr> <tr>
<td>{{ i }}</td> <th>{{ i }}</th>
<td>{{ result.name }}</td> <td><a href="?p=accounts&search_name={{ result.name }}">{{ result.name }}</a></td>
<td>{{ result.coins }}</td> <td>{{ result.coins }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -0,0 +1,31 @@
{% if players is iterable %}
<div class=" col-md-6 col-lg-3">
<div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0">Last 10 created</h5>
</div>
<div class="card-body p-0">
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>#</th>
<th>Account</th>
<th>Creation Date</th>
</tr>
</thead>
<tbody>
{% set i = 0 %}
{% for result in players %}
{% set i = i + 1 %}
<tr>
<th>{{ i }}</th>
<td><a href="?p=accounts&search_name={{ result.name }}">{{ result.name }}</a></td>
<td>{{ result.created|date("M d Y, H:i:s") }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}

View File

@@ -1,23 +1,25 @@
{% if players is iterable %} {% if players is iterable %}
<div class="col-md-3"> <div class=" col-md-6 col-lg-3">
<div class="box"> <div class="card card-info card-outline">
<div class="box-header"> <div class="card-header">
<h3 class="box-title">Last 10 Logins</h3> <h5 class="m-0">Last 10 logins</h5>
</div> </div>
<div class="box-body no-padding"> <div class="card-body p-0">
<table class="table table-condensed"> <table class="table table-striped table-condensed">
<tbody> <thead>
<tr> <tr>
<th>#</th> <th>#</th>
<th>Player</th> <th>Player</th>
<th>Login Date</th> <th>Login Date</th>
</tr> </tr>
</thead>
<tbody>
{% set i = 0 %} {% set i = 0 %}
{% for result in players %} {% for result in players %}
{% set i = i + 1 %} {% set i = i + 1 %}
<tr> <tr>
<td>{{ i }}</td> <th>{{ i }}</th>
<td>{{ result.name }}</td> <td><a href="?p=players&search_name={{ result.name }}">{{ result.name }}</a></td>
<td>{{ result.lastlogin|date("M d Y, H:i:s") }}</td> <td>{{ result.lastlogin|date("M d Y, H:i:s") }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -1,23 +1,25 @@
{% if points is iterable %} {% if points is iterable %}
<div class="col-md-3"> <div class=" col-md-6 col-lg-3">
<div class="box"> <div class="card card-info card-outline">
<div class="box-header"> <div class="card-header">
<h3 class="box-title">Top 10 - Most premium points</h3> <h5 class="m-0">Top 10 - Most premium points</h5>
</div> </div>
<div class="box-body no-padding"> <div class="card-body p-0">
<table class="table table-condensed"> <table class="table table-striped table-condensed">
<tbody> <thead>
<tr> <tr>
<th>#</th> <th>#</th>
<th>Account {{ account_type }}</th> <th>Account</th>
<th>Premium points</th> <th>Premium points</th>
</tr> </tr>
</thead>
<tbody>
{% set i = 0 %} {% set i = 0 %}
{% for result in points %} {% for result in points %}
{% set i = i + 1 %} {% set i = i + 1 %}
<tr> <tr>
<td>{{ i }}</td> <th>{{ i }}</th>
<td>{{ result.name }}</td> <td><a href="?p=accounts&search_name={{ result.name }}">{{ result.name }}</a></td>
<td>{{ result.premium_points }}</td> <td>{{ result.premium_points }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -0,0 +1,45 @@
<div class="col">
<div class="info-box">
<span class="info-box-icon bg-info elevation-1"><i class="fas fa-user-plus"></i></span>
<div class="info-box-content">
<span class="info-box-text">Accounts:</span>
<span class="info-box-number">{{ count.total_accounts }}</span>
</div>
</div>
</div>
<div class="col">
<div class="info-box">
<span class="info-box-icon bg-red elevation-1"><i class="fas fa-user-plus"></i></span>
<div class="info-box-content">
<span class="info-box-text">Players:</span>
<span class="info-box-number">{{ count.total_players }}</span>
</div>
</div>
</div>
<div class="col">
<div class="info-box">
<span class="info-box-icon bg-teal elevation-1"><i class="fas fa-pastafarianism"></i></span>
<div class="info-box-content">
<span class="info-box-text">Monsters:</span>
<span class="info-box-number">{{ count.total_monsters }}</span>
</div>
</div>
</div>
<div class="col">
<div class="info-box">
<span class="info-box-icon bg-green elevation-1"><i class="fas fa-chart-pie"></i></span>
<div class="info-box-content">
<span class="info-box-text">Guilds:</span>
<span class="info-box-number">{{ count.total_guilds }}</span>
</div>
</div>
</div>
<div class="col">
<div class="info-box">
<span class="info-box-icon bg-yellow elevation-1"><i class="fas fa-home"></i></span>
<div class="info-box-content">
<span class="info-box-text">Houses:</span>
<span class="info-box-number">{{ count.total_houses }}</span>
</div>
</div>
</div>

View File

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

View File

@@ -0,0 +1,10 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
$twig->display('web_status.twig', array(
'is_closed' => $is_closed,
'closed_message' => $closed_message,
'status' => $status,
'account_type' => USE_ACCOUNT_NAME ? 'name' : 'number'
));
?>

View File

@@ -13,6 +13,7 @@ require_once LIBS . 'forum.php';
require_once LIBS . 'news.php'; require_once LIBS . 'news.php';
$title = 'News Panel'; $title = 'News Panel';
$use_datatable = true;
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
@@ -22,8 +23,8 @@ 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)
define('TITLE_LIMIT', 100); define('NEWS_TITLE_LIMIT', 100);
define('BODY_LIMIT', 65535); // maximum news body length define('NEWS_BODY_LIMIT', 65535); // maximum news body length
define('ARTICLE_TEXT_LIMIT', 300); define('ARTICLE_TEXT_LIMIT', 300);
define('ARTICLE_IMAGE_LIMIT', 100); define('ARTICLE_IMAGE_LIMIT', 100);
@@ -42,12 +43,12 @@ if(!empty($action))
$forum_section = isset($_REQUEST['forum_section']) ? $_REQUEST['forum_section'] : null; $forum_section = isset($_REQUEST['forum_section']) ? $_REQUEST['forum_section'] : null;
$errors = array(); $errors = array();
if($action == 'add') { 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(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; $type = $category = $player_id = 0;
@@ -114,21 +115,21 @@ if($action == 'edit' || $action == 'new') {
$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' => getLink(PAGE),
'news_link_form' => '?p=news&action=' . ($action == 'edit' ? 'edit' : 'add'), 'news_link_form' => '?p=news&action=' . ($action == 'edit' ? 'edit' : 'new'),
'news_id' => isset($id) ? $id : null, 'news_id' => $id ?? null,
'title' => isset($p_title) ? $p_title : '', 'title' => $p_title ?? '',
'body' => isset($body) ? escapeHtml($body) : '', 'body' => isset($body) ? escapeHtml($body) : '',
'type' => isset($type) ? $type : null, 'type' => $type ?? null,
'player' => isset($player) && $player->isLoaded() ? $player : null, 'player' => isset($player) && $player->isLoaded() ? $player : null,
'player_id' => isset($player_id) ? $player_id : null, 'player_id' => $player_id ?? null,
'account_players' => $account_players, 'account_players' => $account_players,
'category' => isset($category) ? $category : 0, 'category' => $category ?? 0,
'categories' => $categories, 'categories' => $categories,
'forum_boards' => getForumBoards(), 'forum_boards' => getForumBoards(),
'forum_section' => isset($forum_section) ? $forum_section : null, 'forum_section' => $forum_section ?? null,
'comments' => isset($comments) ? $comments : null, 'comments' => $comments ?? null,
'article_text' => isset($article_text) ? $article_text : null, 'article_text' => $article_text ?? null,
'article_image' => isset($article_image) ? $article_image : null 'article_image' => $article_image ?? null
)); ));
} }

View File

@@ -0,0 +1,14 @@
<?php
/**
* Open Source libraries
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2023 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Open Source';
$twig->display('admin.open_source.html.twig');

View File

@@ -9,6 +9,7 @@
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Pages'; $title = 'Pages';
$use_datatable = true;
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
@@ -17,13 +18,18 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
header('X-XSS-Protection:0'); header('X-XSS-Protection:0');
$name = $p_title = ''; $name = $p_title = null;
$groups = new OTS_Groups_List(); $groups = new OTS_Groups_List();
$php = false; $php = false;
$enable_tinymce = true; $enable_tinymce = true;
$access = 0; $access = 0;
// some constants, used mainly by database (cannot by modified without schema changes)
define('PAGE_TITLE_LIMIT', 30);
define('PAGE_NAME_LIMIT', 30);
define('PAGE_BODY_LIMIT', 65535); // maximum page body length
if (!empty($action)) { if (!empty($action)) {
if ($action == 'delete' || $action == 'edit' || $action == 'hide') if ($action == 'delete' || $action == 'edit' || $action == 'hide')
$id = $_REQUEST['id']; $id = $_REQUEST['id'];
@@ -49,12 +55,13 @@ if (!empty($action)) {
$errors = array(); $errors = array();
$player_id = 1; $player_id = 1;
if ($action == 'add') { if ($action == 'new') {
if (Pages::add($name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { if (isset($p_title) && Pages::add($name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
$name = $p_title = $body = ''; $name = $p_title = $body = '';
$player_id = $access = 0; $player_id = $access = 0;
$php = false; $php = false;
$enable_tinymce = true; $enable_tinymce = true;
success('Added successful.');
} }
} else if ($action == 'delete') { } else if ($action == 'delete') {
if (Pages::delete($id, $errors)) if (Pages::delete($id, $errors))
@@ -69,15 +76,18 @@ if (!empty($action)) {
$enable_tinymce = $_page['enable_tinymce'] == '1'; $enable_tinymce = $_page['enable_tinymce'] == '1';
$access = $_page['access']; $access = $_page['access'];
} else { } else {
Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access); if(Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
$action = $name = $p_title = $body = ''; $action = $name = $p_title = $body = '';
$player_id = 1; $player_id = 1;
$access = 0; $access = 0;
$php = false; $php = false;
$enable_tinymce = true; $enable_tinymce = true;
success('Updated successful.');
}
} }
} else if ($action == 'hide') { } else if ($action == 'hide') {
Pages::toggleHidden($id, $errors); Pages::toggleHidden($id, $errors, $status);
success(($status == 1 ? 'Show' : 'Hide') . ' successful.');
} }
if (!empty($errors)) if (!empty($errors))
@@ -116,6 +126,48 @@ $twig->display('admin.pages.html.twig', array(
class 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) static public function get($id)
{ {
global $db; global $db;
@@ -128,8 +180,11 @@ class Pages
static public function add($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors) 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; global $db;
if (isset($name[0]) && isset($title[0]) && isset($body[0]) && $player_id != 0) {
$query = $db->select(TABLE_PREFIX . 'pages', array('name' => $name)); $query = $db->select(TABLE_PREFIX . 'pages', array('name' => $name));
if ($query === false) if ($query === false)
$db->insert(TABLE_PREFIX . 'pages', $db->insert(TABLE_PREFIX . 'pages',
@@ -145,14 +200,16 @@ class Pages
); );
else else
$errors[] = 'Page with this link already exists.'; $errors[] = 'Page with this link already exists.';
} else
$errors[] = 'Please fill all inputs.';
return !count($errors); return !count($errors);
} }
static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access) static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors)
{ {
if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
return false;
}
global $db; global $db;
$db->update(TABLE_PREFIX . 'pages', $db->update(TABLE_PREFIX . 'pages',
array( array(
@@ -165,6 +222,8 @@ class Pages
'access' => $access 'access' => $access
), ),
array('id' => $id)); array('id' => $id));
return true;
} }
static public function delete($id, &$errors) static public function delete($id, &$errors)
@@ -181,15 +240,18 @@ class Pages
return !count($errors); return !count($errors);
} }
static public function toggleHidden($id, &$errors) static public function toggleHidden($id, &$errors, &$status)
{ {
global $db; global $db;
if (isset($id)) { if (isset($id)) {
$query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id)); $query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id));
if ($query !== false) if ($query !== false) {
$db->update(TABLE_PREFIX . 'pages', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id)); $db->update(TABLE_PREFIX . 'pages', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
else $status = $query['hidden'];
}
else {
$errors[] = 'Page with id ' . $id . ' does not exists.'; $errors[] = 'Page with id ' . $id . ' does not exists.';
}
} else } else
$errors[] = 'id not set'; $errors[] = 'id not set';

View File

@@ -16,4 +16,4 @@ if (!function_exists('phpinfo')) { ?>
<?php return; <?php return;
} }
?> ?>
<iframe src="<?php echo BASE_URL; ?>admin/tools/phpinfo.php" width="1024" height="550"/> <iframe src="<?php echo ADMIN_URL; ?>tools/phpinfo.php" width="1024" height="550"></iframe>

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,14 @@
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Plugin manager'; $title = 'Plugin manager';
$use_datatable = true;
require_once LIBS . 'plugins.php';
if (!getBoolean(setting('core.admin_plugins_manage_enable'))) {
warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.');
}
else {
$twig->display('admin.plugins.form.html.twig'); $twig->display('admin.plugins.form.html.twig');
if (isset($_REQUEST['uninstall'])) { if (isset($_REQUEST['uninstall'])) {
@@ -20,13 +27,27 @@ if (isset($_REQUEST['uninstall'])) {
} else { } else {
error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError());
} }
} else if (isset($_FILES["plugin"]["name"])) { } else if (isset($_REQUEST['enable'])) {
$file = $_FILES["plugin"]; $enable = $_REQUEST['enable'];
$filename = $file["name"]; if (Plugins::enable($enable)) {
$tmp_name = $file["tmp_name"]; success('Successfully enabled plugin ' . $enable);
$type = $file["type"]; } else {
error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError());
}
} else if (isset($_REQUEST['disable'])) {
$disable = $_REQUEST['disable'];
if (Plugins::disable($disable)) {
success('Successfully disabled plugin ' . $disable);
} else {
error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError());
}
} else if (isset($_FILES['plugin']['name'])) {
$file = $_FILES['plugin'];
$filename = $file['name'];
$tmp_name = $file['tmp_name'];
$type = $file['type'];
$name = explode(".", $filename); $name = explode('.', $filename);
$accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', 'application/octet-stream', 'application/zip-compressed'); $accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', 'application/octet-stream', 'application/zip-compressed');
if (isset($file['error'])) { if (isset($file['error'])) {
@@ -85,23 +106,26 @@ if (isset($_REQUEST['uninstall'])) {
} }
} }
} }
}
$plugins = array(); $plugins = array();
foreach (get_plugins() as $plugin) { foreach (get_plugins(true) as $plugin) {
$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json'); $string = file_get_contents(BASE . 'plugins/' . $plugin . '.json');
$string = Plugins::removeComments($string);
$plugin_info = json_decode($string, true); $plugin_info = json_decode($string, true);
if ($plugin_info == false) { if (!$plugin_info) {
warning('Cannot load plugin info ' . $plugin . '.json'); warning('Cannot load plugin info ' . $plugin . '.json');
} else { } else {
$disabled = (strpos($plugin, 'disabled.') !== false);
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
$plugins[] = array( $plugins[] = array(
'name' => isset($plugin_info['name']) ? $plugin_info['name'] : '', 'name' => $plugin_info['name'] ?? '',
'description' => isset($plugin_info['description']) ? $plugin_info['description'] : '', 'description' => $plugin_info['description'] ?? '',
'version' => isset($plugin_info['version']) ? $plugin_info['version'] : '', 'version' => $plugin_info['version'] ?? '',
'author' => isset($plugin_info['author']) ? $plugin_info['author'] : '', 'author' => $plugin_info['author'] ?? '',
'contact' => isset($plugin_info['contact']) ? $plugin_info['contact'] : '', 'contact' => $plugin_info['contact'] ?? '',
'file' => $plugin, 'file' => $pluginOriginal,
'enabled' => !$disabled,
'uninstall' => isset($plugin_info['uninstall']) 'uninstall' => isset($plugin_info['uninstall'])
); );
} }

View File

@@ -4,11 +4,12 @@
* *
* @package MyAAC * @package MyAAC
* @author Lee * @author Lee
* @copyright 2019 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Report Viewer'; $title = 'Report Viewer';
$use_datatable = true;
$files = array(); $files = array();
$server_path_reports = $config['data_path'] . 'reports/'; $server_path_reports = $config['data_path'] . 'reports/';
@@ -42,16 +43,13 @@ foreach ($files as &$f) {
unset($f); unset($f);
$twig->display('admin.reports.html.twig', array('files' => $files));
$file = isset($_GET['file']) ? $_GET['file'] : NULL; $file = isset($_GET['file']) ? $_GET['file'] : NULL;
if (!empty($file)) { if (!empty($file)) {
if (!preg_match('/[^A-z0-9\' _\/\-\.]/', $file)) { if (!preg_match('/[^A-z0-9\' _\/\-\.]/', $file)) {
if (file_exists($server_path_reports . $file)) { if (file_exists($server_path_reports . $file)) {
$content = nl2br(file_get_contents($server_path_reports . $file)); $file_content = nl2br(file_get_contents($server_path_reports . $file));
$twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $content)); $twig->display('admin.logs.view.html.twig', array('file' => $file, 'content' => $file_content));
} else { } else {
echo 'Specified file does not exist.'; echo 'Specified file does not exist.';
} }
@@ -59,3 +57,5 @@ if (!empty($file)) {
echo 'Invalid file name specified.'; echo 'Invalid file name specified.';
} }
} }
$twig->display('admin.reports.html.twig', array('files' => $files));

56
admin/pages/settings.php Normal file
View File

@@ -0,0 +1,56 @@
<?php
/**
* Menus
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Settings';
require_once SYSTEM . 'clients.conf.php';
if (empty($_GET['plugin'])) {
error('Please select plugin from left Panel.');
return;
}
$plugin = $_GET['plugin'];
if($plugin != 'core') {
$pluginSettings = Plugins::getPluginSettings($plugin);
if (!$pluginSettings) {
error('This plugin does not exist or does not have settings defined.');
return;
}
$settingsFilePath = BASE . $pluginSettings;
}
else {
$settingsFilePath = SYSTEM . 'settings.php';
}
if (!file_exists($settingsFilePath)) {
error("Plugin $plugin does not exist or does not have settings defined.");
return;
}
$settingsFile = require $settingsFilePath;
if (!is_array($settingsFile)) {
error("Cannot load settings file for plugin $plugin");
return;
}
$settingsKeyName = ($plugin == 'core' ? $plugin : $settingsFile['key']);
$title = ($plugin == 'core' ? 'Settings' : 'Plugin Settings - ' . $plugin);
$settingsParsed = Settings::display($settingsKeyName, $settingsFile['settings']);
$twig->display('admin.settings.html.twig', [
'settingsParsed' => $settingsParsed['content'],
'settings' => $settingsFile['settings'],
'script' => $settingsParsed['script'],
'settingsKeyName' => $settingsKeyName,
]);

View File

@@ -10,18 +10,24 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Tools'; $title = 'Tools';
$tool = $_GET['tool']; if (!isset($_GET['tool'])) {
if (!isset($tool)) {
echo 'Tool not set.'; echo 'Tool not set.';
return; return;
} }
$tool = $_GET['tool'];
if (preg_match("/[^A-z0-9_\-]/", $tool)) { if (preg_match("/[^A-z0-9_\-]/", $tool)) {
echo 'Invalid tool.'; echo 'Invalid tool.';
return; return;
} }
$file = BASE . 'admin/pages/tools/' . $tool . '.php'; $file = ADMIN . 'tools/' . $tool . '.php';
if (!@file_exists($file))
if (@file_exists($file)) {
require $file; require $file;
return;
}
echo 'Tool <strong>' . $tool . '</strong> not found.';
?> ?>

View File

@@ -24,10 +24,10 @@ if (!$myaac_version) {
$version_compare = version_compare($myaac_version, MYAAC_VERSION); $version_compare = version_compare($myaac_version, MYAAC_VERSION);
if ($version_compare == 0) { if ($version_compare == 0) {
success('MyAAC latest version is ' . $myaac_version . '. You\'re using the latest version. success('MyAAC latest version is ' . $myaac_version . '. You\'re using the latest version.
<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=changelog', 'here')); <br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=clmd', 'here'));
} else if ($version_compare < 0) { } else if ($version_compare < 0) {
success('Woah, seems you\'re using newer version as latest released one! MyAAC latest released version is ' . $myaac_version . ', and you\'re using version ' . MYAAC_VERSION . '. success('Woah, seems you\'re using newer version as latest released one! MyAAC latest released version is ' . $myaac_version . ', and you\'re using version ' . MYAAC_VERSION . '.
<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=changelog', 'here')); <br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=clmd', 'here'));
} else { } else {
warning('You\'re using outdated version.<br/> warning('You\'re using outdated version.<br/>
Your version: <b>' . MYAAC_VERSION . '</b><br/> Your version: <b>' . MYAAC_VERSION . '</b><br/>

View File

@@ -8,9 +8,15 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Visitors';
if (!$config['visitors_counter']): ?> use DeviceDetector\DeviceDetector;
use DeviceDetector\Parser\Client\Browser;
use DeviceDetector\Parser\OperatingSystem;
$title = 'Visitors';
$use_datatable = true;
if (!setting('core.visitors_counter')): ?>
Visitors counter is disabled.<br/> Visitors counter is disabled.<br/>
You can enable it by editing this configurable in <b>config.local.php</b> file:<br/> You can enable it by editing this configurable in <b>config.local.php</b> file:<br/>
<p style="margin-left: 3em;"><b>$config['visitors_counter'] = true;</b></p> <p style="margin-left: 3em;"><b>$config['visitors_counter'] = true;</b></p>
@@ -19,18 +25,42 @@ if (!$config['visitors_counter']): ?>
endif; endif;
require SYSTEM . 'libs/visitors.php'; require SYSTEM . 'libs/visitors.php';
$visitors = new Visitors($config['visitors_counter_ttl']); $visitors = new Visitors(setting('core.visitors_counter_ttl'));
function compare($a, $b) function compare($a, $b): int {
{
return $a['lastvisit'] > $b['lastvisit'] ? -1 : 1; return $a['lastvisit'] > $b['lastvisit'] ? -1 : 1;
} }
$tmp = $visitors->getVisitors(); $tmp = $visitors->getVisitors();
usort($tmp, 'compare'); usort($tmp, 'compare');
foreach ($tmp as &$visitor) {
$userAgent = $visitor['user_agent'] ?? '';
if (!strlen($userAgent) || $userAgent == 'unknown') {
$browser = 'Unknown';
}
else {
$dd = new DeviceDetector($userAgent);
$dd->parse();
if ($dd->isBot()) {
$bot = $dd->getBot();
$message = '(Bot) %s, <a href="%s" target="_blank">%s</a>';
$browser = sprintf($message, $bot['category'], $bot['url'], $bot['name']);
}
else {
$osFamily = OperatingSystem::getOsFamily($dd->getOs('name'));
$browserFamily = Browser::getBrowserFamily($dd->getClient('name'));
$browser = $osFamily . ', ' . $browserFamily;
}
}
$visitor['browser'] = $browser;
}
$twig->display('admin.visitors.html.twig', array( $twig->display('admin.visitors.html.twig', array(
'config_visitors_counter_ttl' => $config['visitors_counter_ttl'], 'config_visitors_counter_ttl' => setting('core.visitors_counter_ttl'),
'visitors' => $tmp 'visitors' => $tmp
)); ));
?> ?>

69
admin/template/menus.php Normal file
View File

@@ -0,0 +1,69 @@
<?php
return [
['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'],
['name' => 'Settings', 'icon' => 'edit', 'order' => 19, 'link' =>
require ADMIN . 'includes/settings_menus.php'
],
['name' => 'News', 'icon' => 'newspaper', 'order' => 20, 'link' =>
[
['name' => 'View', 'link' => 'news', 'icon' => 'list', 'order' => 10],
['name' => 'Add news', 'link' => 'news&action=new&type=1', 'icon' => 'plus', 'order' => 20],
['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'icon' => 'plus', 'order' => 30],
['name' => 'Add article', 'link' => 'news&action=new&type=3', 'icon' => 'plus', 'order' => 40],
],
],
['name' => 'Changelogs', 'icon' => 'newspaper', 'order' => 30, 'link' =>
[
['name' => 'View', 'link' => 'changelog', 'icon' => 'list', 'order' => 10],
['name' => 'Add', 'link' => 'changelog&action=new', 'icon' => 'plus', 'order' => 20],
],
],
['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !setting('core.mail_enabled')],
['name' => 'Pages', 'icon' => 'book', 'order' => 50, 'link' =>
[
['name' => 'View', 'link' => 'pages', 'icon' => 'list', 'order' => 10],
['name' => 'Add', 'link' => 'pages&action=new', 'icon' => 'plus', 'order' => 20],
],
],
['name' => 'Menus', 'icon' => 'list', 'order' => 60, 'link' => 'menus'],
['name' => 'Plugins', 'icon' => 'plug', 'order' => 70, 'link' => 'plugins'],
['name' => 'Server Data', 'icon' => 'gavel', 'order' => 80, 'link' => 'data'],
['name' => 'Editor', 'icon' => 'edit', 'order' => 90, 'link' =>
[
['name' => 'Accounts', 'link' => 'accounts', 'icon' => 'users', 'order' => 10],
['name' => 'Players', 'link' => 'players', 'icon' => 'user-astronaut', 'order' => 20],
],
],
['name' => 'Tools', 'icon' => 'tools', 'order' => 100, 'link' =>
[
['name' => 'Mass Account Actions', 'link' => 'mass_account', 'icon' => 'globe', 'order' => 10],
['name' => 'Mass Teleport Actions', 'link' => 'mass_teleport', 'icon' => 'globe', 'order' => 20],
['name' => 'Notepad', 'link' => 'notepad', 'icon' => 'marker', 'order' => 30],
['name' => 'phpinfo', 'link' => 'phpinfo', 'icon' => 'server', 'order' => 40],
],
],
['name' => 'Logs', 'icon' => 'bug', 'order' => 110, 'link' =>
[
['name' => 'Logs', 'link' => 'logs', 'icon' => 'book', 'order' => 10],
['name' => 'Reports', 'link' => 'reports', 'icon' => 'book', 'order' => 20],
['name' => 'Visitors', 'link' => 'visitors', 'icon' => 'user', 'order' => 30],
],
],
];
$hooks->trigger(HOOK_ADMIN_MENU);
usort($menus, function ($a, $b) {
return $a['order'] - $b['order'];
});
foreach ($menus as $i => $menu) {
if (isset($menu['link']) && is_array($menu['link'])) {
usort($menus[$i]['link'], function ($a, $b) {
return $a['order'] - $b['order'];
});
}
}
return $menus;

View File

@@ -1,44 +1,10 @@
.slidecontainer { .menu-text-li {color: #4b646f; background: #1a2226;}
width: 100%; .menu-text {
display: block;
padding: .5rem 1rem;
white-space: nowrap;
} }
.slider { .sidebar-mini.sidebar-collapse .menu-text {
-webkit-appearance: none; display: none;
width: 100%;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 15px;
height: 25px;
background: #3c8dbc;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #3c8dbc;
cursor: pointer;
}
td.details-control {
text-align: center;
color: forestgreen;
cursor: pointer;
}
tr.shown td.details-control {
text-align: center;
color: red;
} }

View File

@@ -1,229 +1,203 @@
<?php defined('MYAAC') or die('Direct access not allowed!'); ?> <?php defined('MYAAC') or die('Direct access not allowed!'); ?>
<!DOCTYPE html> <!doctype html>
<html> <html lang="en">
<head> <head>
<?php echo template_header(true); <?php $hooks->trigger(HOOK_ADMIN_HEAD_START); ?>
$title_full = (isset($title) ? $title . $config['title_separator'] : '') . $config['lua']['serverName']; <?php echo template_header(true); ?>
?> <title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title><?php echo $title_full ?></title> <link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/adminlte.min.css">
<link rel="shortcut icon" href="<?php echo BASE_URL; ?>images/favicon.ico" type="image/x-icon" />
<link rel="icon" href="<?php echo BASE_URL; ?>images/favicon.ico" type="image/x-icon" />
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/bootstrap.min.css">
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/AdminLTE.min.css">
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/skins/skin-blue.min.css">
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/font-awesome.min.css"> <link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/font-awesome.min.css">
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/ionicons.min.css"> <?php if (isset($use_datatable)) { ?>
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/jquery.dataTables.min.css"> <link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/datatables.bs.min.css">
<?php } ?>
<link rel="stylesheet" type="text/css" href="<?php echo $template_path; ?>style.css"/> <link rel="stylesheet" type="text/css" href="<?php echo $template_path; ?>style.css"/>
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/respond.min.js"></script>
<![endif]--> <![endif]-->
<link rel="stylesheet" <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"> <?php $hooks->trigger(HOOK_ADMIN_HEAD_END); ?>
</head> </head>
<body class="hold-transition skin-blue sidebar-mini"> <body class="sidebar-mini ">
<?php $hooks->trigger(HOOK_ADMIN_BODY_START); ?>
<?php if ($logged && admin()) { ?>
<div class="wrapper"> <div class="wrapper">
<?php <nav class="main-header navbar navbar-expand navbar-white navbar-light">
if ($logged && admin()) { <ul class="navbar-nav">
?> <li class="nav-item">
<header class="main-header"> <a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
<a href="." class="logo"> </li>
<span class="logo-mini"><b>M</b>A</span> <li class="nav-item d-none d-sm-inline-block">
<span class="logo-lg"><b>My</b>AAC</span> <a href="<?php echo ADMIN_URL; ?>" class="nav-link">Home</a>
</a> </li>
</ul>
<nav class="navbar navbar-static-top" role="navigation"> <ul class="navbar-nav ml-auto">
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button"> <li class="nav-item">
<span class="sr-only">Toggle navigation</span> <a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#"><i class="fas fa-th-large"></i></a>
</a>
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li>
<a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a>
</li> </li>
</ul> </ul>
</div>
</nav> </nav>
</header> <aside class="main-sidebar sidebar-dark-info elevation-4">
<aside class="main-sidebar"> <a href="<?php echo ADMIN_URL; ?>" class="brand-link navbar-info">
<section class="sidebar"> <img src="<?php echo ADMIN_URL; ?>images/logo.png" class="brand-image img-circle elevation-3" style="opacity: .8">
<ul class="sidebar-menu" data-widget="tree"> <span class="brand-text"><b>My</b>AAC</span>
<li class="header">MyAAC</li> </a>
<div class="sidebar">
<nav class="mt-1">
<ul class="nav nav-pills nav-sidebar flex-column nav-legacy nav-child-indent" data-widget="treeview" data-accordion="false">
<li class="menu-text-li">
<span class="menu-text">
<a class="text-info" href="<?php echo BASE_URL; ?>" target="_blank">
<?php echo $config['lua']['serverName'] ?>
</a>
</span>
</li>
<?php <?php
$icons_a = array( // name = Display name of link
'dashboard','newspaper-o', 'envelope', // icon = fontawesome icon name without "fas fa-"
'book', 'list', // link = Page link or use as array for sub items
'plug', 'user', $menus = require __DIR__ . '/menus.php';
'edit', 'gavel',
'wrench', 'edit', 'book', 'book',
);
$menus = array( foreach ($menus as $category => $menu) {
'Dashboard' => 'dashboard', if (isset($menu['disabled']) && $menu['disabled']) {
'News' => 'news', continue;
'Mailer' => 'mailer',
'Pages' => 'pages',
'Menus' => 'menus',
'Plugins' => 'plugins',
'Visitors' => 'visitors',
'Editor' => array(
'Accounts' => 'accounts',
'Players' => 'players',
),
'Items' => 'items',
'Tools' => array(
'Notepad' => 'notepad',
'phpinfo' => 'phpinfo',
),
'Logs' => array(
'Logs' => 'logs',
'Reports' => 'reports',
),
);
$i = 0;
foreach ($menus as $_name => $_page) {
$has_child = is_array($_page);
if (!$has_child) {
echo '<li ';
if ($page == $_page) echo ' class="active"';
echo ">";
echo '<a href="?p=' . $_page . '"><i class="fa fa-' . (isset($icons_a[$i]) ? $icons_a[$i] : 'link') . '"></i> <span>' . $_name . '</span></a></li>';
} }
if ($has_child) { $has_child = is_array($menu['link']);
$used_menu = ""; if (!$has_child) { ?>
<li class="nav-item">
<a class="nav-link<?php echo(strpos($menu['link'], $page) !== false ? ' active' : '') ?>" href="?p=<?php echo $menu['link'] ?>">
<i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i>
<p><?php echo $menu['name'] ?></p>
</a>
</li>
<?php
} else if ($has_child) {
$used_menu = null;
$nav_construct = ''; $nav_construct = '';
foreach ($_page as $__name => $__page) { foreach ($menu['link'] as $sub_category => $sub_menu) {
$nav_construct = $nav_construct . '<li'; $nav_construct .= '<li class="nav-item"><a href="?p=' . $sub_menu['link'] . '" class="nav-link';
if ($_SERVER['QUERY_STRING'] == 'p=' . $sub_menu['link']) {
if ($page == $__page) { $nav_construct .= ' active';
$nav_construct = $nav_construct . ' class="active"';
$used_menu = true; $used_menu = true;
} }
$nav_construct = $nav_construct . '><a href="?p=' . $__page . '"><i class="fa fa-circle-o"></i> ' . $__name . '</a></li>'; $nav_construct .= '"><i class="fas fa-' . ($sub_menu['icon'] ?? 'circle') . ' nav-icon"></i><p>' . $sub_menu['name'] . '</p></a></li>';
} }
?>
echo '<li class="treeview' . (($used_menu) ? ' menu-open' : '') . '"> <li class="nav-item has-treeview<?php echo($used_menu ? ' menu-open' : '') ?>">
<a href="#"><i class="fa fa-' . (isset($icons_a[$i]) ? $icons_a[$i] : 'link') . '"></i> <span>' . $_name . '</span> <a href="#" class="nav-link<?php echo($used_menu ? ' active' : '') ?>">
<span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a> <i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i>
<ul class="treeview-menu" style="' . (($used_menu) ? ' display: block' : ' display: none') . '">'; <p><?php echo $menu['name'] ?></p><i class="right fas fa-angle-left"></i>
echo $nav_construct; </a>
echo '</ul> <ul class="nav nav-treeview">
</li>'; <?php echo $nav_construct; ?>
</ul>
</li>
<?php
} }
$i++;
} }
$query = $db->query('SELECT `name`, `page`, `flags` FROM `' . TABLE_PREFIX . 'admin_menu` ORDER BY `ordering`'); $query = $db->query('SELECT `name`, `page`, `flags` FROM `' . TABLE_PREFIX . 'admin_menu` ORDER BY `ordering`');
$menu_db = $query->fetchAll(); $menu_db = $query->fetchAll();
foreach ($menu_db as $item) { foreach ($menu_db as $item) {
if ($item['flags'] == 0 || hasFlag($item['flags'])) { if ($item['flags'] == 0 || hasFlag($item['flags'])) { ?>
echo '<li '; <li class="nav-item">
if ($page == $item['page']) echo ' class="active"'; <a class="nav-link<?php echo($page == $item['page'] ? ' active' : '') ?>" href="?p=<?php echo $item['page'] ?>">
echo ">"; <i class="nav-icon fas fa-link"></i>
echo '<a href="?p=' . $item['page'] . '"><i class="fa fa-link"></i> <span>' . $item['name'] . '</span></a></li>'; <p><?php echo $item['name'] ?></p>
</a>
</li>
<?php
} }
} }
?> ?>
</ul> </ul>
</section> </nav>
</div>
</aside> </aside>
<div class="content-wrapper"> <div class="content-wrapper" style="min-height: 823px;">
<section class="content-header"> <div class="content-header">
<h1><?php echo(isset($title) ? $title : ''); ?> <div class="container-fluid">
<small> - Admin Panel</small> <div class="row mb-2">
<div class="pull-right"> <div class="col-sm-6">
<span class="label label-<?php echo(($status['online']) ? 'success' : 'danger'); ?>"><?php echo $config['lua']['serverName'] ?></span> <h3 class="m-0 text-dark"><?php echo(isset($title) ? $title : ''); ?><small> - Admin Panel</small></h3>
</div> </div>
</h1> <div class="col-sm-6">
</section> <div class="float-sm-right d-none d-sm-inline">
<section class="content"> <span class="p-2 right badge badge-<?php echo((isset($status['online']) and $status['online']) ? 'success' : 'danger'); ?>"><?php echo $config['lua']['serverName'] ?></span>
</div>
</div>
</div>
</div>
</div>
<div class="content">
<div class="container-fluid">
<?php echo $content; ?> <?php echo $content; ?>
</section>
</div> </div>
</div>
</div>
<aside class="control-sidebar control-sidebar-dark">
<div class="p-3">
<h4>Account:</h4>
<p><h5><a href="?action=logout"><i class="fas fa-sign-out-alt text-danger"></i> Log out</h5></a>
<small>This will log you out</small></p>
</div>
<div class="p-3">
<h4>Site:</h4>
<p><h5><a href="<?php echo BASE_URL; ?>" target="_blank"><i class="far fa-eye text-blue"></i> Preview</a></h5>
<small>This will open a new tab</small></p>
</div>
<div class="p-3">
<h4>Version:</h4>
<p><h5><a href="?p=version"><i class="fas fa-code-branch"></i> <?php echo MYAAC_VERSION; ?></a></h5>
<small>Check for updates</small></p>
</div>
<div class="p-3">
<h4>Site:</h4>
<p><h5><a href="https://github.com/slawkens/myaac" target="_blank"><i class="fab fa-github"></i> Github</a></h5>
<small>Goto GitHub Page</small></p>
<p><h5><a href="http://my-aac.org/" target="_blank"><i class="fas fa-shoe-prints"></i> MyAAC Official</a></h5>
<small>Goto MyAAC Official Website</small></p>
<p><h5><a href="?p=open_source"><i class="fas fa-wrench"></i> Open Source</a></h5>
<small>View Open Source Software MyAAC is using</small></p>
</div>
</aside>
<footer class="main-footer"> <footer class="main-footer">
<div class="float-sm-right d-none d-sm-inline">
<div class="pull-right hidden-xs"> <span class="p-2 right badge badge-<?php echo((isset($status['online']) and $status['online']) ? 'success' : 'danger'); ?>"><?php echo $config['lua']['serverName'] ?></span>
<div id="status">
<?php if ($status['online']): ?>
<p class="success" style="width: 120px; text-align: center;">Server Online</p>
<?php else: ?>
<p class="error" style="width: 120px; text-align: center;">Server Offline</p>
<?php endif; ?>
</div>
</div> </div>
<?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?> <?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?>
</footer> </footer>
<div id="sidebar-overlay"></div>
<aside class="control-sidebar control-sidebar-dark">
<ul class="nav nav-tabs nav-justified control-sidebar-tabs">
<li class="active"><a href="#control-sidebar-home-tab" data-toggle="tab"><i class="fa fa-home"></i></a></li>
<li><a href="#control-sidebar-settings-tab" data-toggle="tab"><i class="fa fa-gears"></i></a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="control-sidebar-home-tab">
<h3 class="control-sidebar-heading">Account</h3>
<ul class="control-sidebar-menu">
<li>
<a href="?action=logout">
<i class="menu-icon fa fa-sign-out bg-red"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">Log out</h4>
<p>This will log you out
of <?php echo(USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()); ?></p>
</div>
</a>
</li>
</ul>
<h3 class="control-sidebar-heading">Site</h3>
<ul class="control-sidebar-menu">
<li>
<a href="<?php echo BASE_URL; ?>" target="_blank">
<i class="menu-icon fa fa-eye bg-blue"></i>
<div class="menu-info">
<h4 class="control-sidebar-subheading">Preview</h4>
<p>This will open a new tab</p>
</div>
</a>
</li>
</ul>
</div>
<div class="tab-pane" id="control-sidebar-settings-tab">
<form method="post">
<h3 class="control-sidebar-heading">Version</h3>
<div class="form-group">
<label class="control-sidebar-subheading">
<?php echo MYAAC_VERSION; ?> (<a href="?p=version">Check for updates</a>)<br/>
</label>
<label class="control-sidebar-subheading">
<p><a href="https://github.com/slawkens/myaac" target="_blank">Github</a></p>
</div>
</form>
</div>
</div>
</aside>
<div class="control-sidebar-bg"></div>
</div> </div>
<?php } <?php } else if (!$logged && !admin()) {
if (!$logged && !admin()) {
echo $content; echo $content;
} }
?> ?>
<?php
/**
* @var OTS_Account $account_logged
*/
if ($logged && admin()) {
$twig->display('admin-bar.html.twig', [
'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()
]);
}
?>
<script src="<?php echo BASE_URL; ?>tools/js/bootstrap.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/bootstrap.min.js"></script>
<script src="<?php echo BASE_URL; ?>tools/js/jquery-ui.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/jquery-ui.min.js"></script>
<script src="<?php echo BASE_URL; ?>tools/js/jquery.dataTables.min.js"></script> <?php if (isset($use_datatable)) { ?>
<script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script>
<script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script>
<?php } ?>
<script src="<?php echo BASE_URL; ?>tools/js/adminlte.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/adminlte.min.js"></script>
<?php $hooks->trigger(HOOK_ADMIN_BODY_END); ?>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,46 @@
<?php
/**
* Project: MyAAC
* Automatic Account Creator for Open Tibia Servers
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
define('MYAAC_ADMIN', true);
require '../../common.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
require SYSTEM . 'login.php';
if (!admin())
die('Access denied.');
ini_set('max_execution_time', 300);
ob_implicit_flush();
ob_end_flush();
header('X-Accel-Buffering: no');
require LIBS . 'DataLoader.php';
require LOCALE . 'en/main.php';
require LOCALE . 'en/install.php';
DataLoader::setLocale($locale);
DataLoader::load();

View File

@@ -0,0 +1,34 @@
<?php
const MYAAC_ADMIN = true;
require '../../common.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
require SYSTEM . 'login.php';
if(!admin()) {
http_response_code(500);
die('Access denied.');
}
if (!isset($_REQUEST['plugin'])) {
http_response_code(500);
die('Please enter plugin name.');
}
if (!isset($_POST['settings'])) {
http_response_code(500);
die('Please enter settings.');
}
$settings = Settings::getInstance();
$settings->save($_REQUEST['plugin'], $_POST['settings']);
$errors = $settings->getErrors();
if (count($errors) > 0) {
http_response_code(500);
die(implode('<br/>', $errors));
}
echo 'Saved at ' . date('H:i');

View File

@@ -0,0 +1,53 @@
<?php
define('MYAAC_ADMIN', true);
require '../../common.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
require SYSTEM . 'login.php';
if(!admin())
die('Access denied.');
// Don't attempt to process the upload on an OPTIONS request
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header('Access-Control-Allow-Methods: POST, OPTIONS');
return;
}
$imageFolder = BASE . EDITOR_IMAGES_DIR;
reset ($_FILES);
$temp = current($_FILES);
if (is_uploaded_file($temp['tmp_name'])) {
header('Access-Control-Allow-Credentials: true');
header('P3P: CP="There is no P3P policy."');
// Sanitize input
if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
header('HTTP/1.1 400 Invalid file name.');
return;
}
// Verify extension
$ext = strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION));
if (!in_array($ext, ['gif', 'jpg', 'png'])) {
header('HTTP/1.1 400 Invalid extension.');
return;
}
do {
$randomName = generateRandomString(8). ".$ext";
$fileToWrite = $imageFolder . $randomName;
} while (file_exists($fileToWrite));
move_uploaded_file($temp['tmp_name'], $fileToWrite);
$returnPathToImage = BASE_URL . EDITOR_IMAGES_DIR . $randomName;
echo json_encode(['location' => $returnPathToImage]);
} else {
// Notify editor that the upload failed
header('HTTP/1.1 500 Server Error');
}

View File

@@ -25,68 +25,93 @@
*/ */
if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.'); if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.');
define('MYAAC', true); const MYAAC = true;
define('MYAAC_VERSION', '0.8.21'); const MYAAC_VERSION = '0.10.0-dev';
define('DATABASE_VERSION', 33); const DATABASE_VERSION = 36;
define('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'));
define('IS_CLI', in_array(php_sapi_name(), ['cli', 'phpdb'])); define('IS_CLI', in_array(php_sapi_name(), ['cli', 'phpdb']));
// account flags // account flags
define('FLAG_ADMIN', 1); const FLAG_NONE = 0;
define('FLAG_SUPER_ADMIN', 2); const FLAG_ADMIN = 1;
define('FLAG_CONTENT_PAGES', 4); const FLAG_SUPER_ADMIN = 2;
define('FLAG_CONTENT_MAILER', 8); const FLAG_SUPER_BOTH = 3;
define('FLAG_CONTENT_NEWS', 16); const FLAG_CONTENT_PAGES = 4;
define('FLAG_CONTENT_FORUM', 32); const FLAG_CONTENT_MAILER = 8;
define('FLAG_CONTENT_COMMANDS', 64); const FLAG_CONTENT_NEWS = 16;
define('FLAG_CONTENT_SPELLS', 128); const FLAG_CONTENT_FORUM = 32;
define('FLAG_CONTENT_MONSTERS', 256); const FLAG_CONTENT_COMMANDS = 64;
define('FLAG_CONTENT_GALLERY', 512); const FLAG_CONTENT_SPELLS = 128;
define('FLAG_CONTENT_VIDEOS', 1024); const FLAG_CONTENT_MONSTERS = 256;
define('FLAG_CONTENT_FAQ', 2048); const FLAG_CONTENT_GALLERY = 512;
define('FLAG_CONTENT_MENUS', 4096); const FLAG_CONTENT_VIDEOS = 1024;
define('FLAG_CONTENT_PLAYERS', 8192); const FLAG_CONTENT_FAQ = 2048;
const FLAG_CONTENT_MENUS = 4096;
const FLAG_CONTENT_PLAYERS = 8192;
// account access types
const ACCOUNT_WEB_FLAGS = [
FLAG_NONE => 'None',
FLAG_ADMIN =>'Admin',
FLAG_SUPER_ADMIN => 'Super Admin',
FLAG_SUPER_BOTH =>'(Admin + Super Admin)',
];
// news // news
define('NEWS', 1); const NEWS = 1;
define('TICKER', 2); const TICKER = 2;
define('ARTICLE', 3); const ARTICLE = 3;
// here you can change location of admin panel
// you need also to rename folder "admin"
// this may improve security
const ADMIN_PANEL_FOLDER = 'admin';
// directories // directories
define('BASE', __DIR__ . '/'); const BASE = __DIR__ . '/';
define('ADMIN', BASE . 'admin/'); const ADMIN = BASE . ADMIN_PANEL_FOLDER . '/';
define('SYSTEM', BASE . 'system/'); const SYSTEM = BASE . 'system/';
define('CACHE', SYSTEM . 'cache/'); const CACHE = SYSTEM . 'cache/';
define('LOCALE', SYSTEM . 'locale/'); const LOCALE = SYSTEM . 'locale/';
define('LIBS', SYSTEM . 'libs/'); const LIBS = SYSTEM . 'libs/';
define('LOGS', SYSTEM . 'logs/'); const LOGS = SYSTEM . 'logs/';
define('PAGES', SYSTEM . 'pages/'); const PAGES = SYSTEM . 'pages/';
define('PLUGINS', BASE . 'plugins/'); const PLUGINS = BASE . 'plugins/';
define('TEMPLATES', BASE . 'templates/'); const TEMPLATES = BASE . 'templates/';
define('TOOLS', BASE . 'tools/'); const TOOLS = BASE . 'tools/';
const VENDOR = BASE . 'vendor/';
// other dirs
const SESSIONS_DIR = SYSTEM . 'php_sessions';
const GUILD_IMAGES_DIR = 'images/guilds/';
const EDITOR_IMAGES_DIR = 'images/editor/';
const GALLERY_DIR = 'images/gallery/';
// menu categories // menu categories
define('MENU_CATEGORY_NEWS', 1); const MENU_CATEGORY_NEWS = 1;
define('MENU_CATEGORY_ACCOUNT', 2); const MENU_CATEGORY_ACCOUNT = 2;
define('MENU_CATEGORY_COMMUNITY', 3); const MENU_CATEGORY_COMMUNITY = 3;
define('MENU_CATEGORY_FORUM', 4); const MENU_CATEGORY_FORUM = 4;
define('MENU_CATEGORY_LIBRARY', 5); const MENU_CATEGORY_LIBRARY = 5;
define('MENU_CATEGORY_SHOP', 6); const MENU_CATEGORY_SHOP = 6;
// otserv versions // otserv versions
define('OTSERV', 1); const OTSERV = 1;
define('OTSERV_06', 2); const OTSERV_06 = 2;
define('OTSERV_FIRST', OTSERV); const OTSERV_FIRST = OTSERV;
define('OTSERV_LAST', OTSERV_06); const OTSERV_LAST = OTSERV_06;
define('TFS_02', 3); const TFS_02 = 3;
define('TFS_03', 4); const TFS_03 = 4;
define('TFS_FIRST', TFS_02); const TFS_FIRST = TFS_02;
define('TFS_LAST', TFS_03); const TFS_LAST = TFS_03;
// other definitions
const ACCOUNT_NUMBER_LENGTH = 8;
if (!IS_CLI) { if (!IS_CLI) {
session_save_path(SYSTEM . 'php_sessions'); session_save_path(SESSIONS_DIR);
session_start(); session_start();
} }
@@ -97,13 +122,9 @@ $size = count($tmp) - 1;
for($i = 1; $i < $size; $i++) for($i = 1; $i < $size; $i++)
$basedir .= '/' . $tmp[$i]; $basedir .= '/' . $tmp[$i];
$basedir = str_replace(array('/admin', '/install', '/tools'), '', $basedir); $basedir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $basedir);
define('BASE_DIR', $basedir); define('BASE_DIR', $basedir);
if (file_exists(BASE . 'config.local.php') && !defined('MYAAC_INSTALL')) {
require BASE . 'config.local.php';
}
if(!IS_CLI) { if(!IS_CLI) {
if (isset($_SERVER['HTTP_HOST'][0])) { if (isset($_SERVER['HTTP_HOST'][0])) {
$baseHost = $_SERVER['HTTP_HOST']; $baseHost = $_SERVER['HTTP_HOST'];
@@ -115,21 +136,32 @@ 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/'); define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/');
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); //define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
if(@$config['env'] === 'dev') {
require SYSTEM . 'exception.php';
} }
}
require SYSTEM . 'autoload.php';
function isHttps(): bool if (file_exists(BASE . 'config.local.php')) {
{ require BASE . 'config.local.php';
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);
} }
ini_set('log_errors', 1);
if(@$config['env'] === 'dev') {
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
}
else {
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
}
$autoloadFile = VENDOR . 'autoload.php';
if (!is_file($autoloadFile)) {
throw new RuntimeException('The vendor folder is missing. Please download Composer: <a href="https://getcomposer.org/download">https://getcomposer.org/download</a>, install it and execute in the main MyAAC directory this command: <b>composer install</b>. Or download MyAAC from <a href="https://github.com/slawkens/myaac/releases">GitHub releases</a>, which includes Vendor folder.');
}
require $autoloadFile;

19
composer.json Normal file
View File

@@ -0,0 +1,19 @@
{
"require": {
"php": "^7.2.5 || ^8.0",
"ext-pdo": "*",
"ext-pdo_mysql": "*",
"ext-json": "*",
"ext-xml": "*",
"ext-dom": "*",
"phpmailer/phpmailer": "^6.1",
"composer/semver": "^3.2",
"twig/twig": "^2.0",
"erusev/parsedown": "^1.7",
"nikic/fast-route": "^1.3",
"matomo/device-detector": "^6.0"
},
"require-dev": {
"filp/whoops": "^2.15"
}
}

View File

@@ -1,302 +0,0 @@
<?php
/**
* This is MyAAC's Main Configuration file
*
* All the default values are kept here, you should not modify it but use
* a config.local.php file instead to override the settings from here.
*
* This is a piece of PHP code so PHP syntax applies!
* For boolean values please use true/false.
*
* Minimally 'server_path' directive have to be filled, other options are optional.
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
$config = array(
// directories & files
'server_path' => '', // path to the server directory (same directory where config file is located)
/**
* Environment Setting
*
* if you use this script on your live server - set to 'prod' (production)
* if you want to test and debug the script locally, or develop plugins, set to 'dev' (development)
* WARNING: on 'dev' cache is disabled, so site will be significantly slower !!!
* WARNING2: on 'dev' all PHP errors/warnings are displayed
* Recommended: 'prod' cause of speed (page load time is better)
*/
'env' => 'prod', // 'prod' for production and 'dev' for development
'template' => 'kathrine', // template used by website (kathrine, tibiacom)
'template_allow_change' => true, // allow users to choose their own template while browsing website?
'vocations_amount' => 4, // how much basic vocations your server got (without promotion)
// what client version are you using on this OT?
// used for the Downloads page and some templates aswell
'client' => 1098, // 954 = client 9.54
'session_prefix' => 'myaac_', // must be unique for every site on your server
'friendly_urls' => false, // mod_rewrite is required for this, it makes links looks more elegant to eye, and also are SEO friendly (example: https://my-aac.org/guilds/Testing instead of https://my-aac.org/?subtopic=guilds&name=Testing). Remember to rename .htaccess.dist to .htaccess
'gzip_output' => false, // gzip page content before sending it to the browser, uses less bandwidth but more cpu cycles
// gesior backward support (templates & pages)
// allows using gesior templates and pages with myaac
// might bring some performance when disabled
'backward_support' => true,
// head options (html)
'meta_description' => 'Tibia is a free massive multiplayer online role playing game (MMORPG).', // description of the site
'meta_keywords' => 'free online game, free multiplayer game, ots, open tibia server', // keywords list separated by commas
'title_separator' => ' - ',
// footer
'footer' => ''/*'<br/>Your Server &copy; 2016. All rights reserved.'*/,
'language' => 'en', // default language (currently only 'en' available)
'language_allow_change' => false,
'visitors_counter' => true,
'visitors_counter_ttl' => 10, // how long visitor will be marked as online (in minutes)
'views_counter' => true,
// cache system. by default file cache is used
'cache_engine' => 'auto', // apc, apcu, eaccelerator, xcache, file, auto, or blank to disable.
'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache)
// database details (leave blank for auto detect from config.lua)
'database_host' => '',
'database_port' => '', // leave blank to default 3306
'database_user' => '',
'database_password' => '',
'database_name' => '',
'database_log' => false, // should database queries be logged and and saved into system/logs/database.log?
'database_socket' => '', // set if you want to connect to database through socket (example: /var/run/mysqld/mysqld.sock)
'database_persistent' => false, // use database permanent connection (like server), may speed up your site
'database_encryption' => 'sha1',
// multiworld system (only TFS 0.3)
'multiworld' => false, // use multiworld system?
'worlds' => array( // list of worlds
//'1' => 'Your World Name',
//'2' => 'Your Second World Name'
),
// images
'outfit_images_url' => 'https://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit
'item_images_url' => 'https://item-images.ots.me/1092/', // set to images/items if you host your own items in images folder
// account
'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager)
'account_create_auto_login' => false, // auto login after creating account?
'account_create_character_create' => true, // allow directly to create character on create account page?
'account_mail_verify' => false, // force users to confirm their email addresses when registering
'account_mail_confirmed_reward' => [ // reward users for confirming their E-Mails
// account_mail_verify needs to be enabled too
'premium_days' => 0,
'premium_points' => 0,
'coins' => 0,
'message' => 'You received %d %s for confirming your E-Mail address.' // example: You received 20 premium points for confirming your E-Mail address.
],
'account_mail_unique' => true, // email addresses cannot be duplicated? (one account = one email)
'account_premium_days' => 0, // default premium days on new account
'account_premium_points' => 0, // default premium points on new account
'account_welcome_mail' => true, // send welcome email when user registers
'account_mail_change' => 2, // how many days user need to change email to account - block hackers
'account_country' => true, // user will be able to set country of origin when registering account, this information will be viewable in others places aswell
'account_country_recognize' => true, // should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io
'account_change_character_name' => false, // can user change their character name for premium points?
'account_change_character_name_points' => 30, // cost of name change
'account_change_character_sex' => false, // can user change their character sex for premium points?
'account_change_character_sex_points' => 30, // cost of sex change
'characters_per_account' => 10, // max. number of characters per account
// mail
'mail_enabled' => false, // is aac maker configured to send e-mails?
'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:)
'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent
'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function
'plain' => ""/*"--\nMy Server,\nhttp://www.myserver.com"*/,
'html' => ''/*'<br/>My Server,\n<a href="http://www.myserver.com">myserver.com</a>'*/
),
'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function, set to true if you use GMail or Microsoft Outlook)
'smtp_host' => '', // mail host. smtp.gmail.com for GMail / smtp-mail.outlook.com for Microsoft Outlook
'smtp_port' => 25, // 25 (default) / 465 (ssl, GMail) / 587 (tls, Microsoft Outlook)
'smtp_auth' => true, // need authorization?
'smtp_user' => 'admin@example.org', // here your email username
'smtp_pass' => '',
'smtp_secure' => '', // What kind of encryption to use on the SMTP connection. Options: '', 'ssl' (GMail) or 'tls' (Microsoft Outlook)
'smtp_debug' => false, // set true to debug (you will see more info in error.log)
// reCAPTCHA (prevent spam bots)
'recaptcha_enabled' => false, // enable recaptcha verification code
'recaptcha_site_key' => '', // get your own site and secret keys at https://www.google.com/recaptcha
'recaptcha_secret_key' => '',
'recaptcha_theme' => 'light', // light, dark
//
'generate_new_reckey' => true, // let player generate new recovery key, he will receive e-mail with new rec key (not display on page, hacker can't generate rec key)
'generate_new_reckey_price' => 20, // price for new recovery key
'send_mail_when_change_password' => true, // send e-mail with new password when change password to account
'send_mail_when_generate_reckey' => true, // send e-mail with rec key (key is displayed on page anyway when generate)
// genders (aka sex)
'genders' => array(
0 => 'Female',
1 => 'Male'
),
// new character config
'character_samples' => array( // vocations, format: ID_of_vocation => 'Name of Character to copy'
//0 => 'Rook Sample',
1 => 'Sorcerer Sample',
2 => 'Druid Sample',
3 => 'Paladin Sample',
4 => 'Knight Sample'
),
'use_character_sample_skills' => false,
// it must show limited number of players after using search in character page
'characters_search_limit' => 15,
// town list used when creating character
// won't be displayed if there is only one item (rookgaard for example)
'character_towns' => array(1),
// characters length
// This is the minimum and the maximum length that a player can create a character. It is highly recommend the maximum length to be 21.
'character_name_min_length' => 4,
'character_name_max_length' => 21,
// list of towns
// if you use TFS 1.3 with support for 'towns' table in database, then you can ignore this - it will be configured automatically (generated from your .OTBM map)
'towns' => array(
0 => 'No town',
1 => 'Sample town'
),
// guilds
'guild_management' => true, // enable guild management system on the site?
'guild_need_level' => 1, // min. level to form a guild
'guild_need_premium' => true, // require premium account to form a guild?
'guild_image_size_kb' => 80, // maximum size of the guild logo image in KB (kilobytes)
'guild_description_chars_limit' => 1000, // limit of guild description
'guild_description_lines_limit' => 6, // limit of lines, if description has more lines it will be showed as long text, without 'enters'
'guild_motd_chars_limit' => 150, // limit of MOTD (message of the day) that is shown later in the game on the guild channel
// online page
'online_record' => true, // display players record?
'online_vocations' => false, // display vocation statistics?
'online_vocations_images' => false, // display vocation images?
'online_skulls' => false, // display skull images
'online_outfit' => true,
'online_afk' => false,
// support list page
'team_style' => 2, // 1/2 (1 - normal table, 2 - in boxes, grouped by group id)
'team_display_status' => true,
'team_display_lastlogin' => true,
'team_display_world' => false,
'team_display_outfit' => true,
// bans page
'bans_limit' => 50,
'bans_display_all' => true, // should all bans be displayed? (sorted page by page)
// highscores page
'highscores_vocation_box' => true, // show 'Choose a vocation' box on the highscores (allowing peoples to sort highscores by vocation)?
'highscores_vocation' => true, // show player vocation under his nickname?
'highscores_frags' => false, // show 'Frags' tab (best fraggers on the server)? Only 0.3
'highscores_balance' => false, // show 'Balance' tab (richest players on the server)
'highscores_outfit' => true, // show player outfit?
'highscores_country_box' => false, // doesnt work yet! (not implemented)
'highscores_groups_hidden' => 3, // this group id and higher won't be shown on the highscores
'highscores_ids_hidden' => array(0), // this ids of players will be hidden on the highscores (should be ids of samples)
'highscores_length' => 100, // how many records per page on highscores
// characters page
'characters' => array( // what things to display on character view page (true/false in each option)
'level' => true,
'experience' => false,
'magic_level' => false,
'balance' => false,
'marriage_info' => true, // only 0.3
'outfit' => true,
'creation_date' => true,
'quests' => true,
'skills' => true,
'equipment' => true,
'frags' => false,
'deleted' => false, // should deleted characters from same account be still listed on the list of characters? When enabled it will show that character is "[DELETED]"
),
'quests' => array(
//'Some Quest' => 123,
//'Some Quest Two' => 456,
), // quests list (displayed in character view), name => storage
'signature_enabled' => true,
'signature_type' => 'tibian', // signature engine to use: tibian, mango, gesior
'signature_cache_time' => 5, // how long to store cached file (in minutes), default 5 minutes
'signature_browser_cache' => 60, // how long to cache by browser (in minutes), default 1 hour
// news page
'news_limit' => 5, // limit of news on the latest news page
'news_ticker_limit' => 5, // limit of news in tickers (mini news) (0 to disable)
'news_date_format' => 'j.n.Y', // check php manual date() function for more info about this
'news_author' => true, // show author of the news
// gifts/shop system
'gifts_system' => false,
// support/system
'bug_report' => true, // this configurable has no effect, its always enabled
// forum
'forum' => 'site', // link to the server forum, set to "site" if you want to use build in forum system, otherwise leave empty if you aren't going to use any forum
'forum_level_required' => 0, // level required to post, 0 to disable
'forum_post_interval' => 30, // in seconds
'forum_posts_per_page' => 20,
'forum_threads_per_page' => 20,
// uncomment to force use table for forum
//'forum_table_prefix' => 'z_', // what forum mysql table to use, z_ (for gesior old forum) or myaac_ (for myaac)
// last kills
'last_kills_limit' => 50, // max. number of deaths shown on the last kills page
// status, took automatically from config file if empty
'status_enabled' => true, // you can disable status checking by settings this to "false"
'status_ip' => '127.0.0.1',
'status_port' => '',
'status_timeout' => 1.0, // how long to wait for the initial response from the server (default: 1 second)
// how often to connect to server and update status (default: every minute)
// if your status timeout in config.lua is bigger, that it will be used instead
// when server is offline, it will be checked every time web refreshes, ignoring this variable
'status_interval' => 60,
// admin panel
'admin_panel_modules' => 'lastlogin,points,coins',
// other
'anonymous_usage_statistics' => true,
'email_lai_sec_interval' => 60, // time in seconds between e-mails to one account from lost account interface, block spam
'google_analytics_id' => '', // e.g.: UA-XXXXXXX-X
'experiencetable_columns' => 3, // how many columns to display in experience table page. * experiencetable_rows, 5 = 500 (will show up to 500 level)
'experiencetable_rows' => 200, // till how many levels in one column
'date_timezone' => 'Europe/Berlin', // more info at http://php.net/manual/en/timezones.php
'footer_show_load_time' => true, // display load time of the page in the footer
'npc' => array(),
// character name blocked
'character_name_blocked' => array(
'prefix' => array(),
'names' => array(),
'words' => array(),
),
);

9
cypress.config.js Normal file
View File

@@ -0,0 +1,9 @@
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});

View File

@@ -0,0 +1,75 @@
describe('Install MyAAC', () => {
beforeEach(() => {
// Cypress starts out with a blank slate for each test
// so we must tell it to visit our website with the `cy.visit()` command.
// Since we want to visit the same URL at the start of all our tests,
// we include it in our beforeEach function so that it runs before each test
cy.visit(Cypress.env('URL'))
})
it('Go through installer', () => {
cy.visit(Cypress.env('URL') + '/install/?step=welcome')
cy.wait(1000)
cy.screenshot('install-welcome')
// step 1 - Welcome
cy.get('select[name="lang"]').select('en')
//cy.get('input[type=button]').contains('Next »').click()
cy.get('form').submit()
// step 2 - License
// just skip
cy.contains('GNU/GPL License');
cy.get('form').submit()
// step 3 - Requirements
cy.contains('Requirements check');
cy.get('#step').then(elem => {
elem.val('config');
});
cy.get('form').submit()
// step 4 - Configuration
cy.contains('Basic configuration');
cy.get('#vars_server_path').click().clear().type(Cypress.env('SERVER_PATH'))
cy.get('#vars_mail_admin').click().clear().type('noone@example.net')
cy.get('[type="checkbox"]').uncheck() // usage statistics uncheck
cy.wait(1000)
cy.get('form').submit()
// check if there is any error
// step 5 - Import Schema
cy.contains('Import MySQL schema');
// AAC is not installed yet, this message should not come
cy.contains('Seems AAC is already installed. Skipping importing MySQL schema..').should('not.exist')
cy.contains('[class="alert alert-success"]', 'Local configuration has been saved into file: config.local.php').should('be.visible')
cy.get('form').submit()
// step 6 - Admin Account
cy.get('#vars_email').click().clear().type('admin@my-aac.org')
cy.get('#vars_account').click().clear().type('admin')
cy.get('#vars_password').click().clear().type('test1234')
cy.get('#vars_password_confirm').click().clear().type('test1234')
cy.get('#vars_player_name').click().clear().type('Admin')
cy.get('form').submit()
cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 30000 }).should('be.visible')
cy.screenshot('install-finish')
})
})

View File

@@ -0,0 +1,33 @@
describe('Create Account Page', () => {
beforeEach(() => {
// Cypress starts out with a blank slate for each test
// so we must tell it to visit our website with the `cy.visit()` command.
// Since we want to visit the same URL at the start of all our tests,
// we include it in our beforeEach function so that it runs before each test
cy.visit(Cypress.env('URL') + '/index.php/account/create')
})
it('Create Test Account', () => {
cy.screenshot('create-account-page')
cy.get('#account_input').type('tester')
cy.get('#email').type('tester@example.com')
cy.get('#password').type('test1234')
cy.get('#password2').type('test1234')
cy.get('#character_name').type('Slaw')
cy.get('#sex1').check()
cy.get('#vocation1').check()
cy.get('#accept_rules').check()
cy.get('#createaccount').submit()
// no errors please
cy.contains('The Following Errors Have Occurred:').should('not.exist')
// ss of post page
cy.screenshot('create-account-page-post')
})
})

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

20
cypress/support/e2e.js Normal file
View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 B

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 783 B

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 789 B

After

Width:  |  Height:  |  Size: 735 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 615 B

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 816 B

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 476 B

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 809 B

After

Width:  |  Height:  |  Size: 709 B

270
index.php
View File

@@ -28,18 +28,22 @@ require_once 'common.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';
$uri = $_SERVER['REQUEST_URI']; $uri = $_SERVER['REQUEST_URI'];
if(false !== strpos($uri, 'index.php')) {
$uri = str_replace_first('/index.php', '', $uri);
}
$tmp = BASE_DIR; if(0 === strpos($uri, '/')) {
if(!empty($tmp))
$uri = str_replace(BASE_DIR . '/', '', $uri);
else
$uri = str_replace_first('/', '', $uri); $uri = str_replace_first('/', '', $uri);
}
$uri = str_replace(array('index.php/', '?'), '', $uri); if(preg_match("/^[A-Za-z0-9-_%'+\/]+\.png$/i", $uri)) {
define('URI', $uri); if (!empty(BASE_DIR)) {
$tmp = explode('.', str_replace_first(str_replace_first('/', '', BASE_DIR) . '/', '', $uri));
if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) { }
else {
$tmp = explode('.', $uri); $tmp = explode('.', $uri);
}
$_REQUEST['name'] = urldecode($tmp[0]); $_REQUEST['name'] = urldecode($tmp[0]);
chdir(TOOLS . 'signature'); chdir(TOOLS . 'signature');
@@ -47,168 +51,44 @@ if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) {
exit(); exit();
} }
if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) { if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) {
http_response_code(404); http_response_code(404);
exit; exit;
} }
if(file_exists(BASE . 'config.local.php')) {
require_once BASE . 'config.local.php';
}
ini_set('log_errors', 1);
if(config('env') === 'dev') {
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
}
else {
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
}
if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install')) if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install'))
{ {
header('Location: ' . BASE_URL . 'install/'); header('Location: ' . BASE_URL . 'install/');
throw new RuntimeException('Setup detected that <b>install/</b> directory exists. Please visit <a href="' . BASE_URL . 'install">this</a> url to start MyAAC Installation.<br/>Delete <b>install/</b> directory if you already installed MyAAC.<br/>Remember to REFRESH this page when you\'re done!'); 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();
require_once SYSTEM . 'init.php'; require_once SYSTEM . 'init.php';
require_once SYSTEM . 'template.php';
// verify myaac tables exists in database // verify myaac tables exists in database
if(!$db->hasTable('myaac_account_actions')) { 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.'); 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.');
} }
$found = false;
if(empty($uri) || isset($_REQUEST['template'])) {
$_REQUEST['p'] = 'news';
$found = true;
}
else {
$tmp = strtolower($uri);
if (!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(TEMPLATES . $template_name . '/pages/' . $tmp . '.php')) {
$_REQUEST['p'] = $uri;
$found = true;
}
else if (!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(SYSTEM . 'pages/' . $tmp . '.php')) {
$_REQUEST['p'] = $uri;
$found = true;
}
else {
$rules = array(
'/^account\/manage\/?$/' => array('subtopic' => 'accountmanagement'),
'/^account\/create\/?$/' => array('subtopic' => 'createaccount'),
'/^account\/lost\/?$/' => array('subtopic' => 'lostaccount'),
'/^account\/logout\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'logout'),
'/^account\/password\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_password'),
'/^account\/register\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register'),
'/^account\/register\/new\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register_new'),
'/^account\/email\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_email'),
'/^account\/info\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_info'),
'/^account\/character\/create\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'create_character'),
'/^account\/character\/name\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_name'),
'/^account\/character\/sex\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_sex'),
'/^account\/character\/delete\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'delete_character'),
'/^account\/character\/comment\/[A-Za-z0-9-_%+\']+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment', 'name' => '$3'),
'/^account\/character\/comment\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment'),
'/^account\/confirm_email\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'confirm_email', 'v' => '$2'),
'/^characters\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'characters', 'name' => '$1'),
'/^changelog\/[0-9]+\/?$/' => array('subtopic' => 'changelog', 'page' => '$1'),
'/^commands\/add\/?$/' => array('subtopic' => 'commands', 'action' => 'add'),
'/^commands\/edit\/?$/' => array('subtopic' => 'commands', 'action' => 'edit'),
'/^faq\/add\/?$/' => array('subtopic' => 'faq', 'action' => 'add'),
'/^faq\/edit\/?$/' => array('subtopic' => 'faq', 'action' => 'edit'),
'/^forum\/add_board\/?$/' => array('subtopic' => 'forum', 'action' => 'add_board'),#
'/^forum\/edit_board\/?$/' => array('subtopic' => 'forum', 'action' => 'edit_board'),
'/^forum\/board\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2'),
'/^forum\/board\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2', 'page' => '$3'),
'/^forum\/thread\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2'),
'/^forum\/thread\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2', 'page' => '$3'),
'/^gallery\/add\/?$/' => array('subtopic' => 'gallery', 'action' => 'add'),
'/^gallery\/edit\/?$/' => array('subtopic' => 'gallery', 'action' => 'edit'),
'/^gallery\/[0-9]+\/?$/' => array('subtopic' => 'gallery', 'image' => '$1'),
'/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'),
'/^guilds\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'guilds', 'action' => 'show', 'guild' => '$1'),
'/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2', 'page' => '$3'),
'/^highscores\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'page' => '$2'),
'/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2'),
'/^highscores\/[A-Za-z0-9-_\']+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1'),
'/^news\/add\/?$/' => array('subtopic' => 'news', 'action' => 'add'),
'/^news\/edit\/?$/' => array('subtopic' => 'news', 'action' => 'edit'),
'/^news\/archive\/?$/' => array('subtopic' => 'newsarchive'),
'/^news\/archive\/[0-9]+\/?$/' => array('subtopic' => 'newsarchive', 'id' => '$2'),
'/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'),
'/^spells\/[A-Za-z0-9-_%]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'spells', 'vocation' => '$1', 'order' => '$2'),
'/^houses\/view\/?$/' => array('subtopic' => 'houses', 'page' => 'view')
);
foreach ($rules as $rule => $redirect) {
if (preg_match($rule, $uri)) {
$tmp = explode('/', $uri);
/* @var $redirect array */
foreach ($redirect as $key => $value) {
if (strpos($value, '$') !== false) {
$value = str_replace('$' . $value[1], $tmp[$value[1]], $value);
}
$_REQUEST[$key] = $value;
$_GET[$key] = $value;
}
$found = true;
break;
}
}
}
}
// handle ?fbclid=x, etc. (show news page)
if (!$found && count($_GET) > 0 && !isset($_REQUEST['subtopic']) && !isset($_REQUEST['p']) && !in_array($_SERVER['QUERY_STRING'], getDatabasePages())) {
$_REQUEST['p'] = $_REQUEST['subtopic'] = 'news';
$found = true;
}
// define page visited, so it can be used within events system
$page = isset($_REQUEST['subtopic']) ? $_REQUEST['subtopic'] : (isset($_REQUEST['p']) ? $_REQUEST['p'] : '');
if(empty($page) || !preg_match('/^[A-z0-9\_\-]+$/', $page)) {
$tmp = URI;
if(!empty($tmp)) {
$page = $tmp;
}
else {
if(!$found)
$page = '404';
else
$page = 'news';
}
}
$page = strtolower($page);
define('PAGE', $page);
$template_place_holders = array();
// event system // event system
require_once SYSTEM . 'hooks.php'; require_once SYSTEM . 'hooks.php';
$hooks = new Hooks(); $hooks = new Hooks();
$hooks->load(); $hooks->load();
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';
$twig->addGlobal('config', $config); $twig->addGlobal('config', $config);
$twig->addGlobal('status', $status); $twig->addGlobal('status', $status);
require SYSTEM . 'migrate.php'; require_once SYSTEM . 'router.php';
$hooks->trigger(HOOK_STARTUP); $hooks->trigger(HOOK_STARTUP);
// anonymous usage statistics // anonymous usage statistics
// sent only when user agrees // sent only when user agrees
if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_statistics']) { if(setting('core.anonymous_usage_statistics')) {
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days $report_time = 30 * 24 * 60 * 60; // report one time per 30 days
$should_report = true; $should_report = true;
@@ -241,53 +121,22 @@ if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_stat
} }
} }
if($config['views_counter']) if(setting('core.views_counter'))
require_once SYSTEM . 'counter.php'; require_once SYSTEM . 'counter.php';
if($config['visitors_counter']) if(setting('core.visitors_counter')) {
{
require_once SYSTEM . 'libs/visitors.php'; require_once SYSTEM . 'libs/visitors.php';
$visitors = new Visitors($config['visitors_counter_ttl']); $visitors = new Visitors(setting('core.visitors_counter_ttl'));
} }
// page content loading
if(!isset($content[0]))
$content = '';
$load_it = true;
// check if site has been closed
$site_closed = false;
if(fetchDatabaseConfig('site_closed', $site_closed)) {
$site_closed = ($site_closed == 1);
if($site_closed) {
if(!admin())
{
$title = getDatabaseConfig('site_closed_title');
$content .= '<p class="note">' . getDatabaseConfig('site_closed_message') . '</p><br/>';
$load_it = false;
}
if(!$logged)
{
ob_start();
require SYSTEM . 'pages/accountmanagement.php';
$content .= ob_get_contents();
ob_end_clean();
$load_it = false;
}
}
}
define('SITE_CLOSED', $site_closed);
// backward support for gesior // backward support for gesior
if($config['backward_support']) { if(setting('core.backward_support')) {
define('INITIALIZED', true); define('INITIALIZED', true);
$SQL = $db; $SQL = $db;
$layout_header = template_header(); $layout_header = template_header();
$layout_name = $template_path; $layout_name = $template_path;
$news_content = ''; $news_content = '';
$tickers_content = ''; $tickers_content = '';
$subtopic = PAGE;
$main_content = ''; $main_content = '';
$config['access_admin_panel'] = 2; $config['access_admin_panel'] = 2;
@@ -297,7 +146,7 @@ if($config['backward_support']) {
$config['site'] = &$config; $config['site'] = &$config;
$config['server'] = &$config['lua']; $config['server'] = &$config['lua'];
$config['site']['shop_system'] = $config['gifts_system']; $config['site']['shop_system'] = setting('core.gifts_system');
$config['site']['gallery_page'] = true; $config['site']['gallery_page'] = true;
if(!isset($config['vdarkborder'])) if(!isset($config['vdarkborder']))
@@ -311,74 +160,23 @@ if($config['backward_support']) {
$config['site']['serverinfo_page'] = true; $config['site']['serverinfo_page'] = true;
$config['site']['screenshot_page'] = true; $config['site']['screenshot_page'] = true;
if($config['forum'] != '') $forumSetting = setting('core.forum');
$config['forum_link'] = (strtolower($config['forum']) === 'site' ? getLink('forum') : $config['forum']); if($forumSetting != '')
$config['forum_link'] = (strtolower($forumSetting) === 'site' ? getLink('forum') : $forumSetting);
foreach($status as $key => $value) foreach($status as $key => $value)
$config['status']['serverStatus_' . $key] = $value; $config['status']['serverStatus_' . $key] = $value;
} }
if($load_it) /**
{ * @var OTS_Account $account_logged
if(SITE_CLOSED && admin()) */
$content .= '<p class="note">Site is under maintenance (closed mode). Only privileged users can see it.</p>'; if ($logged && admin()) {
$content .= $twig->render('admin-bar.html.twig', [
if($config['backward_support']) { 'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()
require SYSTEM . 'compat/pages.php'; ]);
require SYSTEM . 'compat/classes.php';
} }
$title_full = (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];
$ignore = false;
$logged_access = 1;
if($logged && $account_logged && $account_logged->isLoaded()) {
$logged_access = $account_logged->getAccess();
}
$success = false;
$tmp_content = getCustomPage($page, $success);
if($success) {
$content .= $tmp_content;
if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) {
$pageInfo = getCustomPageInfo($page);
$content = $twig->render('admin.pages.links.html.twig', array(
'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0')
)) . $content;
}
} else {
$file = TEMPLATES . "$template_name/pages/$page.php";
if(!@file_exists($file) || preg_match('/[^A-z0-9_\-]/', $page)) {
$file = SYSTEM . "pages/$page.php";
if(!@file_exists($file) || preg_match('/[^A-z0-9_\-]/', $page)) {
$page = '404';
$file = SYSTEM . 'pages/404.php';
}
}
}
ob_start();
if($hooks->trigger(HOOK_BEFORE_PAGE)) {
if(!$ignore)
require $file;
}
if($config['backward_support'] && isset($main_content[0]))
$content .= $main_content;
$content .= ob_get_contents();
ob_end_clean();
$hooks->trigger(HOOK_AFTER_PAGE);
}
if($config['backward_support']) {
$main_content = $content;
if(!isset($title))
$title = ucfirst($page);
$topic = $title;
}
$title_full = (isset($title) ? $title . $config['title_separator'] : '') . $config['lua']['serverName'];
require $template_path . '/' . $template_index; require $template_path . '/' . $template_index;
echo base64_decode('PCEtLSBQb3dlcmVkIGJ5IE15QUFDIDo6IGh0dHBzOi8vd3d3Lm15LWFhYy5vcmcvIC0tPg==') . PHP_EOL; echo base64_decode('PCEtLSBQb3dlcmVkIGJ5IE15QUFDIDo6IGh0dHBzOi8vd3d3Lm15LWFhYy5vcmcvIC0tPg==') . PHP_EOL;

View File

@@ -6,12 +6,18 @@ $ots = POT::getInstance();
require SYSTEM . 'database.php'; require SYSTEM . 'database.php';
if(!isset($db)) { if(!isset($db)) {
$database_error = $locale['step_database_error_mysql_connect'] . '<br/>' . $database_error = '<p class="lead">' . $locale['step_database_error_mysql_connect'] . '</p>';
$locale['step_database_error_mysql_connect_2'] .
'<ul>' . $database_error .= '<p>' . $locale['step_database_error_mysql_connect_2'] . '</p>';
'<li>' . $locale['step_database_error_mysql_connect_3'] . '</li>' .
'<li>' . $locale['step_database_error_mysql_connect_4'] . '</li>' . $database_error .= '<ul class="list-group">' .
'</ul>' . '<br/>' . $error; '<li class="list-group-item list-group-item-warning">' . $locale['step_database_error_mysql_connect_3'] . '</li>' .
'<li class="list-group-item list-group-item-warning">' . $locale['step_database_error_mysql_connect_4'] . '</li>' .
'</ul>';
$database_error .= '<div class="alert alert-danger mt-4">
<span>' . $error . '</span>
</div>';
} }
else { else {
if($db->hasTable('accounts')) if($db->hasTable('accounts'))

View File

@@ -62,9 +62,9 @@ function next_buttons($previous = true, $next = true)
$ret .= '<input class="button" type="submit" onclick="document.getElementById(\'step\').value=\'' . $steps[$i + 1] . '\';" value="' . $locale['next'] . '" />'; $ret .= '<input class="button" type="submit" onclick="document.getElementById(\'step\').value=\'' . $steps[$i + 1] . '\';" value="' . $locale['next'] . '" />';
*/ */
if($previous) if($previous)
$ret .= '<input type="button" class="button" onclick="document.getElementById(\'step\').value=\'' . $steps[$i - 1] . '\'; this.form.submit();" value="&laquo; ' . $locale['previous'] . '" />'; $ret .= '<input type="button" class="button btn btn-primary m-2" onclick="document.getElementById(\'step\').value=\'' . $steps[$i - 1] . '\'; this.form.submit();" value="&laquo; ' . $locale['previous'] . '" />';
if($next) if($next)
$ret .= '<input type="button" class="button" onclick="document.getElementById(\'step\').value=\'' . $steps[$i + 1] . '\'; this.form.submit(); " value="' . $locale['next'] . ' &raquo;" />'; $ret .= '<input type="button" class="button btn btn-primary m-2" onclick="document.getElementById(\'step\').value=\'' . $steps[$i + 1] . '\'; this.form.submit(); " value="' . $locale['next'] . ' &raquo;" />';
$ret .= '</div>'; $ret .= '</div>';
return $ret; return $ret;

View File

@@ -1,4 +1,4 @@
SET @myaac_database_version = 33; SET @myaac_database_version = 36;
CREATE TABLE `myaac_account_actions` CREATE TABLE `myaac_account_actions`
( (
@@ -203,25 +203,29 @@ CREATE TABLE `myaac_monsters` (
`mana` int(11) NOT NULL DEFAULT 0, `mana` int(11) NOT NULL DEFAULT 0,
`exp` int(11) NOT NULL, `exp` int(11) NOT NULL,
`health` int(11) NOT NULL, `health` int(11) NOT NULL,
`look` VARCHAR(255) NOT NULL DEFAULT '',
`speed_lvl` int(11) NOT NULL default 1, `speed_lvl` int(11) NOT NULL default 1,
`use_haste` tinyint(1) NOT NULL, `use_haste` tinyint(1) NOT NULL,
`voices` text NOT NULL, `voices` text NOT NULL,
`immunities` varchar(255) NOT NULL, `immunities` varchar(255) NOT NULL,
`elements` TEXT NOT NULL,
`summonable` tinyint(1) NOT NULL, `summonable` tinyint(1) NOT NULL,
`convinceable` tinyint(1) NOT NULL, `convinceable` tinyint(1) NOT NULL,
`pushable` TINYINT(1) NOT NULL DEFAULT '0',
`canpushitems` TINYINT(1) NOT NULL DEFAULT '0',
`canwalkonenergy` TINYINT(1) NOT NULL DEFAULT '0',
`canwalkonpoison` TINYINT(1) NOT NULL DEFAULT '0',
`canwalkonfire` TINYINT(1) NOT NULL DEFAULT '0',
`runonhealth` TINYINT(1) NOT NULL DEFAULT '0',
`hostile` TINYINT(1) NOT NULL DEFAULT '0',
`attackable` TINYINT(1) NOT NULL DEFAULT '0',
`rewardboss` TINYINT(1) NOT NULL DEFAULT '0',
`defense` INT(11) NOT NULL DEFAULT '0',
`armor` INT(11) NOT NULL DEFAULT '0',
`canpushcreatures` TINYINT(1) NOT NULL DEFAULT '0',
`race` varchar(255) NOT NULL, `race` varchar(255) NOT NULL,
`loot` text NOT NULL, `loot` text NOT NULL,
PRIMARY KEY (`id`) `summons` TEXT NOT NULL,
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE `myaac_videos`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL DEFAULT '',
`youtube_id` VARCHAR(20) NOT NULL,
`author` VARCHAR(50) NOT NULL DEFAULT '',
`ordering` INT(11) 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;
@@ -299,6 +303,16 @@ CREATE TABLE `myaac_gallery`
INSERT INTO `myaac_gallery` (`id`, `ordering`, `comment`, `image`, `thumb`, `author`) VALUES (NULL, 1, 'Demon', 'images/gallery/demon.jpg', 'images/gallery/demon_thumb.gif', 'MyAAC'); INSERT INTO `myaac_gallery` (`id`, `ordering`, `comment`, `image`, `thumb`, `author`) VALUES (NULL, 1, 'Demon', 'images/gallery/demon.jpg', 'images/gallery/demon_thumb.gif', 'MyAAC');
CREATE TABLE `myaac_settings`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT '',
`key` VARCHAR(255) NOT NULL DEFAULT '',
`value` TEXT NOT NULL,
PRIMARY KEY (`id`),
KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE `myaac_spells` CREATE TABLE `myaac_spells`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` INT(11) NOT NULL AUTO_INCREMENT,
@@ -327,6 +341,7 @@ CREATE TABLE `myaac_visitors`
`ip` VARCHAR(45) NOT NULL, `ip` VARCHAR(45) NOT NULL,
`lastvisit` INT(11) NOT NULL DEFAULT 0, `lastvisit` INT(11) NOT NULL DEFAULT 0,
`page` VARCHAR(2048) NOT NULL, `page` VARCHAR(2048) NOT NULL,
`user_agent` VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE (`ip`) UNIQUE (`ip`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

View File

@@ -12,9 +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';
if(file_exists(BASE . 'config.local.php'))
require BASE . 'config.local.php';
// ignore undefined index from Twig autoloader // ignore undefined index from Twig autoloader
$config['env'] = 'prod'; $config['env'] = 'prod';
@@ -26,13 +24,13 @@ $twig = new Twig_Environment($twig_loader, array(
)); ));
// load installation status // load installation status
$step = isset($_POST['step']) ? $_POST['step'] : 'welcome'; $step = $_REQUEST['step'] ?? 'welcome';
$install_status = array(); $install_status = array();
if(file_exists(CACHE . 'install.txt')) { if(file_exists(CACHE . 'install.txt')) {
$install_status = unserialize(file_get_contents(CACHE . 'install.txt')); $install_status = unserialize(file_get_contents(CACHE . 'install.txt'));
if(!isset($_POST['step'])) { if(!isset($_REQUEST['step'])) {
$step = isset($install_status['step']) ? $install_status['step'] : ''; $step = isset($install_status['step']) ? $install_status['step'] : '';
} }
} }
@@ -70,7 +68,7 @@ if($step == 'database') {
$key = str_replace('var_', '', $key); $key = str_replace('var_', '', $key);
if(in_array($key, array('account', 'account_id', 'password', 'email', 'player_name'))) { if(in_array($key, array('account', 'account_id', 'password', 'password_confirm', 'email', 'player_name'))) {
continue; continue;
} }
@@ -91,14 +89,6 @@ if($step == 'database') {
break; break;
} }
} }
else if($key == 'mail_admin' && !Validator::email($value)) {
$errors[] = $locale['step_config_mail_admin_error'];
break;
}
else if($key == 'mail_address' && !Validator::email($value)) {
$errors[] = $locale['step_config_mail_address_error'];
break;
}
else if($key == 'timezone' && !in_array($value, DateTimeZone::listIdentifiers())) { else if($key == 'timezone' && !in_array($value, DateTimeZone::listIdentifiers())) {
$errors[] = $locale['step_config_timezone_error']; $errors[] = $locale['step_config_timezone_error'];
break; break;
@@ -124,6 +114,7 @@ else if($step == 'admin') {
else if($step == 'finish') { else if($step == 'finish') {
$email = $_SESSION['var_email']; $email = $_SESSION['var_email'];
$password = $_SESSION['var_password']; $password = $_SESSION['var_password'];
$password_confirm = $_SESSION['var_password_confirm'];
$player_name = $_SESSION['var_player_name']; $player_name = $_SESSION['var_player_name'];
// email check // email check
@@ -165,6 +156,9 @@ else if($step == 'finish') {
else if(!Validator::password($password)) { else if(!Validator::password($password)) {
$errors[] = $locale['step_admin_password_error_format']; $errors[] = $locale['step_admin_password_error_format'];
} }
else if($password != $password_confirm) {
$errors[] = $locale['step_admin_password_confirm_error_not_same'];
}
// player name check // player name check
if(empty($player_name)) { if(empty($player_name)) {
@@ -189,14 +183,14 @@ clearstatcache();
if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) { if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) {
if(!file_exists(BASE . 'install/ip.txt')) { if(!file_exists(BASE . 'install/ip.txt')) {
$content = warning('AAC installation is disabled. To enable it make file <b>ip.txt</b> in install/ directory and put there your IP.<br/> $content = warning('AAC installation is disabled. To enable it make file <b>ip.txt</b> in install/ directory and put there your IP.<br/>
Your IP is:<br /><b>' . get_browser_real_ip() . '</b>', true); Your IP is:<br /><b>' . $_SERVER['REMOTE_ADDR'] . '</b>', true);
} }
else { else {
$file_content = trim(file_get_contents(BASE . 'install/ip.txt')); $file_content = trim(file_get_contents(BASE . 'install/ip.txt'));
$allow = false; $allow = false;
$listIP = preg_split('/\s+/', $file_content); $listIP = preg_split('/\s+/', $file_content);
foreach($listIP as $ip) { foreach($listIP as $ip) {
if(get_browser_real_ip() == $ip) { if($_SERVER['REMOTE_ADDR'] == $ip) {
$allow = true; $allow = true;
} }
} }

View File

@@ -1,7 +1,7 @@
<?php <?php
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) { if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
echo '<p class="warning">' . $locale['already_installed'] . '</p>'; echo '<div class="alert alert-warning"><span>' . $locale['already_installed'] . '</span></div>';
} }
else { else {
unset($_SESSION['saved']); unset($_SESSION['saved']);

View File

@@ -2,8 +2,21 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
// configuration // configuration
$dirs_required = [
'system/logs',
'system/cache',
];
$dirs_optional = [
GUILD_IMAGES_DIR => $locale['step_requirements_warning_images_guilds'],
GALLERY_DIR => $locale['step_requirements_warning_images_gallery'],
];
$extensions_required = [ $extensions_required = [
'pdo', 'pdo_mysql', 'xml', 'zip' 'pdo', 'pdo_mysql', 'json', 'xml'
];
$extensions_optional = [
'gd' => $locale['step_requirements_warning_player_signatures'],
'zip' => $locale['step_requirements_warning_install_plugins'],
]; ];
/* /*
* *
@@ -14,11 +27,11 @@ $extensions_required = [
function version_check($name, $ok, $info = '', $warning = false) function version_check($name, $ok, $info = '', $warning = false)
{ {
global $failed; global $failed;
echo '<p class="' . ($ok ? 'success' : ($warning ? 'warning' : 'error')) . '">' . $name; echo '<div class="alert alert-' . ($ok ? 'success' : ($warning ? 'warning' : 'danger')) . '">' . $name;
if(!empty($info)) if(!empty($info))
echo ': <b>' . $info . '</b>'; echo ': <b>' . $info . '</b>';
echo '</p>'; echo '</div>';
if(!$ok && !$warning) if(!$ok && !$warning)
$failed = true; $failed = true;
} }
@@ -27,12 +40,18 @@ $failed = false;
// start validating // start validating
version_check($locale['step_requirements_php_version'], (PHP_VERSION_ID >= 50500), PHP_VERSION); version_check($locale['step_requirements_php_version'], (PHP_VERSION_ID >= 50500), PHP_VERSION);
foreach(array('images/guilds', 'images/houses', 'images/gallery') as $value)
foreach ($dirs_required as $value)
{ {
$is_writable = is_writable(BASE . $value); $is_writable = is_writable(BASE . $value) && (MYAAC_OS != 'WINDOWS' || win_is_writable(BASE . $value));
version_check($locale['step_requirements_write_perms'] . ': ' . $value, $is_writable); version_check($locale['step_requirements_write_perms'] . ': ' . $value, $is_writable);
} }
foreach ($dirs_optional as $dir => $errorMsg) {
$is_writable = is_writable(BASE . $dir) && (MYAAC_OS != 'WINDOWS' || win_is_writable(BASE . $dir));
version_check($locale['step_requirements_write_perms'] . ': ' . $dir, $is_writable, $is_writable ? '' : $errorMsg, true);
}
$ini_register_globals = ini_get_bool('register_globals'); $ini_register_globals = ini_get_bool('register_globals');
version_check('register_long_arrays', !$ini_register_globals, $ini_register_globals ? $locale['on'] : $locale['off']); version_check('register_long_arrays', !$ini_register_globals, $ini_register_globals ? $locale['on'] : $locale['off']);
@@ -44,12 +63,19 @@ foreach ($extensions_required as $ext) {
version_check(str_replace('$EXTENSION$', strtoupper($ext), $locale['step_requirements_extension']) , $loaded, $loaded ? $locale['loaded'] : $locale['not_loaded']); version_check(str_replace('$EXTENSION$', strtoupper($ext), $locale['step_requirements_extension']) , $loaded, $loaded ? $locale['loaded'] : $locale['not_loaded']);
} }
foreach ($extensions_optional as $ext => $errorMsg) {
if($failed) $loaded = extension_loaded($ext);
{ version_check(str_replace('$EXTENSION$', strtoupper($ext), $locale['step_requirements_extension']) , $loaded, $loaded ? $locale['loaded'] : $locale['not_loaded'] . '. ' . $errorMsg, true);
echo '<br/><b>' . $locale['step_requirements_failed'];
echo next_form(true, false);
} }
else
echo '<div class="text-center m-3">';
if($failed) {
echo '<div class="alert alert-warning"><span>' . $locale['step_requirements_failed'] . '</span></div>';
echo next_form(true, false);
}else {
echo next_form(true, true); echo next_form(true, true);
}
echo '</div>';
?> ?>

View File

@@ -11,18 +11,12 @@ if(!isset($_SESSION['var_server_path'])) {
} }
if(!$error) { if(!$error) {
$content = "<?php"; $configToSave = [
$content .= PHP_EOL;
$content .= '// place for your configuration directives, so you can later easily update myaac';
$content .= PHP_EOL;
$content .= '$config[\'installed\'] = true;';
$content .= PHP_EOL;
// by default, set env to prod // by default, set env to prod
// user can disable when he wants // user can disable when he wants
$content .= '$config[\'env\'] = \'prod\'; // dev or prod'; 'env' => 'prod',
$content .= PHP_EOL; ];
$content .= '$config[\'mail_enabled\'] = true;';
$content .= PHP_EOL;
foreach($_SESSION as $key => $value) foreach($_SESSION as $key => $value)
{ {
if(strpos($key, 'var_') !== false) if(strpos($key, 'var_') !== false)
@@ -34,17 +28,14 @@ if(!$error) {
$value .= '/'; $value .= '/';
} }
if($key === 'var_usage') { if(!in_array($key, ['var_usage', 'var_date_timezone', 'var_client', 'var_account', 'var_account_id', 'var_password', 'var_password_confirm', 'var_step', 'var_email', 'var_player_name'], true)) {
$content .= '$config[\'anonymous_usage_statistics\'] = ' . ((int)$value == 1 ? 'true' : 'false') . ';'; $configToSave[str_replace('var_', '', $key)] = $value;
$content .= PHP_EOL;
}
else if(!in_array($key, array('var_account', 'var_account_id', 'var_password', 'var_step', 'var_email', 'var_player_name'), true)) {
$content .= '$config[\'' . str_replace('var_', '', $key) . '\'] = \'' . $value . '\';';
$content .= PHP_EOL;
} }
} }
} }
$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true);
require BASE . 'install/includes/config.php'; require BASE . 'install/includes/config.php';
if(!$error) { if(!$error) {
@@ -81,36 +72,17 @@ if(!$error) {
'message' => $locale['loading_spinner'] 'message' => $locale['loading_spinner']
)); ));
if(!Validator::email($_SESSION['var_mail_admin'])) { $content = '';
error($locale['step_config_mail_admin_error']); $saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content);
$error = true;
}
if(!Validator::email($_SESSION['var_mail_address'])) {
error($locale['step_config_mail_address_error']);
$error = true;
}
$content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$content .= PHP_EOL;
$content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$saved = true;
if(!$error) {
$saved = file_put_contents(BASE . 'config.local.php', $content);
}
if($saved) { if($saved) {
success($locale['step_database_config_saved']); success($locale['step_database_config_saved']);
if(!$error) {
$_SESSION['saved'] = true; $_SESSION['saved'] = true;
} }
}
else { else {
$_SESSION['config_content'] = $content; $_SESSION['config_content'] = $content;
unset($_SESSION['saved']); unset($_SESSION['saved']);
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']); $locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.php</b>', $locale['step_database_error_file']);
error($locale['step_database_error_file'] . '<br/> error($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>'); <textarea cols="70" rows="10">' . $content . '</textarea>');
} }
@@ -120,8 +92,10 @@ if(!$error) {
} }
?> ?>
<div class="text-center m-3">
<form action="<?php echo BASE_URL; ?>install/" method="post"> <form action="<?php echo BASE_URL; ?>install/" method="post">
<input type="hidden" name="step" id="step" value="admin" /> <input type="hidden" name="step" id="step" value="admin" />
<?php echo next_buttons(true, !$error); <?php echo next_buttons(true, !$error);
?> ?>
</form> </form>
</div>

View File

@@ -8,15 +8,14 @@ if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['save
else { else {
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';
if(!$error) { if(!$error) {
if(USE_ACCOUNT_NAME) if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER)
$account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null; $account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null;
else else
$account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null; $account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null;
$password = $_SESSION['var_password']; $password = $_SESSION['var_password'];
$config_salt_enabled = $db->hasColumn('accounts', 'salt'); if(USE_ACCOUNT_SALT)
if($config_salt_enabled)
{ {
$salt = generateRandomString(10, false, true, true); $salt = generateRandomString(10, false, true, true);
$password = $salt . $password; $password = $salt . $password;
@@ -74,13 +73,11 @@ else {
$account_used = &$new_account; $account_used = &$new_account;
} }
if($config_salt_enabled) if(USE_ACCOUNT_SALT)
$account_used->setCustomField('salt', $salt); $account_used->setCustomField('salt', $salt);
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN); $account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us'); $account_used->setCustomField('country', 'us');
$account_used->setCustomField('email_verified', 1);
if($db->hasColumn('accounts', 'group_id')) if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId()); $account_used->setCustomField('group_id', $groups->getHighestId());
if($db->hasColumn('accounts', 'type')) if($db->hasColumn('accounts', 'type'))
@@ -119,12 +116,30 @@ else {
} }
} }
$settings = Settings::getInstance();
foreach($_SESSION as $key => $value) {
if (in_array($key, ['var_usage', 'var_date_timezone', 'var_client'])) {
if ($key == 'var_usage') {
$key = 'anonymous_usage_statistics';
$value = ((int)$value == 1 ? 'true' : 'false');
} elseif ($key == 'var_date_timezone') {
$key = 'date_timezone';
} elseif ($key == 'var_client') {
$key = 'client';
}
$settings->updateInDatabase('core', $key, $value);
}
}
success('Settings saved.');
$twig->display('install.installer.html.twig', array( $twig->display('install.installer.html.twig', array(
'url' => 'tools/7-finish.php', 'url' => 'tools/7-finish.php',
'message' => $locale['importing_spinner'] 'message' => $locale['importing_spinner']
)); ));
if(!isset($_SESSION['installed'])) { if(!isset($_SESSION['installed'])) {
if (!array_key_exists('CI', getenv())) {
$report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL);
if (function_exists('curl_version')) if (function_exists('curl_version'))
{ {
@@ -137,6 +152,8 @@ else {
else if (ini_get('allow_url_fopen') ) { else if (ini_get('allow_url_fopen') ) {
file_get_contents($report_url); file_get_contents($report_url);
} }
}
$_SESSION['installed'] = true; $_SESSION['installed'] = true;
} }

View File

@@ -1,299 +1,13 @@
* { @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400&display=swap');
margin: 0; padding: 0;
}
body { body {
text-align: center; font-family: 'Roboto', sans-serif;
font: 12px Verdana;
color: #000000;
background-color: #000000;
}
img {
border: 0;
} }
.break { h1{
font-size: 0; font-weight: 100 !important;
width: 0; height: 0;
clear: both;
}
.alignleft {
float: left;
margin: 4px 10px 5px 0;
}
.alignright {
float: right;
margin: 4px 0 5px 10px;
}
.aligncenter {
text-align: center;
} }
/** BEGIN wrapper **/ h3 {
#wrapper { font-weight: 300 !important;
background: #ffffff url(images/background.jpg) repeat-x 0 0;
width: 980px;
}
#header {
margin-bottom: 10px;
border-bottom: 1px solid #eee;
padding-bottom: 15px;
}
#footer {
padding-top: 15px;
border-top: 1px solid #eee;
margin-top: 10px;
text-align: right;
color: #555;
}
#header h1 {
font-weight: bold;
margin: 0;
padding: 0;
}
#header span {
font-size: 25px;
color: #000;
font-weight: bold;
padding-left: 40px;
line-height: 80px;
}
#version {
float: right;
color: #000;
font-size: 17px;
padding-top: 25px;
padding-right: 5px;
}
/** BEGIN body **/
#body {
background: url(images/wrapper.gif) repeat-y 0 0;
}
/** END body **/
/** BEGIN content **/
#content {
width: 642px;
float: left;
padding: 20px 18px 20px 20px;
color: #434242;
}
/** begin headers **/
h1, h2, h3, h4, h5, h6 {
font-family: Tahoma;
margin-bottom: 10px;
}
h2, h3, h4, h5, h6 {
margin-top: 30px;
}
h1 { font-size: 2em; }
h2 { font-size: 1.6em; }
h3 { font-size: 1.3em; }
h4, h5, h6 { font-size: 1em; }
/** end headers **/
/** begin messages **/
.error, .success, .note, .warning {
font-weight: bold;
font-size: 0.9em;
padding: 4px 10px 4px 24px;
background-repeat: no-repeat;
background-position: 5px 6px;
border-style: solid;
border-width: 1px;
line-height: 1.6em;
margin-bottom: 10px;
}
.error {
background-color: #FDD9D9;
background-image: url(images/error.gif);
border-color: #FBA3A3;
color: #D80303;
}
.success {
background-color: #E4FCD9;
background-image: url(images/success.gif);
border-color: #BFFDA3;
color: #35A502;
}
.note {
background-color: #DDEAFA;
background-image: url(images/note.gif);
border-color: #A3D8FD;
color: #026DA5;
}
.warning {
background-color: #FBF0B3;
background-image: url(images/warning.gif);
border-color: #FBBB95;
color: #FD6002;
}
/** end messages **/
/** begin form **/
form {
border: 1px solid #DDDDDD;
padding: 16px;
}
form .input {
padding-top: 12px;
clear: both;
}
form .first {
padding-top: 0;
}
form .input p {
margin-bottom: 7px !important;
}
form input {
margin-right: 5px;
}
form label {
margin-right: 10px;
color: #8B8B8B;
}
form input.text, form textarea {
border: 1px solid #BEBDBD;
font-size: 1em;
font-family: Verdana;
background-color: #F3F3F3;
color: #808080;
padding: 2px;
max-width: 100%;
}
.positive, .negative {
font-size: 0.9em;
font-weight: bold;
padding: 1px 0 0 20px;
background-repeat: no-repeat;
background-position: 0 0;
display: inline;
margin-top: 2px;
}
.positive {
background-image: url(images/positive.gif);
color: #35A502;
}
.negative {
background-image: url(images/negative.gif);
color: #D80303;
}
form textarea {
line-height: 1.6em;
}
form button, form input.button {
font-size: 0.9em;
font-family: Verdana;
font-weight: bold;
color: #ffffff;
background: #B6B4B4 url(images/button.gif) repeat-x 0 0;
border: 1px solid #B6B4B4;
padding: 5px 10px;
}
/** end form **/
/** begin table **/
table {
}
table th {
font-size: 0.9em;
color: #ffffff;
background-color: #679BC5;
padding: 2px 4px;
line-height: 1.6em;
}
table td {
line-height: 1.6em;
padding: 2px 4px;
}
table tr.odd td { background-color: #EEEEEE; }
table tr.even td { background-color: #E5E5E5; }
/** end table **/
/** begin paragraphs, lists, etc. **/
#content p {
line-height: 1.6em;
margin-bottom: 10px;
}
#content ul, #content ol {
list-style-position: inside;
}
#content li {
line-height: 1.6em;
padding: 2px 0 2px 0;
}
a {
color: #679BC5;
}
a:hover {
color: #ff0000;
text-decoration: none;
}
blockquote {
padding: 10px;
background-color: #eeeeee;
line-height: 1.6em;
border-width: 2px 0 1px;
border-style: solid;
border-color: #e0e0e0;
}
/** end paragraphs, lists, etc. **/
/** END content **/
/** BEGIN sidebar **/
#sidebar {
width: 300px;
float: right;
padding: 10px 0;
}
#sidebar h2 {
background: green url(images/sidehead.gif) no-repeat 0 0;
margin: 0 10px;
font-size: 1em;
color: #ffffff;
padding: 7px 10px;
}
#sidebar ul {
list-style-type: none;
background: #E0E0E0 url(images/sidebody.gif) no-repeat 0 bottom;
padding: 10px;
margin: 0 10px 10px;
}
#sidebar ul li {
padding: 4px 0 4px 14px;
background: none;
line-height: 1.6em;
font-size: 0.9em;
font-weight: bold;
}
#sidebar ul li a {
color: #000000;
text-decoration: none;
}
#sidebar ul li a:hover {
text-decoration: none;
color: #ff0000;
}
#sidebar ul li a:active {
text-decoration: none;
color: #ff0000;
}
#sidebar ul li current {
text-decoration: none;
color: #ff0000;
}
.current {
text-decoration: none;
color: #ff0000;
} }

View File

@@ -1,48 +1,74 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>"> <html dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" /> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MyAAC - <?php echo $locale['installation']; ?></title> <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 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/js/jquery.min.js"></script> <script type="text/javascript" src="<?php echo BASE_URL; ?>tools/js/jquery.min.js"></script>
</head> </head>
<body> <body>
<div id="wrapper">
<!--div class="buffer"--> <div id="body" class="container">
<div id="header">
<header id="header" class="pt-5 pb-4 pb-sm-5">
<h1>MyAAC <?php echo $locale['installation']; ?></h1> <h1>MyAAC <?php echo $locale['installation']; ?></h1>
</div> </header>
<div id="body"> <div class="row">
<div id="sidebar"> <div id="sidebar" class="col-md-3">
<h2><?php echo $locale['steps']; ?></h2> <h3><?php echo $locale['steps']; ?></h3>
<ul> <ul class="list-group mt-4">
<?php <?php
$i = 0; $i = 0;
foreach($steps as $key => $value) foreach($steps as $key => $value){
echo '<li' . ($step == $value ? ' class="current"' : '') . '>' . ++$i . '. ' . $locale['step_' . $value] . '</li>';
if ($step == $value) {
$progress = ($i == 6) ? 100 : $i * 16;
}
echo '<li class="list-group-item' . ($step == $value ? ' active' : '') . '">' . ++$i . '. ' . $locale['step_' . $value] . '</li>';
}
?> ?>
</ul> </ul>
</div> </div>
<div id="content"> <div id="content" class="col-md-9">
<?php <?php
if(isset($locale['step_' . $step . '_title'])) if(isset($locale['step_' . $step . '_title']))
echo '<h1>' . $locale['step_' . $step . '_title'] . '</h1>'; echo '<h3 class="mb-4 mt-4 mt-md-0">' . $locale['step_' . $step . '_title'] . '</h3>';
else else
echo '<h1>' . $locale['step_' . $step] . '</h1>'; echo '<h3 class="mb-4 mt-4 mt-md-0">' . $locale['step_' . $step] . '</h3>';
echo $content;
?> ?>
<?php
if(!isset($config['installed'])):
?>
<div class="row">
<div class="col-md-12">
<div class="progress mb-2">
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: <?php echo $progress; ?>%" role="progressbar" aria-valuenow="<?php echo $progress; ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
<?php endif; ?>
<?php echo $content; ?>
</div> </div>
<div class="break"></div>
</div>
<!--/div-->
</div> </div>
<div id="footer"> <hr />
</div>
<footer id="footer" class="p-4">
<p style="text-align: center;"><?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?></p> <p style="text-align: center;"><?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?></p>
</div> </footer>
</body> </body>
</html> </html>

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) {
@@ -58,7 +56,7 @@ else {
} }
if(!$db->hasColumn('accounts', 'created')) { if(!$db->hasColumn('accounts', 'created')) {
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'email') . "`;")) if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'key') . "`;"))
success($locale['step_database_adding_field'] . ' accounts.created...'); success($locale['step_database_adding_field'] . ' accounts.created...');
} }

View File

@@ -8,16 +8,14 @@ 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'])) {
warning($locale['already_installed']); warning($locale['already_installed']);
return; return;
} }*/
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';
@@ -47,48 +45,12 @@ if($success) {
success($locale['step_database_imported_players']); success($locale['step_database_imported_players']);
} }
require LIBS . 'items.php'; require LIBS . 'DataLoader.php';
if(Items::loadFromXML()) DataLoader::setLocale($locale);
success($locale['step_database_loaded_items']); DataLoader::load();
else
error(Items::getError());
require LIBS . 'weapons.php';
if(Weapons::loadFromXML())
success($locale['step_database_loaded_weapons']);
else
error(Weapons::getError());
require LIBS . 'creatures.php';
if(Creatures::loadFromXML()) {
success($locale['step_database_loaded_monsters']);
if(Creatures::getMonstersList()->hasErrors()) {
$locale['step_database_error_monsters'] = str_replace('$LOG$', 'system/logs/error.log', $locale['step_database_error_monsters']);
warning($locale['step_database_error_monsters']);
}
}
else {
error(Creatures::getLastError());
}
require LIBS . 'spells.php';
if(Spells::loadFromXML()) {
success($locale['step_database_loaded_spells']);
}
else {
error(Spells::getLastError());
}
// update config.highscores_ids_hidden // update config.highscores_ids_hidden
require_once SYSTEM . 'migrations/20.php'; require_once SYSTEM . 'migrations/20.php';
$database_migration_20 = true;
$content = '';
if(!databaseMigration20($content)) {
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
warning($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>');
}
// add z_polls tables // add z_polls tables
require_once SYSTEM . 'migrations/22.php'; require_once SYSTEM . 'migrations/22.php';

View File

@@ -1,7 +1,5 @@
<?php <?php
require_once 'common.php'; require_once 'common.php';
require_once 'config.php';
require_once 'config.local.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php'; require_once SYSTEM . 'init.php';
require_once SYSTEM . 'status.php'; require_once SYSTEM . 'status.php';
@@ -127,8 +125,7 @@ switch ($action) {
$account->find($inputAccountName); $account->find($inputAccountName);
} }
$config_salt_enabled = fieldExist('salt', 'accounts'); $current_password = encrypt((USE_ACCOUNT_SALT ? $account->getCustomField('salt') : '') . $request->password);
$current_password = encrypt(($config_salt_enabled ? $account->getCustomField('salt') : '') . $request->password);
if (!$account->isLoaded() || $account->getPassword() != $current_password) { if (!$account->isLoaded() || $account->getPassword() != $current_password) {
sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.'); sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.');

View File

@@ -10,21 +10,22 @@ server {
# this is very important, be sure its in your nginx conf - it prevents access to logs etc. # this is very important, be sure its in your nginx conf - it prevents access to logs etc.
location ~ /system { location ~ /system {
deny all; deny all;
return 404;
} }
# block .htaccess, CHANGELOG.md, composer.json etc. # block .htaccess
# this is to prevent finding software versions location ~ /\.ht {
location ~\.(ht|md|json|dist)$ {
deny all; deny all;
} }
# block git files and folders # block git files and folders
location ~ /\.git { location ~ /\.git {
return 404;
deny all; deny all;
} }
location / { location / {
try_files $uri $uri/ /index.php?$query_string;; try_files $uri $uri/ /index.php;
} }
location ~ \.php$ { location ~ \.php$ {

1927
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

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