Compare commits

...

487 Commits

Author SHA1 Message Date
slawkens
e2bab4220b Fix composer install 2024-05-18 22:31:59 +02:00
slawkens
0b4c34a823 Update phpstan.yml 2024-05-18 22:20:00 +02:00
slawkens
c5aa9a4684 Do not include phpstan into release 2024-05-18 22:19:23 +02:00
slawkens
301afe190b Remove node_modules in release script 2024-05-18 22:01:41 +02:00
slawkens
c35cc83e4f They say composer.lock should be commited - let it be! 2024-05-18 22:01:30 +02:00
slawkens
3ba9d8f780 Fix date 2024-05-18 21:56:01 +02:00
slawkens
06f228509b Update release.sh 2024-05-18 21:53:41 +02:00
slawkens
39e682dfd2 htmlspecialchars seems to be better here (?) 2024-05-16 18:58:54 +02:00
slawkens
6f209440e0 Fix XSS in monsters.php, thanks to @gesior 2024-05-15 22:18:39 +02:00
slawkens
b2a1675de3 Fix if account_country is disabled 2024-04-16 13:32:34 +02:00
slawkens
163877d303 Update account.generate_recovery_key.html.twig 2024-04-16 11:38:10 +02:00
slawkens
a4d11c1a12 Rename variables 2024-04-16 10:45:34 +02:00
slawkens
8cf4e3da02 Fix change_info if account_country is disabled 2024-04-15 21:54:18 +02:00
slawkens
e0230c5237 Adjustments in success.html.twig 2024-04-15 21:47:21 +02:00
slawkens
127e03081c Support for subfolders in plugins/pages 2024-04-15 21:21:16 +02:00
slawkens
e9c6017e60 Fix forum table header text color 2024-04-15 20:35:53 +02:00
slawkens
d5915df37e Fix redirects in forum + polls 2024-04-14 16:06:57 +02:00
slawkens
eb0c2a7674 Post-fix redirect 2024-04-14 16:02:55 +02:00
slawkens
d225c2da26 Fix form id 2024-04-14 15:59:23 +02:00
slawkens
d95e280b9a Use tables headline for account.redirect.html.twig 2024-04-14 15:25:13 +02:00
slawkens
64387e085b Use tables headline for account.create.html.twig 2024-04-14 15:06:43 +02:00
slawkens
e1f507cf2d Extend timeout to fix broken workflow-runs 2024-04-12 15:15:23 +02:00
slawkens
c92a410209 Don't allow redirect to external website 2024-04-08 19:08:21 +02:00
slawkens
1186f94e21 Add Twig TypeCastingExtension 2024-04-08 10:08:48 +02:00
slawkens
f837b3133d deny vendor, composer.json, changelog.md etc. in nginx config sample 2024-04-06 19:51:34 +02:00
slawkens
9106f1e4ce Update CHANGELOG.md 2024-04-06 19:16:22 +02:00
slawkens
a62cfc5272 Update CHANGELOG.md 2024-04-06 15:08:39 +02:00
slawkens
6229736d07 getPlayerLink -> colored 2024-04-01 23:40:53 +02:00
slawkens
6807339056 Colored (online/offline) player links 2024-04-01 23:33:00 +02:00
slawkens
ffaa0729ac Add player->getOutfit function 2024-04-01 23:19:12 +02:00
slawkens
03cc09b8c7 Adjust submit button 2024-04-01 23:10:00 +02:00
slawkens
6d4724f4f4 Squashed commit of the following:
commit da18629d16
Author: slawkens <slawkens@gmail.com>
Date:   Mon Apr 1 21:53:53 2024 +0200

    Fixes to tables headline

commit 41c3d9ad21
Author: slawkens <slawkens@gmail.com>
Date:   Sun Mar 31 13:59:25 2024 +0200

    [WIP] Tables headline
2024-04-01 21:54:53 +02:00
slawkens
2afe0c1185 Fill up the equipment variable no matter of config 2024-03-28 21:25:43 +01:00
slawkens
6334f3f4fa Fix admin-lte scripts includes 2024-02-23 17:01:49 +01:00
Slawomir Boczek
fe7ad61abe phpstan support (#250)
* phpstan v1 + workflow

* Fix intend

* More fixes

* Update phpstan.neon

* phpstan level 2

* Move errors ignoring into phpstan.neon

* phpstan level 3

* Don't ignore templates folder

* Something from level 4

* Update phpstan.neon
2024-02-18 14:59:25 +01:00
slawkens
e23a749e4c Ignore cypress screenshots folder 2024-02-17 16:48:15 +01:00
slawkens
ab5e4eff76 Fix if hide already exists 2024-02-17 16:43:33 +01:00
slawkens
fdd3bfd105 Fix config_lua reloading, cache clear problem 2024-02-17 16:43:21 +01:00
slawkens
93ad347571 Restore cypress:open npm command 2024-02-17 16:41:40 +01:00
slawkens
7d4aafda4f Update workflow name
[skip ci]
2024-02-17 15:51:19 +01:00
slawkens
87e8c9eb4d Use NPM for packages: bootstrap, jquery, tinymce 2024-02-17 15:42:09 +01:00
slawkens
d61197b6a1 Delete tinymce, will be included by npm 2024-02-17 10:30:50 +01:00
slawkens
dfba8bc60b Update README.md
[skip ci]
2024-02-17 09:05:36 +01:00
slawkens
d2d497d82c Upgrading to gha-find-replace@v3, fixes some warnings about set-output 2024-02-17 08:51:05 +01:00
slawkens
4204e0a419 Nope, it doesn't work 2024-02-17 08:35:16 +01:00
slawkens
e8e093cc1f Try to do it in one step with regex 2024-02-17 08:30:49 +01:00
slawkens
2b39a1e406 Fix canary build 2024-02-17 08:24:59 +01:00
slawkens
cac592e63a Update workflow name [skip ci] 2024-02-17 08:04:05 +01:00
slawkens
0255d0bef2 Fix upload artifacts error + adjust workflow name 2024-02-17 08:00:12 +01:00
slawkens
a59f0e9244 Cypress test on canary + tfs-master 2024-02-17 07:55:51 +01:00
slawkens
9f3231fff6 Fix delete character exception 2024-02-16 20:27:48 +01:00
slawkens
647eae08b4 Display error message if config.local.php is not writable 2024-02-04 10:10:04 +01:00
slawkens
e2487f97e3 settings:set + settings:reset commands 2024-02-04 09:01:00 +01:00
slawkens
235e69b8da Settings::clearCache function 2024-02-04 08:35:33 +01:00
slawkens
649e37ab0f "php aac migrate:run {ids}" command 2024-02-04 08:16:22 +01:00
slawkens
dff4a98ef5 Fix reload server data 2024-02-04 08:13:57 +01:00
slawkens
b754374585 Update CHANGELOG.md 2024-02-04 07:41:25 +01:00
slawkens
ad789c50ff Create creatures.php 2024-02-03 20:54:50 +01:00
slawkens
ccfd2b4f55 Rename creatures to monsters 2024-02-03 20:54:09 +01:00
slawkens
3f5744964a Get rid of ?subtopic=x links 2024-02-03 20:34:42 +01:00
slawkens
b22dc0014a Change spaces to tabs 2024-02-03 20:30:21 +01:00
slawkens
00cbce20b0 Various fixes in forum
Add new access type: guest - all visitors, player will be now for logged players only
Fixed default forum board access for guests
2024-02-03 20:01:38 +01:00
slawkens
bbe922a65d New migration: update menu links 2024-02-03 18:58:20 +01:00
slawkens
8f23c62708 Update list of contributors 2024-02-03 18:42:35 +01:00
slawkens
58bb6093b0 Update release.sh 2024-02-02 20:29:28 +01:00
slawkens
2faaa037ab Update CHANGELOG.md 2024-02-02 20:17:18 +01:00
slawkens
cc9057324a Fix maxlength for email input 2024-02-02 18:52:21 +01:00
slawkens
f7971a21d8 An attempt to bypass the error 2024-02-01 20:43:46 +01:00
slawkens
08e7cf05b5 Remove link, looks bad on Whoops 2024-02-01 19:00:44 +01:00
slawkens
2e482fdc2a Relocation of myaac tables check
Makes more sense, between $db connection and migrate.php
2024-02-01 18:36:23 +01:00
slawkens
a2c8e2b2ae phpstan: level 1 passed 2024-01-31 00:36:15 +01:00
slawkens
cc3e66cacb according to phpstan: isset is not required here 2024-01-30 23:58:33 +01:00
slawkens
bd86454fea Import missing class 2024-01-30 23:16:33 +01:00
slawkens
1bb6e61583 eAccelerator is dead 2024-01-30 23:13:57 +01:00
slawkens
13a2570ad0 Remove old approach of showing errors to users in database pages
Currently handled by config.env
2024-01-30 23:04:53 +01:00
slawkens
e961f2efcf fix: missing semicolon 2024-01-30 23:02:26 +01:00
slawkens
54609bf90e phpstan adjustments 2024-01-30 23:01:18 +01:00
slawkens
6494bd2c0c Add optional $return = false parameter to the csrf function 2024-01-30 22:40:40 +01:00
slawkens
670812772d Seems that this is better solution to the #245 (output buffering)
This works for both, when output_buffering is enabled, and disabled
2024-01-30 19:20:23 +01:00
slawkens
ae8a9fc44c This is more error resistant 2024-01-30 18:30:42 +01:00
slawkens
f80c5fd8ed Update init.php 2024-01-30 18:16:05 +01:00
slawkens
6bac02bd35 Fix links to some pages that has been renamed 2024-01-30 18:09:57 +01:00
slawkens
ac67555f28 Fix exception when settingsDb are empty 2024-01-30 18:09:57 +01:00
slawkens
6c4fd4ed27 add new constant for cli: SELF_NAME 2024-01-30 18:09:56 +01:00
slawkens
a8a896e0f5 Our command line tool will be named: aac 2024-01-30 17:47:31 +01:00
slawkens
b517a12f8a Avoid duplicate loading of hooks 2024-01-28 23:08:37 +01:00
slawkens
5d741944f7 Fix: cronjob command 2024-01-28 23:07:40 +01:00
slawkens
a3056f5f48 Preparing to release 1.0-beta - update changelog 2024-01-28 23:07:22 +01:00
slawkens
8518f21987 Fix the migration, thanks @gpedro 2024-01-28 18:42:10 +01:00
slawkens
a3a2f05783 Forgot to quote 2024-01-28 18:26:03 +01:00
slawkens
9f3c980ed2 Update commands & downloads pages 2024-01-27 23:58:08 +01:00
slawkens
31f8c99745 $menu['target_blank'] 2024-01-27 23:25:03 +01:00
slawkens
25c0bac7a3 Cache clear hook 2024-01-27 20:30:15 +01:00
slawkens
9a749afc46 1 second should be enough, is ages in IT 2024-01-27 20:19:25 +01:00
slawkens
87df817eae Another way to clear database cache 2024-01-27 19:27:25 +01:00
slawkens
3a58c8a6f9 Revert "Revert "Another try..""
This reverts commit 2ba03e0c99.
2024-01-27 19:23:02 +01:00
slawkens
2ba03e0c99 Revert "Another try.."
This reverts commit ccc91a473c.
2024-01-27 18:58:41 +01:00
slawkens
f7f46bae00 OK so that was that 2024-01-27 18:58:19 +01:00
slawkens
ccc91a473c Another try.. 2024-01-27 18:12:38 +01:00
slawkens
7e347e950f Revert "try mysql 5.7"
This reverts commit 535ae2047d.
2024-01-27 18:12:01 +01:00
slawkens
535ae2047d try mysql 5.7 2024-01-27 17:58:00 +01:00
slawkens
12bc6a0333 Revert "Revert "Revert "just testing"""
This reverts commit 3a86738983.
2024-01-27 17:57:43 +01:00
slawkens
3a86738983 Revert "Revert "just testing""
This reverts commit 76256a7ee6.
2024-01-27 17:49:24 +01:00
slawkens
3b3e9b0e70 Update 1-install.cy.js 2024-01-27 17:33:53 +01:00
slawkens
54b9cc5402 This exception makes no sense, as it redirects to install 2024-01-27 17:33:47 +01:00
slawkens
6d23b285c1 Fixes for PHP 8.3 2024-01-27 17:27:05 +01:00
slawkens
76256a7ee6 Revert "just testing"
This reverts commit 07dafc5118.
2024-01-27 17:23:40 +01:00
slawkens
07dafc5118 just testing 2024-01-27 17:13:32 +01:00
slawkens
b5c1b431d5 Upload php log 2024-01-27 17:06:55 +01:00
slawkens
3a3e434d4e Update cypress.yml 2024-01-27 17:04:20 +01:00
slawkens
d71bab648d Change hidden to hide (Eloquent blocked keyword) 2024-01-27 16:54:48 +01:00
slawkens
3554b41172 Preparing to release v1.0-beta 2024-01-27 15:36:34 +01:00
slawkens
41022727bd Fixes to csrf protection 2024-01-27 15:35:24 +01:00
slawkens
9b781d09a9 Use php 7 str_contains 2024-01-27 14:15:56 +01:00
slawkens
c8d4e7d186 Auto clear old menu entries on install 2024-01-27 14:15:42 +01:00
slawkens
6cd8b7697d Fix plugin menus hook 2024-01-27 14:14:40 +01:00
slawkens
19c4cb810b Update 3-check-public-pages.cy.js 2024-01-27 10:00:23 +01:00
slawkens
ba6119e6d0 Rename pages 2024-01-27 09:58:11 +01:00
slawkens
1ce816040a Remove duplicated placeholder 2024-01-27 09:34:35 +01:00
slawkens
aa8e26f6a3 check if menu table exists 2024-01-27 09:34:23 +01:00
slawkens
f0eb113bc2 Refactor clearCache function 2024-01-27 09:02:38 +01:00
slawkens
6ed8f18115 Move consts to global.php 2024-01-27 08:44:51 +01:00
slawkens
2262c4e882 Clear additional keys on cache clear 2024-01-27 08:18:50 +01:00
slawkens
69b02fa977 Update to actions/upload-artifact@v4 2024-01-27 01:37:25 +01:00
slawkens
6baf49bba8 Default town = 1 2024-01-27 01:35:51 +01:00
slawkens
bb02328b5a Update github actions versions 2024-01-27 01:35:42 +01:00
slawkens
5a4854c205 Disable account_login_by_email by default 2024-01-27 01:26:44 +01:00
slawkens
c661ae36ef #vars_mail_admin has been deleted in 1.0+ 2024-01-27 01:21:09 +01:00
slawkens
df8fb68d5e Fix imports 2024-01-27 01:15:11 +01:00
slawkens
fb0afdcea1 We require PHP 8.1, cause of illuminate/database 2024-01-27 01:05:03 +01:00
slawkens
e3775fed86 Update bans.php 2024-01-27 01:01:59 +01:00
slawkens
93b0d3829d update github actions: branch = develop 2024-01-27 01:01:56 +01:00
slawkens
b6f98ffdee test github actions 2024-01-27 01:00:25 +01:00
slawkens
511e10e78b Same for themes + commands 2024-01-27 00:56:45 +01:00
slawkens
cfdbc2a8b2 Fixed: disabled plugins should not enable pages 2024-01-27 00:46:34 +01:00
slawkens
1a6fb8bee2 Refactoring classes into src/ folder, so they will be auto-loaded by composer 2024-01-27 00:36:49 +01:00
slawkens
410d75c882 Revised Commands -> use symfony/console -> php ma (MyAAC)
Usage:
php ma list
php ma cache:clear
php ma plugin:install guild-wars.zip

More sophisticated:
echo "Hello, this is hello world message" | php ma mail:send test@test.com --subject "This is subject"

Also: custom commands can be added via Plugins: just need to return new class instance that extends \MyAAC\Commands\Command in plugins/*/commands folder
2024-01-26 23:19:39 +01:00
slawkens
c59bacea93 Fix page title if the index.php is present 2024-01-25 23:11:13 +01:00
slawkens
f719c02050 Feature: auto-load themes (previously templates) from plugins/*/themes/* 2024-01-25 23:06:10 +01:00
slawkens
0698e7b5f5 Typo 2024-01-25 22:29:28 +01:00
slawkens
c594dfd14b Feature: auto-load pages in plugins/*/pages/*.php 2024-01-25 22:29:19 +01:00
slawkens
514c4a037a admin.links style 2024-01-25 22:02:08 +01:00
slawkens
b894f75e74 Put admin.links in <table> to fix position + remove bootstrap classes (didnt worked anyway) 2024-01-25 22:01:35 +01:00
slawkens
d2a3a9a8da System-solution for styled tables, that works with every template 2024-01-25 21:57:20 +01:00
slawkens
3f4c02a327 bugtracker has been removed 2024-01-13 10:18:24 +01:00
slawkens
199672e0c8 Fix donate_column 2024-01-13 10:12:08 +01:00
Danilo Pucci
02adb87fac - adding check before flush buffer (#245) 2024-01-01 23:32:26 +01:00
slawkens
b4448f7279 Silently ignore if the hook does not exist 2023-12-28 19:13:14 +01:00
slawkens
687c9a6690 feature: color-styled tables in tinymce editor 2023-12-12 17:58:17 +01:00
slawkens
2b86ba94fe Cleanup tabs 2023-12-12 14:37:12 +01:00
slawkens
a9fb5dffa3 Fix account manage redirect 2023-12-09 09:26:33 +01:00
slawkens
da77ec20ef Delete bugtracker, it will be included as plugin 2023-12-08 23:56:29 +01:00
slawkens
6fd141eca6 composer --prefer-dist --optimize-autoloader 2023-11-29 22:34:26 +01:00
slawkens
e17dde0dca Fix session fixation 2023-11-27 23:52:36 +01:00
slawkens
d1046ba21d Fix forum XSS 2023-11-27 22:56:38 +01:00
slawkens
98332f1483 Fix XSS in bugtracker.php 2023-11-27 22:29:24 +01:00
slawkens
1423046039 Sort changelogs by date + make sortable in admin panel 2023-11-25 20:09:42 +01:00
slawkens
9c60beeed0 I like this color better - teams page adjustment 2023-11-25 16:56:45 +01:00
slawkens
336b6ac530 Fix mango signature warnings 2023-11-25 16:33:48 +01:00
slawkens
c71722fc52 Fix warning 2023-11-25 16:24:18 +01:00
slawkens
4d8d574089 Fix missing query_string in nginx sample config
Causes missing parameters in $_GET query
2023-11-25 16:24:08 +01:00
slawkens
e74fbe5bfd Update account.lost.form.html.twig 2023-11-25 15:47:53 +01:00
slawkens
48e9a1ed51 Fix account lost interface links 2023-11-25 15:44:34 +01:00
slawkens
56631bdf27 New hook: HOOK_ACCOUNT_CREATE_CHARACTER_AFTER
Possibility to change character after create
2023-11-25 13:53:50 +01:00
slawkens
b1224d9d1a clearRouteCache on database pages change 2023-11-25 13:37:24 +01:00
slawkens
e18ada3d9d Fix default access for database pages 2023-11-25 13:30:48 +01:00
slawkens
c8218f69a5 Fix undefined variable 2023-11-25 13:08:56 +01:00
slawkens
f991a8c817 clearCache after install plugin 2023-11-25 11:09:45 +01:00
slawkens
36ec2e1e56 Add option to execute "install" part of the plugin 2023-11-25 10:10:15 +01:00
slawkens
19c06df300 Insert new setting if it doesn't exist yet 2023-11-24 21:03:31 +01:00
slawkens
b2d5d6f115 Fix backward support, needs to be before router.php 2023-11-23 20:03:15 +01:00
slawkens
5769ac8bb4 Fix onlineTable relation, fixed online status in highscores 2023-11-23 20:02:18 +01:00
slawkens
41c9f54e4b Fix the fix 2023-11-11 21:32:00 +01:00
slawkens
8ef238c96c Fix default option for options 2023-11-11 21:30:10 +01:00
slawkens
9ffb7f5fa9 Move monsters page settings to other tab + some small adjustments 2023-11-11 21:18:00 +01:00
slawkens
8b5464f8f8 Update init.php 2023-11-11 21:16:45 +01:00
slawkens
f008591580 Make links in settings desc clickable 2023-11-11 21:16:34 +01:00
slawkens
1d5b751fe1 Fix Settings:save for other plugins 2023-11-11 18:44:48 +01:00
slawkens
37bde7df22 Use str_contains + str_starts_with 2023-11-11 16:09:44 +01:00
slawkens
89deca1adb Fix empty PAGE 2023-11-11 16:09:31 +01:00
slawkens
c996f25d8d Fix guild leave 2023-11-11 15:28:41 +01:00
slawkens
d291f694d2 Update .gitignore 2023-11-11 15:24:49 +01:00
slawkens
cee1e67d3d Fix highscores_ids_hidden 2023-11-11 15:02:38 +01:00
slawkens
c81861d8c8 debugbar dont like persistent connection 2023-11-11 14:40:10 +01:00
slawkens
c3c1a6b2a6 Preserve config.local.php on settings save
Will be helpful when migration from 0.8
2023-11-11 14:33:20 +01:00
slawkens
d0590d2747 Execute highscores_ids_hidden migration again, cause of settings 2023-11-11 14:29:49 +01:00
slawkens
c79a1d5f3a Fix changelog + news.tickers buttons 2023-11-11 13:18:37 +01:00
slawkens
ada1e391d4 Add option to restrict Page view to logged user
$logged_access = 0 -> not logged in
$logged_access = 1 -> logged in
2023-11-11 12:52:26 +01:00
slawkens
193e18523d Uncheck PHP after enable TinyMCE
This needs to be rewritten anyway
2023-11-11 12:22:42 +01:00
slawkens
3fb9b1ae2f Enable TinyMCE by default 2023-11-11 12:15:03 +01:00
slawkens
561bdcd766 My bad 2023-11-11 12:07:10 +01:00
slawkens
556ef47d59 Towns & NPCs & Items should be persistent 2023-11-11 12:04:21 +01:00
slawkens
130ad25c4d Saving setting in db is not intended - you can use Settings Model for that 2023-11-11 11:34:02 +01:00
slawkens
08bea2c541 Update index.php 2023-11-11 11:31:12 +01:00
slawkens
8974830621 Move debugbar code to separate file 2023-11-11 11:30:08 +01:00
slawkens
d582120fac Squashed commit of the following:
commit 94a61f32ae
Merge: 57772569 8227303b
Author: slawkens <slawkens@gmail.com>
Date:   Sat Nov 11 11:11:13 2023 +0100

    Merge branch 'develop' into feature/debug-bar

commit 577725690d
Author: slawkens <slawkens@gmail.com>
Date:   Mon Aug 21 11:08:12 2023 +0200

    Add option to enable debugbar, even if dev mode is disabled

commit c227fd4e96
Merge: 9fef84bf a692607c
Author: slawkens <slawkens@gmail.com>
Date:   Mon Aug 21 10:20:04 2023 +0200

    Merge branch 'develop' into feature/debug-bar

commit 9fef84bffe
Author: slawkens <slawkens@gmail.com>
Date:   Fri Aug 11 06:39:50 2023 +0200

    Fix debugBar mysql logs (Thanks @gpedro)

commit dedd54286f
Author: slawkens <slawkens@gmail.com>
Date:   Thu Aug 10 13:21:36 2023 +0200

    Log PDO queries, as stated in docs, but doesn't work yet (don't know the reason)

commit 7403a24030
Author: slawkens <slawkens@gmail.com>
Date:   Thu Aug 10 13:21:20 2023 +0200

    Use dev-master, cause of some bugs appearing

commit cc7aec8e28
Author: slawkens <slawkens@gmail.com>
Date:   Thu Aug 10 13:05:02 2023 +0200

    Init debugBar
2023-11-11 11:26:38 +01:00
slawkens
8227303b89 1.0 will be our next release
we are starting to follow semantic versioning
2023-11-11 11:04:09 +01:00
slawkens
7a402ec0e0 fix #225 2023-11-11 11:00:28 +01:00
Slawomir Boczek
790d85a88a CSRF Protection (#235)
* Fix alert class name

* feature: csrf protection

* Cosmetics

* Fix token generate

* Admin Panel: changelogs csrf protection

* news/id route

* Refactor admin newses + add csrf

* Use admin.links instead

* Admin panel: Pages csrf

* Menus: better csrf + add success message on reset colors

* Plugins csrf

* Move definitions

* add info function, same as note($message)

* Update mailer.php

* Fix new page/news links

* clear_cache & maintenance csrf

* Formatting

* Fix news type

* Fix changelog link

* Add new changelog link

* More info to confirm dialog

* This is always true
2023-11-11 10:57:57 +01:00
slawkens
a04fbde607 Fix highscores error 2023-11-09 20:32:20 +01:00
slawkens
9d119b6279 This is more error tolerant 2023-11-07 22:15:23 +01:00
slawkens
7dd9b7764a Update common.php 2023-11-07 22:01:47 +01:00
slawkens
3297a7c51a Better https detection 2023-11-07 22:01:43 +01:00
slawkens
4a430ae9db Fix display ban info on account page
https://otland.net/threads/myacc-bans-display-problem.286825/
2023-11-02 22:06:14 +01:00
Kamil Grzechulski
26a80e0741 fix: password2 variable refactor to correct name (#237) 2023-10-06 07:52:21 +02:00
slawkens
3b9feaf3bd My fault 2023-09-26 22:03:30 +02:00
slawkens
21bff97137 Add additional cache keys to clear function 2023-09-26 21:52:05 +02:00
slawkens
a2a273cde2 Twig_SimpleFilter is deprecated 2023-09-22 16:21:52 +02:00
slawkens
fc5635bad3 spaceless twig tag is deprecated as well 2023-09-22 16:19:56 +02:00
slawkens
e01a44f352 Update .editorconfig 2023-09-16 14:40:19 +02:00
slawkens
855b05b15f Fix class names 2023-09-16 11:45:40 +02:00
slawkens
b3991a8e78 Add HOOK_TWIG. Also moved Hooks loading to init.php
For adding twig functions & filters by plugins
2023-09-16 11:07:38 +02:00
slawkens
0ac0f4e7a8 Fixes 2023-09-16 10:22:10 +02:00
slawkens
e9f155fb49 Fix XSS in players editor 2023-09-16 10:21:18 +02:00
slawkens
55b5e3b600 Fix XSS in accounts editor 2023-09-16 10:21:18 +02:00
slawkens
08339fe8b6 Fix XSS in tibiacom template - subtopic 2023-09-16 10:21:17 +02:00
slawkens
89c2e84bff Fix alert class name 2023-09-16 09:24:10 +02:00
slawkens
f76615e59b Fix getGuildLogoById 2023-09-16 05:54:41 +02:00
slawkens
4c4089a155 Quotes & const 2023-09-12 12:11:49 +02:00
slawkens
2d02d8d8b3 Fix news delete message part 2 2023-09-12 12:09:39 +02:00
slawkens
95b1460b13 Fix news delete message 2023-09-12 12:08:09 +02:00
slawkens
673e40350a Small adjustment to menus install 2023-09-12 11:42:03 +02:00
slawkens
f7cbe5170d set display quest default to false 2023-09-11 16:16:38 +02:00
slawkens
619b8ba4a0 Fix creatures datatable 2023-09-03 21:33:41 +02:00
slawkens
8c3b73ca9e Add account logs to admin panel accounts editor 2023-09-03 21:18:58 +02:00
slawkens
d90810cf84 Add latest clients versions 2023-08-31 14:20:24 +02:00
slawkens
fd25e6e881 Fix highscores country box to be hidden 2023-08-31 14:08:02 +02:00
slawkens
63e69c97b7 Fix login.php @gpedro <3 2023-08-31 14:01:30 +02:00
slawkens
574e35ba35 Fix: forgot to remove those menu items 2023-08-31 13:49:32 +02:00
slawkens
09627bdb1e Linux is case-sensitive! 2023-08-31 11:03:36 +02:00
Slawomir Boczek
5f10773189 feature: plugin cronjobs (#215) 2023-08-31 08:33:32 +02:00
slawkens
8a3986932d My fault was commenting this 2023-08-25 17:13:21 +02:00
slawkens
9e2a87f448 Add forgotten prefix for some settings 2023-08-25 17:09:31 +02:00
slawkens
0746708743 Reviewed some settings again, fixing many glitches 2023-08-24 17:20:32 +02:00
slawkens
3ef53aff6c Allow hooks to be prefixed with HOOK_ 2023-08-23 11:58:03 +02:00
slawkens
f43a5d1221 Option to disable settings saving with hooks
for next.my-aac.org
2023-08-23 11:57:37 +02:00
slawkens
43353b4f53 Update .gitattributes 2023-08-22 13:19:03 +02:00
Gabriel Pedro
a692607c5e feat: replace POT Query Builder to Eloquent ORM (#230)
* wip

* wip

* wip

* wip

* wip

* fix: reusing pdo connection from pot

* wip

* wip

* wip

* wip

* move files

In future, all classes will be in src/ folder

* Replace namespace name, for future

* Remove duplicated exception

* Fix towns from db

* Fix spells page

* Add default FAQ question + FAQ model

* feat: reset colors in menus

* Add confirm + save button at the top (menus)

* Do not insert duplicated FAQ on install

* Refactor install menus

* Fix changelogs showing

* Fix menu update, only with specified template name

* Fix account create -> missing compat

* Fix bans_per_page

* banned_by is player_id. type = 2 is namelock in tfs 0.3

* Add getPlayerNameById, fix getPlayerNameByAccount

* Change link name

* Order by lastlogin

* fix: query optimize

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Refactor notepad.php, class was useless

* This is showing error, if the updated rows = 0

* Fix success & error class (bootstrap)

* Uncomment require migrate.php

* Some distro have owner_id

* Update Player.php

---------

Co-authored-by: slawkens <slawkens@gmail.com>
2023-08-21 10:16:58 +02:00
slawkens
b72e7a3d96 Merge branch '0.9' into develop 2023-08-21 09:43:52 +02:00
slawkens
e15b57f967 Ignore gallery 2023-08-21 09:43:44 +02:00
slawkens
c3a161e2ee Merge branch '0.9' into develop 2023-08-21 09:38:31 +02:00
slawkens
30fe42939d Fix FAQ actions 2023-08-21 09:38:23 +02:00
slawkens
627369bbde Add some variable to config.local.php on install 2023-08-21 09:01:50 +02:00
slawkens
7cea023965 Remove item.php include (was removed in last commits) 2023-08-15 22:33:37 +02:00
slawkens
eb416e18cc Add missing guild_ settings to config compat 2023-08-15 22:28:52 +02:00
slawkens
fc0d13437a Fix highscores show vocation 2023-08-15 22:17:34 +02:00
slawkens
14c8160020 Merge branch '0.9' into develop 2023-08-15 22:06:18 +02:00
slawkens
1f95a415aa Fix tabs 2023-08-15 22:06:09 +02:00
slawkens
370cc554ad Fix success & error class (bootstrap) 2023-08-15 22:04:43 +02:00
slawkens
2991696a60 typo 2023-08-12 13:34:53 +02:00
slawkens
a1ecdd228d Fixes in getPlayerNameByAccountId + add getPlayerNameById 2023-08-12 13:34:25 +02:00
slawkens
6c8961638e Merge branch '0.9' into develop 2023-08-12 13:28:07 +02:00
slawkens
3dd493b790 banned_by is player_id. type = 2 is namelock in tfs 0.3 2023-08-12 13:23:53 +02:00
slawkens
b49c247162 Remove items generator, there are better ones made in JS
This one wasn't working with newer files anyways
2023-08-12 12:23:03 +02:00
slawkens
cfbcabbfdb Fix accounts editor store_history column not found 2023-08-12 08:13:29 +02:00
slawkens
0f38a677b1 Require PHP min 8.0, older versions are EOL 2023-08-11 22:20:00 +02:00
slawkens
0835b69a93 Merge branch '0.9' into develop 2023-08-11 22:17:27 +02:00
slawkens
538723c405 Added JetBrains logo + notice, thanks for support! 2023-08-11 22:16:07 +02:00
slawkens
4f2e410a71 Merge branch '0.9' into develop 2023-08-11 22:11:47 +02:00
slawkens
a70daa8830 Add version support table + fix badges 2023-08-11 22:11:10 +02:00
slawkens
ae600da28b Merge branch '0.9' into develop 2023-08-11 21:41:18 +02:00
slawkens
d8f1bf0a50 Fix exception when monster doesn't have look defined 2023-08-11 18:52:11 +02:00
Gabriel Pedro
cfc4f3601b feat: add more tests (#229) 2023-08-11 06:40:53 +02:00
slawkens
1a533388e7 Merge branch 'develop' of https://github.com/slawkens/myaac into develop 2023-08-11 06:40:20 +02:00
Gabriel Pedro
98335b8cc0 feat: add more tests (#229) 2023-08-11 06:39:17 +02:00
slawkens
16ebc1f577 Update functions.php 2023-08-10 13:05:17 +02:00
slawkens
7bab8f033c Allow hook file to be callable 2023-08-10 13:00:18 +02:00
slawkens
42d97721bf Merge branch '0.9' into develop 2023-08-10 12:02:54 +02:00
slawkens
23266e05ed Update README.md 2023-08-10 12:02:43 +02:00
Slawomir Boczek
a72d1a3c9f Feature: settings (#216)
* New admin panel Pages: Options + Config [WIP]

* Forgot the plugin example of options

* Rename to settings.php

* Add Settings Class

* New myaac_settings table

* Add $limit parameter to $db->select method

* Add $member var annotation

* Remove useless title_separator from config

* Move $menus to menus.php

Also fix active link when menu item has subpage

* 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

* Change options.php to settings.php

* Change name to settings

* Add Settings menu

* Add Sections + Add setting($key) function

Reorganisation

* Add email + password fields as type

* Update 33.php

* add settings migration

* php 8 compatibility

* add missing hook

* Add categories in tabs, move more settings, revert back getPluginSettings

Categories and sections are now not numbered
Remove example settings plugin

* fix typo

* Update .gitignore

* Add 36th migration for settings table

* Execute migrations just after db connect

* Update plugins.php

* [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

* Rename

* Fix path

* [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

* Add min, max, step to number field option

* Re-enable plugin if disabled and already installed

* Add Settings menu, including all plugins with settings

One change included in previous commit, due to missclick

* Nothing important

* Better boolean detection

* More detailed error message in settings

* Lets call it settings.name instead

* Add new function: only_if, to hide fields when they are not enabled [WIP]

Not fully finished yet

* guild_management: show_if

* Hide section title on show_if

* Fix: check on page load if radio button is checked

* Add: show_if - account_mail_verify

* nothing important

* Rename team_* variables + add to deprecated

* Change variable name

* Extract Settings:save function

* Add settings.callbacks.get

* Move forum config to settings

* Move status config to settings

* Remove whitespaces

* More config to settings: account_types, genders, highscores, admin

* Move signature config to settings

* Move news config to settings

* Rename variable

* 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

* Remove configs from previous commit

* Fix create account, if account_create_character_create is enabled

* Add more deprecated configs

* Add more info into comment

* Update 5-database.php

* Fix menu highlighting & opening

* Update template.php

* Enable script option

* Reword email settings + move two new settings

* add last_kills_limit + move shop

* google_analytics_id

* add mail_lost_account_interval

* Create character blocked words (by @gpedro), just moved to settings

* Fix google_analytics

* create character name config moved to settings

* Fix for install warning - min/max length

* New create character checks configurable: block monsters & spells names

* fixes

* Improve character npc name check

* New setting: donate_column + move donate config to settings

* Add super fancy No Refresh saving with a toast

* Add new possibility: to deny saving setting if condition is not met

* Move database settings to separate category

* Fix default value displaying

* Add database_hash setting

* add last_kills_limit to compat config

* Move create character blocked names down

* Every setting needs to have default

* 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 21:00:45 +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
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
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
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
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
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
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
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
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
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
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
bf137189c5 Update CHANGELOG.md 2023-05-15 00:22:51 +02:00
slawkens
da4e18cb69 Fixes to routing 2023-05-13 12:49:17 +02:00
slawkens
85769c1439 Empty URL = show news 2023-05-13 11:34:51 +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
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
570 changed files with 20126 additions and 13292 deletions

View File

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

5
.gitattributes vendored
View File

@@ -3,8 +3,11 @@
.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
*.sh text eol=lf *.sh text eol=lf

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

@@ -0,0 +1,162 @@
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: [ '8.1', '8.2', '8.3' ]
ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration)
name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }})
steps:
- name: 📌 MySQL Start & init & show db
run: |
sudo /etc/init.d/mysql start
mysql -e 'CREATE DATABASE myaac;' -uroot -proot
mysql -e "SHOW DATABASES" -uroot -proot
- name: Checkout MyAAC
uses: actions/checkout@v4
with:
ref: develop
- uses: actions/setup-node@v4
with:
node-version: 18
- run: npm ci
- name: Checkout TFS
uses: actions/checkout@v4
if: matrix.ots == 'tfs-1.4'
with:
repository: otland/forgottenserver
ref: 1.4
path: ots
- name: Checkout TFS
uses: actions/checkout@v4
if: matrix.ots == 'tfs-master'
with:
repository: otland/forgottenserver
ref: master
path: ots
- name: Checkout Canary
uses: actions/checkout@v4
if: matrix.ots == 'canary-3.1.2'
with:
repository: opentibiabr/canary
ref: v3.1.2
path: ots
- name: Import OTS Schema
run: |
mysql -uroot -proot myaac < ots/schema.sql
- name: Rename config.lua
run: mv ots/config.lua.dist ots/config.lua
- name: Replace mysqlUser (TFS 1.4)
uses: jacobtomlinson/gha-find-replace@v3
if: matrix.ots == 'tfs-1.4'
with:
find: 'mysqlUser = "forgottenserver"'
replace: 'mysqlUser = "root"'
regex: false
include: 'ots/config.lua'
- name: Replace mysqlPass (TFS 1.4)
uses: jacobtomlinson/gha-find-replace@v3
if: matrix.ots == 'tfs-1.4'
with:
find: 'mysqlPass = ""'
replace: 'mysqlPass = "root"'
regex: false
include: 'ots/config.lua'
- name: Replace mysqlDatabase (TFS 1.4)
uses: jacobtomlinson/gha-find-replace@v3
if: matrix.ots == 'tfs-1.4'
with:
find: 'mysqlDatabase = "forgottenserver"'
replace: 'mysqlDatabase = "myaac"'
regex: false
include: 'ots/config.lua'
- name: Replace mysqlDatabase (Canary)
uses: jacobtomlinson/gha-find-replace@v3
if: matrix.ots == 'canary-3.1.2'
with:
find: 'mysqlDatabase = "otservbr-global"'
replace: 'mysqlDatabase = "myaac"'
regex: false
include: 'ots/config.lua'
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: mbstring, dom, fileinfo, mysql, json, xml, pdo, pdo_mysql
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
# Use composer.json for key, if composer.lock is not committed.
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
#key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
- name: Install Composer dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader
- name: Run PHP server
run: nohup php -S localhost:8080 > php.log 2>&1 &
- name: Cypress Run
uses: cypress-io/github-action@v6
env:
CYPRESS_URL: http://localhost:8080
CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/ots
- name: Save screenshots
uses: actions/upload-artifact@v4
if: always()
with:
name: cypress-screenshots-${{ matrix.php-versions }}-${{ matrix.ots }}
path: cypress/screenshots
- name: Upload Cypress Videos
uses: actions/upload-artifact@v4
if: always()
with:
name: cypress-videos-${{ matrix.php-versions }}-${{ matrix.ots }}
path: cypress/videos
- name: Upload PHP Logs
uses: actions/upload-artifact@v4
if: always()
with:
name: php-log-${{ matrix.php-versions }}-${{ matrix.ots }}
path: php.log

View File

@@ -1,13 +1,16 @@
name: PHP Linting name: PHP Linting
on: on:
pull_request: pull_request:
branches: [master, develop] 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@v1 - uses: actions/checkout@v3
- uses: michaelw90/PHP-Lint@master - uses: overtrue/phplint@8.2
with:
path: .
options: --exclude=*.log

46
.github/workflows/phpstan.yml vendored Normal file
View File

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

20
.gitignore vendored
View File

@@ -2,12 +2,21 @@ Thumbs.db
.DS_Store .DS_Store
.idea .idea
#
/.htaccess
# composer # composer
composer.lock composer.phar
vendor vendor
# npm # npm
node_modules node_modules
tools/ext
# cypress
cypress.env.json
cypress/e2e/2-advanced-examples
cypress/screenshots
# created by release.sh # created by release.sh
releases releases
@@ -28,12 +37,19 @@ images/guilds/*
images/editor/* images/editor/*
!images/editor/index.html !images/editor/index.html
# gallery images
images/gallery/*
!images/gallery/index.html
!images/gallery/demon.jpg
!images/gallery/demon_thumb.gif
# cache # cache
system/cache/* system/cache/*
!system/cache/index.html !system/cache/index.html
!system/cache/twig/index.html !system/cache/twig/index.html
!system/cache/signatures/index.html !system/cache/signatures/index.html
!system/cache/plugins/index.html !system/cache/plugins/index.html
!system/cache/persistent/index.html
# logs # logs
system/logs/* system/logs/*
@@ -53,6 +69,8 @@ plugins/*
!plugins/example.json !plugins/example.json
!plugins/account-create-hint.json !plugins/account-create-hint.json
!plugins/account-create-hint !plugins/account-create-hint
!plugins/email-confirmed-reward.json
!plugins/email-confirmed-reward
landing landing
# system # system

View File

@@ -6,12 +6,14 @@
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 #RewriteBase /myaac/
# path relative to web root
#RewriteBase /myaac/
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d

View File

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

View File

@@ -1,9 +1,67 @@
# Changelog # Changelog
## [0.9.0 - x.x.2020] ## [1.0-beta - 18.05.2024]
Minimum PHP version for this release is 8.1.
### Added ### Added
* reworked Admin Panel (@Leesneaks, @gpedro, @slawkens)
* updated to Bootstrap v4
* new Menu
* new Dashboard: statistics, server status
* new Admin Bar showed on top when admin logged in
* new page: Server Data, to reload server data
* Towns, NPCs & Items are stored in permanent cache
* new pages: mass account & teleport tools
* changelogs editor
* revised Accounts & Players editors
* option to add/modify admin menus with plugins
* option to enable/disable plugins
* better, updated TinyMCE editor (v6.x)
* with option to upload images
* list of open source libraries used in project page
* auto-loading of themes, commands & pages from plugins/ folder. You need just to place them in correct folder and they will be loaded automatically - this allows better customization, without interfering with core AAC folders. This will allow in the future automatic updates for plugins as well the AAC as whole.
* config.php moved to Admin Panel -> Settings page
* new console script: aac - using symfony/console
* usage: `php aac` (will list all commands by default)
* example: `php aac cache:clear`
* example: `php aac plugin:install theme-example.zip`
* replace POT Query Builder to Eloquent ORM. Not 100% yet - in some places there is still old $db approach used (@gpedro) (https://github.com/slawkens/myaac/pull/230)
* brand new charming installation page (by @fernandomatos)
* using Bootstrap
* new pages router: nikic/fast-route, allowing for better customisation
* Plugin cronjobs: central control of the cronjobs
* Guild Wars support (available as plugin)
* support for login and create account only by email (configurable)
* with no need for account name
* Google ReCAPTCHA v3 support (available as plugin)
* automatically load towns names from .OTBM file
* support for Account Number
* suggest account number option
* many new functions, hooks and configurables
* better Exception Handler (Whoops - https://github.com/filp/whoops)
* automated website tests (using Cypress)
* csrf protection (https://github.com/slawkens/myaac/pull/235)
* option to restrict Page view to specified group of users (Not-Logged in, logged-in players, tutors, gamemasters etc.)
* phpdebug bar (http://phpdebugbar.com/). Activated if env == 'dev', can be also activated in production by enabling "enable_debugbar" in local config
### Changed ### Changed
* Composer and NPM is now used for external libraries like: Twig, PHPMailer, fast-route, jQuery, Bootstrap etc.
* mail support is disabled on fresh install, can be manually enabled by user
* disable add php pages in admin panel for security. Option to disable plugins upload
* visitors counter shows now user browser, and also if its bot
* changes in required and optional PHP extensions
* reworked Pages:
* Bans
* works now for TFS 1.x
* Highscores
* frags works for TFS 1.x
* cached
* Monsters
* moved pages to Twig:
* experience stages
* update player_deaths entries on name change
* change_password email to be more informal
### Fixed ### Fixed
* hundrets of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here

View File

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

View File

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

View File

@@ -1,24 +1,29 @@
# [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
- PDO PHP Extension - PHP Extensions: pdo, xml, json
- XML PHP Extension - (optional) apache2 mod_rewrite (to use friendly_urls)
- ZIP PHP Extension - (optional) zip PHP Extension (to install plugins)
- (optional) mod_rewrite to use friendly_urls - (optional) gd PHP Extension (for generating signature images)
### Installation ### Installation
@@ -36,13 +41,14 @@ Official website: https://my-aac.org
chmod 660 images/guilds chmod 660 images/guilds
chmod 660 images/houses chmod 660 images/houses
chmod 660 images/gallery chmod 660 images/gallery
chmod -R 770 system/cache chmod -R 760 system/cache
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser. Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.
### Configuration ### Configuration
Check *config.php* to get more informations. 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).
Use *config.local.php* for your local configuration changes. Use *config.local.php* for your local configuration changes.
### Branches ### Branches
@@ -71,7 +77,13 @@ Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our w
### Other Notes ### Other Notes
If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org
## Project supported by JetBrains
Many thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects.
[![JetBrains](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://www.jetbrains.com/?from=https://github.com/slawkens)
### License ### License

40
aac Normal file
View File

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

View File

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

View File

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

View File

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

View File

@@ -1,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,44 +25,43 @@ define('PAGE', $page);
require SYSTEM . 'functions.php'; require SYSTEM . 'functions.php';
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';
if(config('env') === 'dev') { require __DIR__ . '/includes/debugbar.php';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
}
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
require SYSTEM . 'status.php'; require SYSTEM . 'status.php';
require SYSTEM . 'login.php'; require SYSTEM . 'login.php';
require 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 = SYSTEM . 'pages/admin/' . $page . '.php'; $file = __DIR__ . '/pages/' . $page . '.php';
if(!@file_exists($file)) { if(!@file_exists($file)) {
$page = '404'; if (str_contains($page, 'plugins/')) {
$file = SYSTEM . 'pages/404.php'; $file = BASE . $page;
}
else {
$page = '404';
$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

@@ -7,22 +7,33 @@
* @copyright 2020 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Account editor'; $title = 'Account editor';
$admin_base = BASE_URL . 'admin/?p=accounts';
csrfProtect();
$admin_base = ADMIN_URL . '?p=accounts';
$use_datatable = true; $use_datatable = true;
if ($config['account_country']) if (setting('core.account_country'))
require SYSTEM . 'countries.conf.php'; require SYSTEM . 'countries.conf.php';
$nameOrNumberColumn = 'name';
if (USE_ACCOUNT_NUMBER) {
$nameOrNumberColumn = 'number';
}
$hasSecretColumn = $db->hasColumn('accounts', 'secret'); $hasSecretColumn = $db->hasColumn('accounts', 'secret');
$hasCoinsColumn = $db->hasColumn('accounts', 'coins'); $hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); $hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$hasTypeColumn = $db->hasColumn('accounts', 'type'); $hasTypeColumn = $db->hasColumn('accounts', 'type');
$hasGroupColumn = $db->hasColumn('accounts', 'group_id'); $hasGroupColumn = $db->hasColumn('accounts', 'group_id');
if ($config['account_country']) { if (setting('core.account_country')) {
$countries = array(); $countries = array();
foreach (array('pl', 'se', 'br', 'us', 'gb') as $c) foreach (array('pl', 'se', 'br', 'us', 'gb') as $c)
$countries[$c] = $config['countries'][$c]; $countries[$c] = $config['countries'][$c];
@@ -31,8 +42,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 = array("None", "Admin", "Super Admin", "(Admin + Super Admin)"); $web_acc = ACCOUNT_WEB_FLAGS;
$acc_type = array("None", "Normal", "Tutor", "Senior Tutor", "Gamemaster", "God"); $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"/ >
@@ -48,16 +59,16 @@ else if (isset($_REQUEST['search'])) {
if (strlen($search_account) < 3 && !Validator::number($search_account)) { if (strlen($search_account) < 3 && !Validator::number($search_account)) {
echo_error('Player name is too short.'); echo_error('Player name is too short.');
} else { } else {
$query = $db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $db->quote($search_account)); $query = $db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $db->quote($search_account));
if ($query->rowCount() == 1) { if ($query->rowCount() == 1) {
$query = $query->fetch(); $query = $query->fetch();
$id = (int)$query['id']; $id = (int)$query['id'];
} else { } else {
$query = $db->query('SELECT `id`, `name` FROM `accounts` WHERE `name` LIKE ' . $db->quote('%' . $search_account . '%')); $query = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` LIKE ' . $db->quote('%' . $search_account . '%'));
if ($query->rowCount() > 0 && $query->rowCount() <= 10) { if ($query->rowCount() > 0 && $query->rowCount() <= 10) {
$str_construct = 'Do you mean?<ul class="mb-0">'; $str_construct = 'Do you mean?<ul class="mb-0">';
foreach ($query as $row) foreach ($query as $row)
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row['name'] . '</a></li>'; $str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row[$nameOrNumberColumn] . '</a></li>';
$str_construct .= '</ul>'; $str_construct .= '</ul>';
echo_error($str_construct); echo_error($str_construct);
} else if ($query->rowCount() > 10) } else if ($query->rowCount() > 10)
@@ -70,12 +81,11 @@ else if (isset($_REQUEST['search'])) {
?> ?>
<div class="row"> <div class="row">
<?php <?php
$groups = new OTS_Groups_List();
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()) { if (isset($_POST['save']) && $account->isLoaded()) {
$error = false; $error = false;
$_error = ''; $_error = '';
@@ -146,7 +156,7 @@ else if (isset($_REQUEST['search'])) {
$web_lastlogin = strtotime($_POST['web_lastlogin']); $web_lastlogin = strtotime($_POST['web_lastlogin']);
verify_number($web_lastlogin, 'Web Last login', 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);
} }
@@ -186,8 +196,7 @@ else if (isset($_REQUEST['search'])) {
$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->setCustomField('salt', $salt); $account->setCustomField('salt', $salt);
@@ -196,7 +205,7 @@ else if (isset($_REQUEST['search'])) {
$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);
} }
@@ -205,7 +214,7 @@ else if (isset($_REQUEST['search'])) {
} }
} }
} else if ($id == 0) { } else if ($id == 0) {
$accounts_db = $db->query('SELECT `id`, `name`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC'); $accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC');
?> ?>
<div class="col-12 col-sm-12 col-lg-10"> <div class="col-12 col-sm-12 col-lg-10">
<div class="card card-info card-outline"> <div class="card card-info card-outline">
@@ -217,7 +226,7 @@ else if (isset($_REQUEST['search'])) {
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>Name</th> <th><?= ($nameOrNumberColumn == 'number' ? 'Number' : 'Name'); ?></th>
<?php if($hasTypeColumn || $hasGroupColumn): ?> <?php if($hasTypeColumn || $hasGroupColumn): ?>
<th>Position</th> <th>Position</th>
<?php endif; ?> <?php endif; ?>
@@ -228,7 +237,7 @@ else if (isset($_REQUEST['search'])) {
<?php foreach ($accounts_db as $account_lst): ?> <?php foreach ($accounts_db as $account_lst): ?>
<tr> <tr>
<th><?php echo $account_lst['id']; ?></th> <th><?php echo $account_lst['id']; ?></th>
<td><?php echo $account_lst['name']; ?></a></td> <td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td>
<?php if($hasTypeColumn || $hasGroupColumn): ?> <?php if($hasTypeColumn || $hasGroupColumn): ?>
<td> <td>
<?php if ($hasTypeColumn) { <?php if ($hasTypeColumn) {
@@ -260,6 +269,9 @@ else if (isset($_REQUEST['search'])) {
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a> <a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a>
</li> </li>
<li class="nav-item">
<a class="nav-link" id="accounts-logs-tab" data-toggle="pill" href="#accounts-logs">Logs</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a> <a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a>
</li> </li>
@@ -269,7 +281,7 @@ else if (isset($_REQUEST['search'])) {
</li> </li>
<?php endif; <?php endif;
if ($db->hasTable('store_history')) : ?> if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) : ?>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a> <a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a>
</li> </li>
@@ -279,13 +291,19 @@ else if (isset($_REQUEST['search'])) {
<div class="card-body"> <div class="card-body">
<div class="tab-content" id="accounts-tabContent"> <div class="tab-content" id="accounts-tabContent">
<div class="tab-pane fade active show" id="accounts-acc"> <div class="tab-pane fade active show" id="accounts-acc">
<form action="<?php echo $admin_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post"> <form action="<?php echo $admin_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post">
<?php csrf(); ?>
<div class="form-group row"> <div class="form-group row">
<?php if (USE_ACCOUNT_NAME): ?> <?php if (USE_ACCOUNT_NAME): ?>
<div class="col-12 col-sm-12 col-lg-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="name">Account Name:</label> <label for="name">Account Name:</label>
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getName(); ?>"/> <input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getName(); ?>"/>
</div> </div>
<?php elseif (USE_ACCOUNT_NUMBER): ?>
<div class="col-12 col-sm-12 col-lg-4">
<label for="name">Account Number:</label>
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getNumber(); ?>"/>
</div>
<?php endif; ?> <?php endif; ?>
<div class="col-12 col-sm-12 col-lg-5"> <div class="col-12 col-sm-12 col-lg-5">
<div class="form-check"> <div class="form-check">
@@ -313,8 +331,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group">Account Type:</label> <label for="group">Account Type:</label>
<select name="group" id="group" class="form-control"> <select name="group" id="group" class="form-control">
<?php foreach ($acc_type as $id => $a_type): ?> <?php foreach ($acc_type as $_id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($acc_group == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($_id); ?>" <?php echo($acc_group == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -324,8 +342,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group">Account Type:</label> <label for="group">Account Type:</label>
<select name="group" id="group" class="form-control"> <select name="group" id="group" class="form-control">
<?php foreach ($groups->getGroups() as $id => $group): ?> <?php foreach ($groups->getGroups() as $_id => $group): ?>
<option value="<?php echo $id; ?>" <?php echo($acc_group == $id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option> <option value="<?php echo $_id; ?>" <?php echo($acc_group == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -333,8 +351,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="web_flags">Website Access:</label> <label for="web_flags">Website Access:</label>
<select name="web_flags" id="web_flags" class="form-control"> <select name="web_flags" id="web_flags" class="form-control">
<?php foreach ($web_acc as $id => $a_type): ?> <?php foreach ($web_acc as $_id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($account->getWebFlags() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($_id); ?>" <?php echo($account->getWebFlags() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -353,7 +371,7 @@ else if (isset($_REQUEST['search'])) {
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="email">Email:</label><?php echo (config('mail_enabled') ? ' (<a href="' . ADMIN_URL . '?p=mailer&mail_to=' . $account->getEMail() . '">Send Mail</a>)' : ''); ?> <label for="email">Email:</label><?php echo (setting('core.mail_enabled') ? ' (<a href="' . ADMIN_URL . '?p=mailer&mail_to=' . $account->getEMail() . '">Send Mail</a>)' : ''); ?>
<input type="text" class="form-control" id="email" name="email" autocomplete="off" value="<?php echo $account->getEMail(); ?>"/> <input type="text" class="form-control" id="email" name="email" autocomplete="off" value="<?php echo $account->getEMail(); ?>"/>
</div> </div>
<?php if ($hasCoinsColumn): ?> <?php if ($hasCoinsColumn): ?>
@@ -386,14 +404,16 @@ else if (isset($_REQUEST['search'])) {
autocomplete="off" maxlength="20" autocomplete="off" maxlength="20"
value="<?php echo $account->getLocation(); ?>"/> value="<?php echo $account->getLocation(); ?>"/>
</div> </div>
<?php if(setting('core.account_country')): ?>
<div class="col-12 col-sm-12 col-lg-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="rl_country">Country:</label> <label for="rl_country">Country:</label>
<select name="rl_country" id="rl_country" class="form-control"> <select name="rl_country" id="rl_country" class="form-control">
<?php foreach ($countries as $id => $a_type): ?> <?php foreach ($countries as $_id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($account->getCountry() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($_id); ?>" <?php echo($account->getCountry() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
<?php endif; ?>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
@@ -412,12 +432,39 @@ else if (isset($_REQUEST['search'])) {
<a href="<?php echo ADMIN_URL; ?>?p=accounts" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a> <a href="<?php echo ADMIN_URL; ?>?p=accounts" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a>
</form> </form>
</div> </div>
<div class="tab-pane fade" id="accounts-logs">
<div class="row">
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Action</th>
<th>IP</th>
</tr>
</thead>
<tbody>
<?php
$accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
foreach ($accountActions as $i => $log):
$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6));
?>
<tr>
<td><?php echo $i + 1; ?></td>
<td><?= date("M d Y, H:i:s", $log->date); ?></td>
<td><?= $log->action; ?></td>
<td><?= $log->ip; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="tab-pane fade" id="accounts-chars"> <div class="tab-pane fade" id="accounts-chars">
<div class="row"> <div class="row">
<?php <?php
if (isset($account) && $account->isLoaded()) { if (isset($account) && $account->isLoaded()) {
$account_players = $account->getPlayersList(); $account_players = Player::where('account_id', $account->getId())->orderBy('id')->get();
$account_players->orderBy('id');
if (isset($account_players)) { ?> if (isset($account_players)) { ?>
<table class="table table-striped table-condensed table-responsive d-md-table"> <table class="table table-striped table-condensed table-responsive d-md-table">
<thead> <thead>
@@ -430,25 +477,13 @@ else if (isset($_REQUEST['search'])) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php $i= 0; <?php foreach ($account_players as $i => $player): ?>
foreach ($account_players as $i => $player):
$i++;
$player_vocation = $player->getVocation();
$player_promotion = $player->getPromotion();
if (isset($player_promotion)) {
if ((int)$player_promotion > 0)
$player_vocation += ($player_promotion * $config['vocations_amount']);
}
if (isset($config['vocations'][$player_vocation])) {
$vocation_name = $config['vocations'][$player_vocation];
} ?>
<tr> <tr>
<th><?php echo $i; ?></th> <th><?php echo $i + 1; ?></th>
<td><?php echo $player->getName(); ?></td> <td><?php echo $player->name; ?></td>
<td><?php echo $player->getLevel(); ?></td> <td><?php echo $player->level; ?></td>
<td><?php echo $vocation_name; ?></td> <td><?php echo $player->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> <td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
</tr> </tr>
<?php endforeach ?> <?php endforeach ?>
</tbody> </tbody>
@@ -515,7 +550,7 @@ else if (isset($_REQUEST['search'])) {
} ?> } ?>
</div> </div>
<?php endif; <?php endif;
if ($db->hasTable('store_history')) { ?> if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) { ?>
<div class="tab-pane fade" id="accounts-store"> <div class="tab-pane fade" id="accounts-store">
<?php $store_history = $db->query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?> <?php $store_history = $db->query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?>
<table class="table table-striped table-condensed table-responsive d-md-table"> <table class="table table-striped table-condensed table-responsive d-md-table">
@@ -552,18 +587,20 @@ else if (isset($_REQUEST['search'])) {
<div class="row"> <div class="row">
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post"> <form action="<?php echo $admin_base; ?>" method="post">
<label for="name">Account Name:</label> <?php csrf(); ?>
<label for="search">Account Name:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" name="search" value="<?php echo $search_account; ?>" maxlength="32" size="32"> <input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_account); ?>" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>
</div> </div>
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post"> <form action="<?php echo $admin_base; ?>" method="post">
<label for="name">Account ID:</label> <?php csrf(); ?>
<label for="id">Account ID:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" name="id" value="" maxlength="32" size="32"> <input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>

131
admin/pages/changelog.php Normal file
View File

@@ -0,0 +1,131 @@
<?php
/**
* CHANGELOG modifier
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Changelog;
use MyAAC\Models\Changelog as ModelsChangelog;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Changelog';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.';
return;
}
$use_datatable = true;
const CL_LIMIT = 600; // maximum changelog body length
$id = $_GET['id'] ?? 0;
if(!empty($action) && isRequestMethod('post'))
{
$id = $_POST['id'] ?? null;
$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null;
$create_date = isset($_POST['createdate']) ? (int)strtotime($_POST['createdate'] ): null;
$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null;
$type = isset($_POST['type']) ? (int)$_POST['type'] : null;
$where = isset($_POST['where']) ? (int)$_POST['where'] : null;
$errors = array();
if($action == 'new') {
if(isset($body) && Changelog::add($body, $type, $where, $player_id, $create_date, $errors)) {
$body = '';
$type = $where = $player_id = $create_date = 0;
success('Added successful.');
}
}
else if($action == 'delete') {
if (Changelog::delete($id, $errors)) {
success('Deleted successful.');
}
}
else if($action == 'edit')
{
if(isset($id) && !isset($body)) {
$cl = Changelog::get($id);
$body = $cl['body'];
$type = $cl['type'];
$where = $cl['where'];
$create_date = $cl['date'];
$player_id = $cl['player_id'];
}
else {
if(Changelog::update($id, $body, $type, $where, $player_id, $create_date,$errors)) {
$action = $body = '';
$type = $where = $player_id = $create_date = 0;
success('Updated successful.');
}
}
}
else if($action == 'hide') {
if (Changelog::toggleHide($id, $errors, $status)) {
success(($status == 1 ? 'Hide' : 'Show') . ' successful.');
}
}
if(!empty($errors))
error(implode(", ", $errors));
}
$changelogs = ModelsChangelog::orderBy('id')->get()->toArray();
$i = 0;
$log_type = [
['id' => 1, 'icon' => 'added'],
['id' => 2, 'icon' => 'removed'],
['id' => 3, 'icon' => 'changed'],
['id' => 4, 'icon' => 'fixed'],
];
$log_where = [
['id' => 1, 'icon' => 'server'],
['id' => 2, 'icon' => 'website'],
];
foreach($changelogs as $key => &$log)
{
$log['type'] = getChangelogType($log['type']);
$log['where'] = getChangelogWhere($log['where']);
}
if($action == 'edit' || $action == 'new') {
if($action == 'edit') {
$player = new OTS_Player();
$player->load($player_id);
}
$account_players = $account_logged->getPlayersList();
$account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.changelog.form.html.twig', array(
'action' => $action,
'cl_link_form' => constant('ADMIN_URL').'?p=changelog',
'cl_id' => $id ?? null,
'body' => isset($body) ? escapeHtml($body) : '',
'create_date' => $create_date ?? '',
'player_id' => $player_id ?? null,
'account_players' => $account_players,
'type' => $type ?? 0,
'where' => $where ?? 0,
'log_type' => $log_type,
'log_where' => $log_where,
));
}
$twig->display('admin.changelog.html.twig', array(
'changelogs' => $changelogs,
));

View File

@@ -10,7 +10,9 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Dashboard'; $title = 'Dashboard';
if (isset($_GET['clear_cache'])) { csrfProtect();
if (isset($_POST['clear_cache'])) {
if (clearCache()) { if (clearCache()) {
success('Cache cleared.'); success('Cache cleared.');
} else { } else {
@@ -18,7 +20,7 @@ if (isset($_GET['clear_cache'])) {
} }
} }
if (isset($_GET['maintenance'])) { if (isset($_POST['maintenance'])) {
$message = (!empty($_POST['message']) ? $_POST['message'] : null); $message = (!empty($_POST['message']) ? $_POST['message'] : null);
$_status = (isset($_POST['status']) && $_POST['status'] == 'true'); $_status = (isset($_POST['status']) && $_POST['status'] == 'true');
$_status = ($_status ? '0' : '1'); $_status = ($_status ? '0' : '1');
@@ -47,20 +49,15 @@ $tmp = '';
if (fetchDatabaseConfig('site_closed_message', $tmp)) if (fetchDatabaseConfig('site_closed_message', $tmp))
$closed_message = $tmp; $closed_message = $tmp;
echo '<div class="row">'; $settingAdminPanelModules = setting('core.admin_panel_modules');
$twig->display('admin.dashboard.html.twig', array()); if (count($settingAdminPanelModules) > 0) {
echo '</div>';
$configAdminPanelModules = config('admin_panel_modules');
if (isset($configAdminPanelModules)) {
echo '<div class="row">'; echo '<div class="row">';
$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

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

View File

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

View File

@@ -9,10 +9,15 @@
* @copyright 2020 MyAAC * @copyright 2020 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Account Actions'; $title = 'Mass Account Actions';
csrfProtect();
$hasCoinsColumn = $db->hasColumn('accounts', 'coins'); $hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); $hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$freePremium = $config['lua']['freePremium']; $freePremium = $config['lua']['freePremium'];
@@ -22,23 +27,22 @@ function admin_give_points($points)
global $db, $hasPointsColumn; global $db, $hasPointsColumn;
if (!$hasPointsColumn) { if (!$hasPointsColumn) {
error('Points not supported.'); displayMessage('Points not supported.');
return; return;
} }
$statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points'); $statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points');
if (!$statement) { if (!$statement) {
error('Failed to prepare query statement.'); displayMessage('Failed to prepare query statement.');
return; return;
} }
if (!$statement->execute([ if (!Account::query()->increment('premium_points', $points)) {
'points' => $points displayMessage('Failed to add points.');
])) {
error('Failed to add points.');
return; return;
} }
success($points . ' points added to all accounts.'); displayMessage($points . ' points added to all accounts.', true);
} }
function admin_give_coins($coins) function admin_give_coins($coins)
@@ -46,24 +50,16 @@ function admin_give_coins($coins)
global $db, $hasCoinsColumn; global $db, $hasCoinsColumn;
if (!$hasCoinsColumn) { if (!$hasCoinsColumn) {
error('Coins not supported.'); displayMessage('Coins not supported.');
return; return;
} }
$statement = $db->prepare('UPDATE `accounts` SET `coins` = `coins` + :coins'); if (!Account::query()->increment('coins', $coins)) {
if (!$statement) { displayMessage('Failed to add coins.');
error('Failed to prepare query statement.');
return; return;
} }
if (!$statement->execute([ displayMessage($coins . ' coins added to all accounts.', true);
'coins' => $coins
])) {
error('Failed to add coins.');
return;
}
success($coins . ' coins added to all accounts.');
} }
function query_add_premium($column, $value_query, $condition_query = '1=1', $params = []) function query_add_premium($column, $value_query, $condition_query = '1=1', $params = [])
@@ -72,12 +68,12 @@ function query_add_premium($column, $value_query, $condition_query = '1=1', $par
$statement = $db->prepare("UPDATE `accounts` SET `{$column}` = $value_query WHERE $condition_query"); $statement = $db->prepare("UPDATE `accounts` SET `{$column}` = $value_query WHERE $condition_query");
if (!$statement) { if (!$statement) {
error('Failed to prepare query statement.'); displayMessage('Failed to prepare query statement.');
return false; return false;
} }
if (!$statement->execute($params)) { if (!$statement->execute($params)) {
error('Failed to add premium days.'); displayMessage('Failed to add premium days.');
return false; return false;
} }
@@ -89,7 +85,7 @@ function admin_give_premdays($days)
global $db, $freePremium; global $db, $freePremium;
if ($freePremium) { if ($freePremium) {
error('Premium days not supported. Free Premium enabled.'); displayMessage('Premium days not supported. Free Premium enabled.');
return; return;
} }
@@ -101,14 +97,14 @@ function admin_give_premdays($days)
if (query_add_premium('premend', '`premend` + :value', '`premend` > :now', ['value' => $value, 'now' => $now])) { if (query_add_premium('premend', '`premend` + :value', '`premend` > :now', ['value' => $value, 'now' => $now])) {
// set premend // set premend
if (query_add_premium('premend', ':value', '`premend` <= :now', ['value' => $now + $value, 'now' => $now])) { if (query_add_premium('premend', ':value', '`premend` <= :now', ['value' => $now + $value, 'now' => $now])) {
success($days . ' premium days added to all accounts.'); displayMessage($days . ' premium days added to all accounts.', true);
return; return;
} else { } else {
error('Failed to execute set query.'); displayMessage('Failed to execute set query.');
return; return;
} }
} else { } else {
error('Failed to execute append query.'); displayMessage('Failed to execute append query.');
return; return;
} }
@@ -123,20 +119,20 @@ function admin_give_premdays($days)
if (query_add_premium('lastday', '`lastday` + :value', '`lastday` > :now', ['value' => $value, 'now' => $now])) { if (query_add_premium('lastday', '`lastday` + :value', '`lastday` > :now', ['value' => $value, 'now' => $now])) {
// set lastday // set lastday
if (query_add_premium('lastday', ':value', '`lastday` <= :now', ['value' => $now + $value, 'now' => $now])) { if (query_add_premium('lastday', ':value', '`lastday` <= :now', ['value' => $now + $value, 'now' => $now])) {
success($days . ' premium days added to all accounts.'); displayMessage($days . ' premium days added to all accounts.', true);
return; return;
} else { } else {
error('Failed to execute set query.'); displayMessage('Failed to execute set query.');
return; return;
} }
success($days . ' premium days added to all accounts.');
return; return;
} else { } else {
error('Failed to execute append query.'); displayMessage('Failed to execute append query.');
return; return;
} }
} else { } else {
error('Failed to execute set days query.'); displayMessage('Failed to execute set days query.');
return; return;
} }
@@ -149,34 +145,34 @@ function admin_give_premdays($days)
if (query_add_premium('premium_ends_at', '`premium_ends_at` + :value', '`premium_ends_at` > :now', ['value' => $value, 'now' => $now])) { if (query_add_premium('premium_ends_at', '`premium_ends_at` + :value', '`premium_ends_at` > :now', ['value' => $value, 'now' => $now])) {
// set premium_ends_at // set premium_ends_at
if (query_add_premium('premium_ends_at', ':value', '`premium_ends_at` <= :now', ['value' => $now + $value, 'now' => $now])) { if (query_add_premium('premium_ends_at', ':value', '`premium_ends_at` <= :now', ['value' => $now + $value, 'now' => $now])) {
success($days . ' premium days added to all accounts.'); displayMessage($days . ' premium days added to all accounts.', true);
return; return;
} else { } else {
error('Failed to execute set query.'); displayMessage('Failed to execute set query.');
return; return;
} }
} else { } else {
error('Failed to execute append query.'); displayMessage('Failed to execute append query.');
return; return;
} }
return; return;
} }
error('Premium Days not supported.'); displayMessage('Premium Days not supported.');
} }
if (isset($_POST['action']) && $_POST['action']) { if (!empty(ACTION) && isRequestMethod('post')) {
$action = $_POST['action']; $action = ACTION;
if (preg_match("/[^A-z0-9_\-]/", $action)) { if (preg_match("/[^A-z0-9_\-]/", $action)) {
error('Invalid action.'); displayMessage('Invalid action.');
} else { } else {
$value = isset($_POST['value']) ? intval($_POST['value']) : 0; $value = isset($_POST['value']) ? intval($_POST['value']) : 0;
if (!$value) { if (!$value) {
error('Please fill all inputs'); displayMessage('Please fill all inputs');
} else { } else {
switch ($action) { switch ($action) {
case 'give-points': case 'give-points':
@@ -189,14 +185,27 @@ if (isset($_POST['action']) && $_POST['action']) {
admin_give_premdays($value); admin_give_premdays($value);
break; break;
default: default:
error('Action ' . $action . 'not found.'); displayMessage('Action ' . $action . 'not found.');
} }
} }
} }
} }
else {
$twig->display('admin.tools.account.html.twig', array(
'hasCoinsColumn' => $hasCoinsColumn,
'hasPointsColumn' => $hasPointsColumn,
'freePremium' => $freePremium,
));
}
$twig->display('admin.tools.account.html.twig', array( function displayMessage($message, $success = false) {
'hasCoinsColumn' => $hasCoinsColumn, global $twig, $hasCoinsColumn, $hasPointsColumn, $freePremium;
'hasPointsColumn' => $hasPointsColumn,
'freePremium' => $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,107 @@
<?php
/**
* Teleport Admin Tool
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Player;
use MyAAC\Models\PlayerOnline;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Teleport Actions';
csrfProtect();
function admin_teleport_position($x, $y, $z) {
if (!Player::query()->update([
'posx' => $x, 'posy' => $y, 'posz' => $z
])) {
displayMessage('Failed to execute query. Probably already updated.');
return;
}
displayMessage('Player\'s position updated.', true);
}
function admin_teleport_town($town_id) {
if (!Player::query()->update([
'town_id' => $town_id,
])) {
displayMessage('Failed to execute query. Probably already updated.');
return;
}
displayMessage('Player\'s town updated.', true);
}
if (!empty(ACTION) && isRequestMethod('post')) {
$action = ACTION;
if (preg_match("/[^A-z0-9_\-]/", $action)) {
displayMessage('Invalid action.');
} else {
$playersOnline = 0;
if($db->hasTable('players_online')) {// tfs 1.0
$playersOnline = PlayerOnline::count();
} else {
$playersOnline = Player::online()->count();
}
if ($playersOnline > 0) {
displayMessage('Please, close the server before execute this action otherwise players will not be affected.');
return;
}
$town_id = isset($_POST['town_id']) ? intval($_POST['town_id']) : null;
$posx = isset($_POST['posx']) ? intval($_POST['posx']) : null;
$posy = isset($_POST['posy']) ? intval($_POST['posy']) : null;
$posz = isset($_POST['posz']) ? intval($_POST['posz']) : null;
$to_temple = $_POST['to_temple'] ?? null;
switch ($action) {
case 'set-town':
if (!$town_id) {
displayMessage('Please fill all inputs');
return;
}
if (!isset($config['towns'][$town_id])) {
displayMessage('Specified town does not exist');
return;
}
admin_teleport_town($town_id);
break;
case 'set-position':
if (!$to_temple && ($posx < 0 || $posx > 65535 || $posy < 0 || $posy > 65535|| $posz < 0 || $posz > 16)) {
displayMessage('Invalid Position');
return;
}
admin_teleport_position($posx, $posy, $posz);
break;
default:
displayMessage('Action ' . $action . 'not found.');
}
}
}
else {
$twig->display('admin.tools.teleport.html.twig', array());
}
function displayMessage($message, $success = false) {
global $twig;
$success ? success($message): error($message);
$twig->display('admin.tools.teleport.html.twig', array());
}

View File

@@ -7,35 +7,49 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Cache\Cache;
use MyAAC\Models\Menu;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Menus'; $title = 'Menus';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
} }
if (isset($_REQUEST['template'])) { if (isset($_POST['template'])) {
$template = $_REQUEST['template']; $template = $_POST['template'];
if (isset($_REQUEST['menu'])) { if (isset($_POST['menu'])) {
$post_menu = $_REQUEST['menu']; $post_menu = $_POST['menu'];
$post_menu_link = $_REQUEST['menu_link']; $post_menu_link = $_POST['menu_link'];
$post_menu_blank = $_REQUEST['menu_blank']; $post_menu_blank = $_POST['menu_blank'];
$post_menu_color = $_REQUEST['menu_color']; $post_menu_color = $_POST['menu_color'];
if (count($post_menu) != count($post_menu_link)) { if (count($post_menu) != count($post_menu_link)) {
echo 'Menu count is not equal menu links. Something went wrong when sending form.'; echo 'Menu count is not equal menu links. Something went wrong when sending form.';
return; return;
} }
$db->query('DELETE FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($template)); Menu::where('template', $template)->delete();
foreach ($post_menu as $category => $menus) { foreach ($post_menu as $category => $menus) {
foreach ($menus as $i => $menu) { foreach ($menus as $i => $menu) {
if (empty($menu)) // don't save empty menu item if (empty($menu)) // don't save empty menu item
continue; continue;
try { try {
$db->insert(TABLE_PREFIX . 'menu', array('template' => $template, 'name' => $menu, 'link' => $post_menu_link[$category][$i], 'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0, 'color' => str_replace('#', '', $post_menu_color[$category][$i]), 'category' => $category, 'ordering' => $i)); Menu::create([
'template' => $template,
'name' => $menu,
'link' => $post_menu_link[$category][$i],
'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0,
'color' => str_replace('#', '', $post_menu_color[$category][$i]),
'category' => $category,
'ordering' => $i
]);
} catch (PDOException $error) { } catch (PDOException $error) {
warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage()); warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage());
} }
@@ -46,6 +60,7 @@ if (isset($_REQUEST['template'])) {
if ($cache->enabled()) { if ($cache->enabled()) {
$cache->delete('template_menus'); $cache->delete('template_menus');
} }
success('Saved at ' . date('H:i')); success('Saved at ' . date('H:i'));
} }
@@ -56,6 +71,17 @@ if (isset($_REQUEST['template'])) {
echo 'Cannot find template config.php file.'; echo 'Cannot find template config.php file.';
return; return;
} }
if (isset($_GET['reset_colors'])) {
if (isset($config['menu_default_color'])) {
Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]);
success('Colors has been reset.');
}
else {
warning('There is no default color defined, cannot reset colors.');
}
}
if (!isset($config['menu_categories'])) { if (!isset($config['menu_categories'])) {
echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus."; echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus.";
return; return;
@@ -69,17 +95,31 @@ if (isset($_REQUEST['template'])) {
Hint: Add links to external sites using: <b>http://</b> or <b>https://</b> prefix.<br/> Hint: Add links to external sites using: <b>http://</b> or <b>https://</b> prefix.<br/>
Not all templates support blank and colorful links. Not all templates support blank and colorful links.
</p> </p>
<?php if (isset($config['menu_default_color'])) {?>
<form method="post" action="?p=menus&reset_colors" onsubmit="return confirm('Do you really want to reset colors?');">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-danger">Reset Colors to default</button>
</form>
<br/>
<?php } ?>
</div> </div>
<?php <?php
$menus = array(); $menus = Menu::query()
$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(); ->select('name', 'link', 'blank', 'color', 'category', 'ordering')
foreach ($menus_db as $menu) { ->where('enabled', 1)
$menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']); ->where('template', $template)
} ->orderBy('ordering')
->get()
->groupBy('category')
->toArray();
$last_id = array(); $last_id = array();
?> ?>
<form method="post" id="menus-form" action="?p=menus"> <form method="post" id="menus-form" action="?p=menus">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/> <input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-info">Save</button><br/><br/>
<div class="row"> <div class="row">
<?php foreach ($config['menu_categories'] as $id => $cat): ?> <?php foreach ($config['menu_categories'] as $id => $cat): ?>
<div class="col-md-12 col-lg-6"> <div class="col-md-12 col-lg-6">
@@ -91,15 +131,16 @@ if (isset($_REQUEST['template'])) {
<ul class="sortable" id="sortable-<?php echo $id ?>"> <ul class="sortable" id="sortable-<?php echo $id ?>">
<?php <?php
if (isset($menus[$id])) { if (isset($menus[$id])) {
foreach ($menus[$id] as $i => $menu): $i = 0;
foreach ($menus[$id] as $menu):
?> ?>
<li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo $menu['name'] ?>"/> <li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo escapeHtml($menu['name']); ?>"/>
<label>Link:</label> <input type="text" name="menu_link[<?php echo $id ?>][]" value="<?php echo $menu['link'] ?>"/> <label>Link:</label> <input type="text" name="menu_link[<?php echo $id ?>][]" value="<?php echo $menu['link'] ?>"/>
<input type="hidden" name="menu_blank[<?php echo $id ?>][]" value="0"/> <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> <label><input class="blank-checkbox" type="checkbox" <?php echo($menu['blank'] == 1 ? 'checked' : '') ?>/><span title="Open in New Window">New Window</span></label>
<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="#<?php echo $menu['color'] ?>"/> <input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo (empty($menu['color']) ? ($config['menu_default_color'] ?? '#ffffff') : $menu['color']); ?>"/>
<a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li> <a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li>
<?php $last_id[$id] = $i; <?php $i++; $last_id[$id] = $i;
endforeach; endforeach;
} ?> } ?>
</ul> </ul>
@@ -110,7 +151,7 @@ if (isset($_REQUEST['template'])) {
</div> </div>
<div class="row pb-2"> <div class="row pb-2">
<div class="col-md-12"> <div class="col-md-12">
<button type="submit" class="btn btn-info"><i class="fas fa-update"></i> Save</button> <button type="submit" class="btn btn-info">Save</button>
<?php <?php
echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>'; echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>';
?> ?>
@@ -120,12 +161,13 @@ if (isset($_REQUEST['template'])) {
<?php <?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 = Menu::select('template')->distinct()->get()->toArray();
foreach ($templates as $key => $value) { foreach ($templates as $key => $value) {
$file = TEMPLATES . $value['template'] . '/config.php'; $file = TEMPLATES . $value['template'] . '/config.php';
if (!file_exists($file)) { if (!file_exists($file)) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,21 @@
<?php
use MyAAC\Models\Account;
use MyAAC\Models\Guild;
use MyAAC\Models\House;
use MyAAC\Models\Monster;
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$count = $eloquentConnection->query()
->select([
'total_accounts' => Account::selectRaw('COUNT(id)'),
'total_players' => Player::selectRaw('COUNT(id)'),
'total_guilds' => Guild::selectRaw('COUNT(id)'),
'total_monsters' => Monster::selectRaw('COUNT(id)'),
'total_houses' => House::selectRaw('COUNT(id)'),
])->first();
$twig->display('statistics.html.twig', array(
'count' => $count,
));

View File

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

View File

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

156
admin/pages/news.php Normal file
View File

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

41
admin/pages/notepad.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
/**
* Notepad
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Notepad as ModelsNotepad;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Notepad';
csrfProtect();
/**
* @var OTS_Account $account_logged
*/
$_content = '';
$notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first();
if (isset($_POST['content'])) {
$_content = html_entity_decode(stripslashes($_POST['content']));
if (!$notepad) {
ModelsNotepad::create([
'account_id' => $account_logged->getId(),
'content' => $_content
]);
}
else {
ModelsNotepad::where('account_id', $account_logged->getId())->update(['content' => $_content]);
}
success('Saved at ' . date('H:i'));
} else {
if ($notepad)
$_content = $notepad->content;
}
$twig->display('admin.notepad.html.twig', ['content' => $_content]);

View File

@@ -1,16 +1,14 @@
<?php <?php
/** /**
* Account confirm mail * Open Source libraries
* Keept for compability
* *
* @package MyAAC * @package MyAAC
* @author Slawkens <slawkens@gmail.com> * @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC * @copyright 2023 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!');
if($action == 'confirm_email') { $title = 'Open Source';
require_once PAGES . 'account/confirm_email.php';
} $twig->display('admin.open_source.html.twig');
?>

133
admin/pages/pages.php Normal file
View File

@@ -0,0 +1,133 @@
<?php
/**
* Pages
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Pages as ModelsPages;
use MyAAC\Admin\Pages;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Pages';
$use_datatable = true;
csrfProtect();
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.';
return;
}
header('X-XSS-Protection:0');
$name = $p_title = null;
$groups = new OTS_Groups_List();
$php = false;
$enable_tinymce = true;
$access = 0;
// some constants, used mainly by database (cannot by modified without schema changes)
const PAGE_TITLE_LIMIT = 30;
const PAGE_NAME_LIMIT = 30;
const PAGE_BODY_LIMIT = 65535; // maximum page body length
if (!empty($action) && isRequestMethod('post')) {
if ($action == 'delete' || $action == 'edit' || $action == 'hide') {
$id = $_POST['id'];
}
if (isset($_POST['name'])) {
$name = $_POST['name'];
}
if (isset($_POST['title'])) {
$p_title = $_POST['title'];
}
$php = isset($_POST['php']) && $_POST['php'] == 1;
$enable_tinymce = (isset($_POST['enable_tinymce']) && $_POST['enable_tinymce'] == 1) ?: $enable_tinymce;
if ($php) {
$body = $_POST['body'];
}
else if (isset($_POST['body'])) {
//$body = $_POST['body'];
$body = html_entity_decode(stripslashes($_POST['body']));
}
if (isset($_POST['access'])) {
$access = $_POST['access'];
}
$errors = array();
$player_id = 1;
if ($action == 'new') {
if (isset($p_title) && Pages::add($name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
$name = $p_title = $body = '';
$player_id = $access = 0;
$php = false;
$enable_tinymce = true;
success('Added successful.');
}
} else if ($action == 'delete') {
if (Pages::delete($id, $errors))
success('Page with id ' . $id . ' has been deleted');
} else if ($action == 'edit') {
if (isset($id) && !isset($_POST['name'])) {
$_page = Pages::get($id);
$name = $_page['name'];
$p_title = $_page['title'];
$body = $_page['body'];
$php = $_page['php'] == '1';
$enable_tinymce = $_page['enable_tinymce'] == '1';
$access = $_page['access'];
} else {
if(Pages::update($id, $name, $p_title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
$action = $name = $p_title = $body = '';
$player_id = 1;
$access = 0;
$php = false;
$enable_tinymce = true;
success('Updated successful.');
}
}
} else if ($action == 'hide') {
if (Pages::toggleHide($id, $errors, $status)) {
success(($status == 0 ? 'Show' : 'Hide') . ' successful.');
}
}
if (!empty($errors))
error(implode(", ", $errors));
}
$pages = ModelsPages::all()->map(function ($e) {
return [
'link' => getFullLink($e->name, $e->name, true),
'title' => substr($e->title, 0, 20),
'php' => $e->php == '1',
'id' => $e->id,
'hide' => $e->hide
];
})->toArray();
$twig->display('admin.pages.form.html.twig', [
'action' => $action,
'id' => $action == 'edit' ? $id : null,
'name' => $name,
'title' => $p_title,
'php' => $php,
'enable_tinymce' => $enable_tinymce,
'body' => isset($body) ? escapeHtml($body) : '',
'groups' => $groups->getGroups(),
'access' => $access
]);
$twig->display('admin.pages.html.twig', [
'pages' => $pages
]);

View File

@@ -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> <iframe src="<?php echo ADMIN_URL; ?>tools/phpinfo.php" width="1024" height="550"></iframe>

View File

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

140
admin/pages/plugins.php Normal file
View File

@@ -0,0 +1,140 @@
<?php
/**
* Plugins
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Plugins;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Plugin manager';
csrfProtect();
$use_datatable = true;
if (!getBoolean(setting('core.admin_plugins_manage_enable'))) {
warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.');
}
else {
$twig->display('admin.plugins.form.html.twig');
if (isset($_POST['uninstall'])) {
$uninstall = $_POST['uninstall'];
if (Plugins::uninstall($uninstall)) {
success('Successfully uninstalled plugin ' . $uninstall);
} else {
error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError());
}
} else if (isset($_POST['enable'])) {
$enable = $_POST['enable'];
if (Plugins::enable($enable)) {
success('Successfully enabled plugin ' . $enable);
} else {
error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError());
}
} else if (isset($_POST['disable'])) {
$disable = $_POST['disable'];
if (Plugins::disable($disable)) {
success('Successfully disabled plugin ' . $disable);
} else {
error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError());
}
} else if (isset($_FILES['plugin']['name'])) {
$file = $_FILES['plugin'];
$filename = $file['name'];
$tmp_name = $file['tmp_name'];
$type = $file['type'];
$name = explode('.', $filename);
$accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', 'application/octet-stream', 'application/zip-compressed');
if (isset($file['error'])) {
$error = 'Error uploading file';
switch ($file['error']) {
case UPLOAD_ERR_OK:
$error = false;
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
$error .= ' - file too large (limit of ' . ini_get('upload_max_filesize') . ' bytes). You can enlarge the limits by changing "upload_max_filesize" in php.ini';
break;
case UPLOAD_ERR_PARTIAL:
$error .= ' - file upload was not completed.';
break;
case UPLOAD_ERR_NO_FILE:
$error .= ' - zero-length file uploaded.';
break;
default:
$error .= ' - internal error #' . $file['error'];
break;
}
}
if (isset($error) && $error != false) {
error($error);
} else {
if (is_uploaded_file($file['tmp_name'])) {
$filetype = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if ($filetype == 'zip') // check if it is zipped/compressed file
{
$tmp_filename = pathinfo($filename, PATHINFO_FILENAME);
$targetzip = BASE . 'plugins/' . $tmp_filename . '.zip';
if (move_uploaded_file($tmp_name, $targetzip)) { // move uploaded file
if (Plugins::install($targetzip)) {
foreach (Plugins::getWarnings() as $warning) {
warning($warning);
}
$info = Plugins::getPluginJson();
success((isset($info['name']) ? '<strong>' . $info['name'] . '</strong> p' : 'P') . 'lugin has been successfully installed.');
} else {
$error = Plugins::getError();
error(!empty($error) ? $error : 'Unexpected error happened while installing plugin. Please try again later.');
}
unlink($targetzip); // delete the Zipped file
} else
error('There was a problem with the upload. Please try again.');
} else {
error('The file you are trying to upload is not a .zip file. Please try again.');
}
} else {
error('Error uploading file - unknown error.');
}
}
}
}
$plugins = array();
foreach (get_plugins(true) as $plugin) {
$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json');
$plugin_info = json_decode($string, true);
if (!$plugin_info) {
warning('Cannot load plugin info ' . $plugin . '.json');
} else {
$disabled = (str_contains($plugin, 'disabled.'));
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
$plugins[] = array(
'name' => $plugin_info['name'] ?? '',
'description' => $plugin_info['description'] ?? '',
'version' => $plugin_info['version'] ?? '',
'author' => $plugin_info['author'] ?? '',
'contact' => $plugin_info['contact'] ?? '',
'file' => $pluginOriginal,
'enabled' => !$disabled,
'uninstall' => isset($plugin_info['uninstall'])
);
}
}
$twig->display('admin.plugins.html.twig', array(
'plugins' => $plugins
));

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

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

@@ -0,0 +1,37 @@
<?php
/**
* Statistics
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Account;
use MyAAC\Models\Guild;
use MyAAC\Models\House;
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Statistics';
$total_accounts = Account::count();
$total_players = Player::count();
$total_guilds = Guild::count();
$total_houses = House::count();
$points = Account::select(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')])
->orderByDesc('premium_points')
->limit(10)
->get()
->toArray();
$twig->display('admin.statistics.html.twig', array(
'total_accounts' => $total_accounts,
'total_players' => $total_players,
'total_guilds' => $total_guilds,
'total_houses' => $total_houses,
'account_type' => (USE_ACCOUNT_NAME ? 'name' : 'number'),
'points' => $points
));

View File

@@ -21,7 +21,7 @@ if (preg_match("/[^A-z0-9_\-]/", $tool)) {
return; return;
} }
$file = SYSTEM . 'pages/admin/tools/' . $tool . '.php'; $file = ADMIN . 'tools/' . $tool . '.php';
if (@file_exists($file)) { if (@file_exists($file)) {
require $file; require $file;

View File

@@ -47,4 +47,3 @@ function version_revert($version)
$release = $version; $release = $version;
return $major . '.' . $minor . '.' . $release; return $major . '.' . $minor . '.' . $release;
}*/ }*/
?>

66
admin/pages/visitors.php Normal file
View File

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

View File

@@ -2,25 +2,28 @@
$menus = [ $menus = [
['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'], ['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'],
['name' => 'News', 'icon' => 'newspaper', 'order' => 20, 'link' => ['name' => 'Settings', 'icon' => 'edit', 'order' => 19, 'link' =>
require ADMIN . 'includes/settings_menus.php'
],
['name' => 'News', 'icon' => 'newspaper', 'order' => 20, 'link' =>
[ [
['name' => 'View', 'link' => 'news', 'order' => 10], ['name' => 'View', 'link' => 'news', 'icon' => 'list', 'order' => 10],
['name' => 'Add news', 'link' => 'news&action=new&type=1', 'order' => 20], ['name' => 'Add news', 'link' => 'news&action=new&type=1', 'icon' => 'plus', 'order' => 20],
['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'order' => 30], ['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'icon' => 'plus', 'order' => 30],
['name' => 'Add article', 'link' => 'news&action=new&type=3', 'order' => 40], ['name' => 'Add article', 'link' => 'news&action=new&type=3', 'icon' => 'plus', 'order' => 40],
], ],
], ],
['name' => 'Changelogs', 'icon' => 'newspaper', 'order' => 30, 'link' => ['name' => 'Changelogs', 'icon' => 'newspaper', 'order' => 30, 'link' =>
[ [
['name' => 'View', 'link' => 'changelog', 'order' => 10], ['name' => 'View', 'link' => 'changelog', 'icon' => 'list', 'order' => 10],
['name' => 'Add', 'link' => 'changelog&action=new', 'order' => 20], ['name' => 'Add', 'link' => 'changelog&action=new', 'icon' => 'plus', 'order' => 20],
], ],
], ],
['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !config('mail_enabled')], ['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !setting('core.mail_enabled')],
['name' => 'Pages', 'icon' => 'book', 'order' => 50, 'link' => ['name' => 'Pages', 'icon' => 'book', 'order' => 50, 'link' =>
[ [
['name' => 'View', 'link' => 'pages', 'order' => 10], ['name' => 'View', 'link' => 'pages', 'icon' => 'list', 'order' => 10],
['name' => 'Add', 'link' => 'pages&action=new', 'order' => 20], ['name' => 'Add', 'link' => 'pages&action=new', 'icon' => 'plus', 'order' => 20],
], ],
], ],
['name' => 'Menus', 'icon' => 'list', 'order' => 60, 'link' => 'menus'], ['name' => 'Menus', 'icon' => 'list', 'order' => 60, 'link' => 'menus'],
@@ -28,23 +31,23 @@ $menus = [
['name' => 'Server Data', 'icon' => 'gavel', 'order' => 80, 'link' => 'data'], ['name' => 'Server Data', 'icon' => 'gavel', 'order' => 80, 'link' => 'data'],
['name' => 'Editor', 'icon' => 'edit', 'order' => 90, 'link' => ['name' => 'Editor', 'icon' => 'edit', 'order' => 90, 'link' =>
[ [
['name' => 'Accounts', 'link' => 'accounts', 'order' => 10], ['name' => 'Accounts', 'link' => 'accounts', 'icon' => 'users', 'order' => 10],
['name' => 'Players', 'link' => 'players', 'order' => 20], ['name' => 'Players', 'link' => 'players', 'icon' => 'user-astronaut', 'order' => 20],
], ],
], ],
['name' => 'Tools', 'icon' => 'tools', 'order' => 100, 'link' => ['name' => 'Tools', 'icon' => 'tools', 'order' => 100, 'link' =>
[ [
['name' => 'Mass Account Actions', 'link' => 'tools&tool=account', 'order' => 10], ['name' => 'Mass Account Actions', 'link' => 'mass_account', 'icon' => 'globe', 'order' => 10],
['name' => 'Mass Teleport Actions', 'link' => 'tools&tool=teleport', 'order' => 20], ['name' => 'Mass Teleport Actions', 'link' => 'mass_teleport', 'icon' => 'globe', 'order' => 20],
['name' => 'Notepad', 'link' => 'notepad', 'order' => 30], ['name' => 'Notepad', 'link' => 'notepad', 'icon' => 'marker', 'order' => 30],
['name' => 'phpinfo', 'link' => 'phpinfo', 'order' => 40], ['name' => 'phpinfo', 'link' => 'phpinfo', 'icon' => 'server', 'order' => 40],
], ],
], ],
['name' => 'Logs', 'icon' => 'bug', 'order' => 110, 'link' => ['name' => 'Logs', 'icon' => 'bug', 'order' => 110, 'link' =>
[ [
['name' => 'Logs', 'link' => 'logs', 'order' => 10], ['name' => 'Logs', 'link' => 'logs', 'icon' => 'book', 'order' => 10],
['name' => 'Reports', 'link' => 'reports', 'order' => 20], ['name' => 'Reports', 'link' => 'reports', 'icon' => 'book', 'order' => 20],
['name' => 'Visitors', 'icon' => 'user', 'link' => 'visitors', 'order' => 30], ['name' => 'Visitors', 'link' => 'visitors', 'icon' => 'user', 'order' => 30],
], ],
], ],
]; ];

View File

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

View File

@@ -2,6 +2,7 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<?php $hooks->trigger(HOOK_ADMIN_HEAD_START); ?>
<?php echo template_header(true); ?> <?php echo template_header(true); ?>
<title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title> <title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
@@ -16,8 +17,10 @@
<script src="<?php echo BASE_URL; ?>tools/js/respond.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/respond.min.js"></script>
<![endif]--> <![endif]-->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
<?php $hooks->trigger(HOOK_ADMIN_HEAD_END); ?>
</head> </head>
<body class="sidebar-mini "> <body class="sidebar-mini ">
<?php $hooks->trigger(HOOK_ADMIN_BODY_START); ?>
<?php if ($logged && admin()) { ?> <?php if ($logged && admin()) { ?>
<div class="wrapper"> <div class="wrapper">
<nav class="main-header navbar navbar-expand navbar-white navbar-light"> <nav class="main-header navbar navbar-expand navbar-white navbar-light">
@@ -65,7 +68,7 @@
if (!$has_child) { ?> if (!$has_child) { ?>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link<?php echo(strpos($menu['link'], $page) !== false ? ' active' : '') ?>" href="?p=<?php echo $menu['link'] ?>"> <a class="nav-link<?php echo(strpos($menu['link'], $page) !== false ? ' active' : '') ?>" href="?p=<?php echo $menu['link'] ?>">
<i class="nav-icon fas fa-<?php echo(isset($menu['icon']) ? $menu['icon'] : 'link') ?>"></i> <i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i>
<p><?php echo $menu['name'] ?></p> <p><?php echo $menu['name'] ?></p>
</a> </a>
</li> </li>
@@ -73,18 +76,18 @@
} else if ($has_child) { } else if ($has_child) {
$used_menu = null; $used_menu = null;
$nav_construct = ''; $nav_construct = '';
foreach ($menu['link'] as $category => $sub_menu) { foreach ($menu['link'] as $sub_category => $sub_menu) {
$nav_construct .= '<li class="nav-item"><a href="?p=' . $sub_menu['link'] . '" class="nav-link'; $nav_construct .= '<li class="nav-item"><a href="?p=' . $sub_menu['link'] . '" class="nav-link';
if ($page == $sub_menu['link']) { if ($_SERVER['QUERY_STRING'] == 'p=' . $sub_menu['link']) {
$nav_construct .= ' active'; $nav_construct .= ' active';
$used_menu = true; $used_menu = true;
} }
$nav_construct .= '"><i class="far fa-' . (isset($sub_menu['icon']) ? $sub_menu['icon'] : 'circle') . ' nav-icon"></i><p>' . $sub_menu['name'] . '</p></a></li>'; $nav_construct .= '"><i class="fas fa-' . ($sub_menu['icon'] ?? 'circle') . ' nav-icon"></i><p>' . $sub_menu['name'] . '</p></a></li>';
} }
?> ?>
<li class="nav-item has-treeview<?php echo($used_menu ? ' menu-open' : '') ?>"> <li class="nav-item has-treeview<?php echo($used_menu ? ' menu-open' : '') ?>">
<a href="#" class="nav-link<?php echo($used_menu ? ' active' : '') ?>"> <a href="#" class="nav-link<?php echo($used_menu ? ' active' : '') ?>">
<i class="nav-icon fas fa-<?php echo(isset($menu['icon']) ? $menu['icon'] : 'link') ?>"></i> <i class="nav-icon fas fa-<?php echo($menu['icon'] ?? 'link') ?>"></i>
<p><?php echo $menu['name'] ?></p><i class="right fas fa-angle-left"></i> <p><?php echo $menu['name'] ?></p><i class="right fas fa-angle-left"></i>
</a> </a>
<ul class="nav nav-treeview"> <ul class="nav nav-treeview">
@@ -159,6 +162,9 @@
<p><h5><a href="http://my-aac.org/" target="_blank"><i class="fas fa-shoe-prints"></i> MyAAC Official</a></h5> <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> <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> </div>
</aside> </aside>
@@ -185,12 +191,13 @@ if ($logged && admin()) {
]); ]);
} }
?> ?>
<script src="<?php echo BASE_URL; ?>tools/js/bootstrap.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/ext/bootstrap/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/ext/jquery-ui/jquery-ui.min.js"></script>
<?php if (isset($use_datatable)) { ?> <?php if (isset($use_datatable)) { ?>
<script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script>
<script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script>
<?php } ?> <?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

@@ -13,4 +13,3 @@ if(!function_exists('phpinfo'))
die('phpinfo() disabled on this web server.'); die('phpinfo() disabled on this web server.');
phpinfo(); phpinfo();
?>

View File

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

View File

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

View File

@@ -23,19 +23,21 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
if (version_compare(phpversion(), '7.1', '<')) die('PHP version 7.1 or higher is required.'); if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
const MYAAC = true; const MYAAC = true;
const MYAAC_VERSION = '0.9.0-dev'; const MYAAC_VERSION = '1.0-beta';
const DATABASE_VERSION = 33; const DATABASE_VERSION = 40;
const TABLE_PREFIX = 'myaac_'; const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true)); define('START_TIME', microtime(true));
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));
define('IS_CLI', in_array(php_sapi_name(), ['cli', 'phpdb'])); define('IS_CLI', in_array(php_sapi_name(), ['cli', 'phpdb']));
// account flags // account flags
const FLAG_NONE = 0;
const FLAG_ADMIN = 1; const FLAG_ADMIN = 1;
const FLAG_SUPER_ADMIN = 2; const FLAG_SUPER_ADMIN = 2;
const FLAG_SUPER_BOTH = 3;
const FLAG_CONTENT_PAGES = 4; const FLAG_CONTENT_PAGES = 4;
const FLAG_CONTENT_MAILER = 8; const FLAG_CONTENT_MAILER = 8;
const FLAG_CONTENT_NEWS = 16; const FLAG_CONTENT_NEWS = 16;
@@ -49,14 +51,27 @@ const FLAG_CONTENT_FAQ = 2048;
const FLAG_CONTENT_MENUS = 4096; const FLAG_CONTENT_MENUS = 4096;
const FLAG_CONTENT_PLAYERS = 8192; const FLAG_CONTENT_PLAYERS = 8192;
// account access types
const ACCOUNT_WEB_FLAGS = [
FLAG_NONE => 'None',
FLAG_ADMIN =>'Admin',
FLAG_SUPER_ADMIN => 'Super Admin',
FLAG_SUPER_BOTH =>'(Admin + Super Admin)',
];
// news // news
const NEWS = 1; const NEWS = 1;
const TICKER = 2; const TICKER = 2;
const 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
const BASE = __DIR__ . '/'; const BASE = __DIR__ . '/';
const ADMIN = BASE . 'admin/'; const ADMIN = BASE . ADMIN_PANEL_FOLDER . '/';
const SYSTEM = BASE . 'system/'; const SYSTEM = BASE . 'system/';
const CACHE = SYSTEM . 'cache/'; const CACHE = SYSTEM . 'cache/';
const LOCALE = SYSTEM . 'locale/'; const LOCALE = SYSTEM . 'locale/';
@@ -93,10 +108,19 @@ const TFS_FIRST = TFS_02;
const TFS_LAST = TFS_03; const TFS_LAST = TFS_03;
// other definitions // other definitions
const MAIL_MAIL = 0;
const MAIL_SMTP = 1;
const SMTP_SECURITY_NONE = 0;
const SMTP_SECURITY_SSL = 1;
const SMTP_SECURITY_TLS = 2;
const ACCOUNT_NUMBER_LENGTH = 8; const ACCOUNT_NUMBER_LENGTH = 8;
session_save_path(SESSIONS_DIR); if (!IS_CLI) {
session_start(); session_save_path(SESSIONS_DIR);
session_start();
}
// basedir // basedir
$basedir = ''; $basedir = '';
@@ -105,7 +129,7 @@ $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(['/admin', '/install', '/tools'], '', $basedir); $basedir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $basedir);
define('BASE_DIR', $basedir); define('BASE_DIR', $basedir);
if(!IS_CLI) { if(!IS_CLI) {
@@ -119,13 +143,28 @@ if(!IS_CLI) {
} }
} }
define('SERVER_URL', 'http' . (isset($_SERVER['HTTPS'][0]) && strtolower($_SERVER['HTTPS']) === 'on' ? 's' : '') . '://' . $baseHost); define('SERVER_URL', 'http' . (isHttps() ? 's' : '') . '://' . $baseHost);
define('BASE_URL', SERVER_URL . BASE_DIR . '/'); define('BASE_URL', SERVER_URL . BASE_DIR . '/');
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/'); 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']);
}
require SYSTEM . 'exception.php'; if (file_exists(BASE . 'config.local.php')) {
require BASE . 'config.local.php';
}
/** @var array $config */
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'; $autoloadFile = VENDOR . 'autoload.php';
@@ -134,3 +173,11 @@ if (!is_file($autoloadFile)) {
} }
require $autoloadFile; require $autoloadFile;
function isHttps(): bool
{
return
(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
|| (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443);
}

View File

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

2922
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

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

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

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('#password_confirm').type('test1234')
cy.get('#character_name').type('Slaw')
cy.get('#sex1').check()
cy.get('#vocation1').check()
cy.get('#accept_rules').check()
cy.get('#form').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,174 @@
describe('Check Public Pages', () => {
/// news
it('Go to news page', () => {
cy.visit({
url: Cypress.env('URL') + '/news',
method: 'GET',
})
})
it('Go to news archive page', () => {
cy.visit({
url: Cypress.env('URL') + '/news/archive',
method: 'GET',
})
})
it('Go to changelog page', () => {
cy.visit({
url: Cypress.env('URL') + '/changelog',
method: 'GET',
})
})
/// account management
it('Go to account manage page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/manage',
method: 'GET',
})
})
it('Go to account create page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/create',
method: 'GET',
})
})
it('Go to account lost page', () => {
cy.visit({
url: Cypress.env('URL') + '/account/lost',
method: 'GET',
})
})
it('Go to rules page', () => {
cy.visit({
url: Cypress.env('URL') + '/rules',
method: 'GET',
})
})
// community
it('Go to online page', () => {
cy.visit({
url: Cypress.env('URL') + '/online',
method: 'GET',
})
})
it('Go to characters list page', () => {
cy.visit({
url: Cypress.env('URL') + '/characters',
method: 'GET',
})
})
it('Go to guilds page', () => {
cy.visit({
url: Cypress.env('URL') + '/guilds',
method: 'GET',
})
})
it('Go to highscores page', () => {
cy.visit({
url: Cypress.env('URL') + '/highscores',
method: 'GET',
})
})
it('Go to last kills page', () => {
cy.visit({
url: Cypress.env('URL') + '/last-kills',
method: 'GET',
})
})
it('Go to houses page', () => {
cy.visit({
url: Cypress.env('URL') + '/houses',
method: 'GET',
})
})
it('Go to bans page', () => {
cy.visit({
url: Cypress.env('URL') + '/bans',
method: 'GET',
})
})
it('Go to forum page', () => {
cy.visit({
url: Cypress.env('URL') + '/forum',
method: 'GET',
})
})
it('Go to team page', () => {
cy.visit({
url: Cypress.env('URL') + '/team',
method: 'GET',
})
})
// library
it('Go to creatures page', () => {
cy.visit({
url: Cypress.env('URL') + '/creatures',
method: 'GET',
})
})
it('Go to spells page', () => {
cy.visit({
url: Cypress.env('URL') + '/spells',
method: 'GET',
})
})
it('Go to server info page', () => {
cy.visit({
url: Cypress.env('URL') + '/server-info',
method: 'GET',
})
})
it('Go to commands page', () => {
cy.visit({
url: Cypress.env('URL') + '/commands',
method: 'GET',
})
})
it('Go to downloads page', () => {
cy.visit({
url: Cypress.env('URL') + '/downloads',
method: 'GET',
})
})
it('Go to gallery page', () => {
cy.visit({
url: Cypress.env('URL') + '/gallery',
method: 'GET',
})
})
it('Go to experience table page', () => {
cy.visit({
url: Cypress.env('URL') + '/exp-table',
method: 'GET',
})
})
it('Go to faq page', () => {
cy.visit({
url: Cypress.env('URL') + '/faq',
method: 'GET',
})
})
})

View File

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

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

335
index.php
View File

@@ -24,22 +24,29 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\UsageStatistics;
use MyAAC\Visitors;
require_once 'common.php'; require_once 'common.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';
$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));
}
else {
$tmp = explode('.', $uri);
}
if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) {
$tmp = explode('.', $uri);
$_REQUEST['name'] = urldecode($tmp[0]); $_REQUEST['name'] = urldecode($tmp[0]);
chdir(TOOLS . 'signature'); chdir(TOOLS . 'signature');
@@ -47,146 +54,21 @@ 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!'); exit();
} }
$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(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'),
'/^bans\/[0-9]+\/?$/' => array('subtopic' => 'bans', 'page' => '$1'),
'/^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'),
'/^creatures\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'creatures', 'creature' => '$1'),
'/^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;
}
}
}
}
// 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(); $template_place_holders = array();
require_once SYSTEM . 'init.php'; require_once SYSTEM . 'init.php';
// verify myaac tables exists in database
if(!$db->hasTable('myaac_account_actions')) {
throw new RuntimeException('Seems that the table <strong>myaac_account_actions</strong> of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting <a href="' . BASE_URL . 'install">this</a> url.');
}
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
require_once SYSTEM . 'template.php'; require_once SYSTEM . 'template.php';
require_once SYSTEM . 'login.php'; require_once SYSTEM . 'login.php';
require_once SYSTEM . 'status.php'; require_once SYSTEM . 'status.php';
@@ -194,13 +76,52 @@ 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'; // backward support for gesior
if(setting('core.backward_support')) {
define('INITIALIZED', true);
$SQL = $db;
$layout_header = template_header();
$layout_name = $template_path;
$news_content = '';
$tickers_content = '';
$main_content = '';
$config['access_admin_panel'] = 2;
$group_id_of_acc_logged = 0;
if($logged && $account_logged)
$group_id_of_acc_logged = $account_logged->getGroupId();
$config['site'] = &$config;
$config['server'] = &$config['lua'];
$config['site']['shop_system'] = setting('core.gifts_system');
$config['site']['gallery_page'] = true;
if(!isset($config['vdarkborder']))
$config['vdarkborder'] = '#505050';
if(!isset($config['darkborder']))
$config['darkborder'] = '#D4C0A1';
if(!isset($config['lightborder']))
$config['lightborder'] = '#F1E0C6';
$config['site']['download_page'] = true;
$config['site']['serverinfo_page'] = true;
$config['site']['screenshot_page'] = true;
$forumSetting = setting('core.forum');
if($forumSetting != '')
$config['forum_link'] = (strtolower($forumSetting) === 'site' ? getLink('forum') : $forumSetting);
foreach($status as $key => $value)
$config['status']['serverStatus_' . $key] = $value;
}
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;
@@ -223,8 +144,7 @@ if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_stat
} }
if($should_report) { if($should_report) {
require_once LIBS . 'usage_statistics.php'; UsageStatistics::report();
Usage_Statistics::report();
updateDatabaseConfig('last_usage_report', time()); updateDatabaseConfig('last_usage_report', time());
if($cache->enabled()) { if($cache->enabled()) {
@@ -233,142 +153,11 @@ 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')) {
{ $visitors = new Visitors(setting('core.visitors_counter_ttl'));
require_once SYSTEM . 'libs/visitors.php';
$visitors = new Visitors($config['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
if($config['backward_support']) {
define('INITIALIZED', true);
$SQL = $db;
$layout_header = template_header();
$layout_name = $template_path;
$news_content = '';
$tickers_content = '';
$subtopic = PAGE;
$main_content = '';
$config['access_admin_panel'] = 2;
$group_id_of_acc_logged = 0;
if($logged && $account_logged)
$group_id_of_acc_logged = $account_logged->getGroupId();
$config['site'] = &$config;
$config['server'] = &$config['lua'];
$config['site']['shop_system'] = $config['gifts_system'];
if(!isset($config['vdarkborder']))
$config['vdarkborder'] = '#505050';
if(!isset($config['darkborder']))
$config['darkborder'] = '#D4C0A1';
if(!isset($config['lightborder']))
$config['lightborder'] = '#F1E0C6';
$config['site']['download_page'] = true;
$config['site']['serverinfo_page'] = true;
$config['site']['screenshot_page'] = true;
if($config['forum'] != '')
$config['forum_link'] = (strtolower($config['forum']) === 'site' ? getLink('forum') : $config['forum']);
foreach($status as $key => $value)
$config['status']['serverStatus_' . $key] = $value;
}
if($load_it)
{
if(SITE_CLOSED && admin())
$content .= '<p class="note">Site is under maintenance (closed mode). Only privileged users can see it.</p>';
if($config['backward_support']) {
require SYSTEM . 'compat/pages.php';
require SYSTEM . 'compat/classes.php';
}
$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 = $template_path . '/pages/' . $page . '.php';
if(!@file_exists($file))
{
$file = SYSTEM . 'pages/' . $page . '.php';
if(!@file_exists($file))
{
$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;
} }
/** /**

View File

@@ -38,4 +38,3 @@ if(!isset($error) || !$error) {
$error = true; $error = true;
} }
} }
?>

View File

@@ -11,13 +11,13 @@ function query($query)
error($error_); error($error_);
$error = true; $error = true;
} }
return !$error; return !$error;
} }
// define php version id if its not already // define php version id if its not already
if(!defined('PHP_VERSION_ID')) { if(!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION); $version = array_map('intval', explode('.', PHP_VERSION));
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
} }
@@ -97,4 +97,4 @@ function win_is_writable($path) {
unlink($path); unlink($path);
return true; return true;
} }

View File

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

@@ -1,4 +1,4 @@
We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):<br/><br/><span class="console">chown -R www-data.www-data /var/www/*</span><br/><span class="console">chmod -R 660 system/cache</span> We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):<br/><br/><span class="console">chown -R www-data.www-data /var/www/*</span><br/><span class="console">chmod -R 760 system/cache</span>
<style type="text/css"> <style type="text/css">
.console { .console {

View File

@@ -13,9 +13,6 @@ 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';
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 +23,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 +67,7 @@ if($step == 'database') {
$key = str_replace('var_', '', $key); $key = str_replace('var_', '', $key);
if(in_array($key, array('account', 'password', 'email', 'player_name'))) { if(in_array($key, array('account', 'account_id', 'password', 'password_confirm', 'email', 'player_name'))) {
continue; continue;
} }
@@ -91,10 +88,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 == '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;
@@ -110,18 +103,17 @@ if($step == 'database') {
} }
} }
else if($step == 'admin') { else if($step == 'admin') {
$config_failed = true; if(!file_exists(BASE . 'config.local.php') || !isset($config['installed']) || !$config['installed']) {
if(file_exists(BASE . 'config.local.php') && isset($config['installed']) && $config['installed'] && isset($_SESSION['saved'])) {
$config_failed = false;
}
if($config_failed) {
$step = 'database'; $step = 'database';
} }
else {
$_SESSION['saved'] = true;
}
} }
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
@@ -163,6 +155,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)) {

View File

@@ -5,4 +5,3 @@ $twig->display('install.license.html.twig', array(
'license' => file_get_contents(BASE . 'LICENSE'), 'license' => file_get_contents(BASE . 'LICENSE'),
'buttons' => next_buttons() 'buttons' => next_buttons()
)); ));
?>

View File

@@ -18,4 +18,3 @@ $twig->display('install.config.html.twig', array(
'errors' => isset($errors) ? $errors : null, 'errors' => isset($errors) ? $errors : null,
'buttons' => next_buttons() 'buttons' => next_buttons()
)); ));
?>

View File

@@ -1,4 +1,7 @@
<?php <?php
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
//ini_set('display_errors', false); //ini_set('display_errors', false);
@@ -11,16 +14,12 @@ if(!isset($_SESSION['var_server_path'])) {
} }
if(!$error) { if(!$error) {
$content = "<?php"; $configToSave = [
$content .= PHP_EOL; // by default, set env to prod
$content .= '// place for your configuration directives, so you can later easily update myaac'; // user can disable when he wants
$content .= PHP_EOL; 'env' => 'prod',
$content .= '$config[\'installed\'] = true;'; ];
$content .= PHP_EOL;
// by default, set env to prod
// user can disable when he wants
$content .= '$config[\'env\'] = \'prod\'; // dev or prod';
$content .= PHP_EOL;
foreach($_SESSION as $key => $value) foreach($_SESSION as $key => $value)
{ {
if(strpos($key, 'var_') !== false) if(strpos($key, 'var_') !== false)
@@ -32,17 +31,16 @@ 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['gzip_output'] = false;
$configToSave['cache_engine'] = 'auto';
$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) {
@@ -55,38 +53,42 @@ if(!$error) {
error($database_error); error($database_error);
} }
else { else {
$twig->display('install.installer.html.twig', array( if(!$db->hasTable('accounts')) {
'url' => 'tools/5-database.php', $tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
'message' => $locale['loading_spinner'] error($tmp);
)); $error = true;
}
if(!$db->hasTable('players')) {
$tmp = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
error($tmp);
$error = true;
}
if(!$db->hasTable('guilds')) {
$tmp = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
error($tmp);
$error = true;
}
if(!$error) { if(!$error) {
if(!Validator::email($_SESSION['var_mail_admin'])) { $twig->display('install.installer.html.twig', array(
error($locale['step_config_mail_admin_error']); 'url' => 'tools/5-database.php',
$error = true; 'message' => $locale['loading_spinner']
} ));
$content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$content .= PHP_EOL;
$content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$saved = true;
if(!$error) {
$saved = file_put_contents(BASE . 'config.local.php', $content);
}
$content = '';
$saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content);
if($saved) { 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']);
warning($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>');
} }
} }
@@ -98,7 +100,7 @@ if(!$error) {
<div class="text-center m-3"> <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 ? false : true); <?php echo next_buttons(true, !$error);
?> ?>
</form> </form>
</div> </div>

View File

@@ -1,4 +1,7 @@
<?php <?php
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
ini_set('max_execution_time', 300); ini_set('max_execution_time', 300);
@@ -8,15 +11,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;
@@ -66,7 +68,6 @@ else {
$new_account->setPassword(encrypt($password)); $new_account->setPassword(encrypt($password));
$new_account->setEMail($email); $new_account->setEMail($email);
$new_account->unblock();
$new_account->save(); $new_account->save();
$new_account->setCustomField('created', time()); $new_account->setCustomField('created', time());
@@ -75,7 +76,7 @@ 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);
@@ -83,7 +84,7 @@ else {
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'))
$account_used->setCustomField('type', 5); $account_used->setCustomField('type', 6);
if(!$player_db->isLoaded()) if(!$player_db->isLoaded())
$player->setAccountId($account_used->getId()); $player->setAccountId($account_used->getId());
@@ -112,30 +113,50 @@ else {
$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX ."news` WHERE `title` LIKE 'Hello!';"); $query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX ."news` WHERE `title` LIKE 'Hello!';");
if($query->rowCount() == 0) { if($query->rowCount() == 0) {
if(query("INSERT INTO `" . TABLE_PREFIX ."news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '1', UNIX_TIMESTAMP(), '2', 'Hello!', 'MyAAC is just READY to use!', " . $player_id . ", 'https://my-aac.org', '0'); if(query("INSERT INTO `" . TABLE_PREFIX ."news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hide`) VALUES (NULL, '1', UNIX_TIMESTAMP(), '2', 'Hello!', 'MyAAC is just READY to use!', " . $player_id . ", 'https://my-aac.org', '0');
INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '2', UNIX_TIMESTAMP(), '4', 'Hello tickets!', 'https://my-aac.org', " . $player_id . ", '', '0');")) { INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hide`) VALUES (NULL, '2', UNIX_TIMESTAMP(), '4', 'Hello tickets!', 'https://my-aac.org', " . $player_id . ", '', '0');")) {
success($locale['step_database_created_news']); success($locale['step_database_created_news']);
} }
} }
$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'])) {
$report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); if (!array_key_exists('CI', getenv())) {
if (function_exists('curl_version')) $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL);
{ if (function_exists('curl_version'))
$curl = curl_init(); {
curl_setopt($curl, CURLOPT_URL, $report_url); $curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_URL, $report_url);
curl_exec($curl); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_close($curl); curl_exec($curl);
} curl_close($curl);
else if (ini_get('allow_url_fopen') ) { }
file_get_contents($report_url); else if (ini_get('allow_url_fopen') ) {
file_get_contents($report_url);
}
} }
$_SESSION['installed'] = true; $_SESSION['installed'] = true;
} }

View File

@@ -4,14 +4,14 @@
<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"> <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.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="template/style.css" /> <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/ext/jquery/jquery.min.js"></script>
</head> </head>
<body> <body>
<div id="body" class="container"> <div id="body" class="container">
<header id="header" class="pt-5 pb-4 pb-sm-5"> <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>
</header> </header>
@@ -28,10 +28,10 @@
if ($step == $value) { if ($step == $value) {
$progress = ($i == 6) ? 100 : $i * 16; $progress = ($i == 6) ? 100 : $i * 16;
} }
echo '<li' . ($step == $value ? ' class="list-group-item active"' : ' class="list-group-item"') . '>' . ++$i . '. ' . $locale['step_' . $value] . '</li>'; echo '<li class="list-group-item' . ($step == $value ? ' active' : '') . '">' . ++$i . '. ' . $locale['step_' . $value] . '</li>';
} }
?> ?>
</ul> </ul>
</div> </div>
@@ -71,4 +71,4 @@
<p style="text-align: center;"><?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?></p> <p style="text-align: center;"><?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?></p>
</footer> </footer>
</body> </body>
</html> </html>

View File

@@ -11,8 +11,10 @@ $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) {
@@ -23,24 +25,6 @@ if(!$error) {
} }
} }
if(!$db->hasTable('accounts')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
return;
}
if(!$db->hasTable('players')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
return;
}
if(!$db->hasTable('guilds')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
return;
}
if($db->hasTable(TABLE_PREFIX . 'account_actions')) { if($db->hasTable(TABLE_PREFIX . 'account_actions')) {
$locale['step_database_error_table_exist'] = str_replace('$TABLE$', TABLE_PREFIX . 'account_actions', $locale['step_database_error_table_exist']); $locale['step_database_error_table_exist'] = str_replace('$TABLE$', TABLE_PREFIX . 'account_actions', $locale['step_database_error_table_exist']);
warning($locale['step_database_error_table_exist']); warning($locale['step_database_error_table_exist']);
@@ -73,13 +57,8 @@ else {
success($locale['step_database_adding_field'] . ' accounts.key...'); success($locale['step_database_adding_field'] . ' accounts.key...');
} }
if(!$db->hasColumn('accounts', 'blocked')) {
if(query("ALTER TABLE `accounts` ADD `blocked` TINYINT(1) NOT NULL DEFAULT FALSE COMMENT 'internal usage' AFTER `key`;"))
success($locale['step_database_adding_field'] . ' accounts.blocked...');
}
if(!$db->hasColumn('accounts', 'created')) { if(!$db->hasColumn('accounts', 'created')) {
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'blocked') . "`;")) if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'key') . "`;"))
success($locale['step_database_adding_field'] . ' accounts.created...'); success($locale['step_database_adding_field'] . ' accounts.created...');
} }
@@ -201,17 +180,17 @@ if(!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion
} }
if($db->hasColumn('players', 'hide_char')) { if($db->hasColumn('players', 'hide_char')) {
if(!$db->hasColumn('players', 'hidden')) { if(!$db->hasColumn('players', 'hide')) {
if(query("ALTER TABLE `players` CHANGE `hide_char` `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) { if(query("ALTER TABLE `players` CHANGE `hide_char` `hide` TINYINT(1) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']); $tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'players.hidden', $tmp); $tmp = str_replace('$FIELD_NEW$', 'players.hide', $tmp);
success($tmp); success($tmp);
} }
} }
} }
else if(!$db->hasColumn('players', 'hidden')) { else if(!$db->hasColumn('players', 'hide')) {
if(query("ALTER TABLE `players` ADD `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) if(query("ALTER TABLE `players` ADD `hide` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.hidden...'); success($locale['step_database_adding_field'] . ' players.hide...');
} }
if(!$db->hasColumn('players', 'comment')) { if(!$db->hasColumn('players', 'comment')) {

View File

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

105
login.php
View File

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

View File

@@ -7,23 +7,38 @@ server {
# increase max file upload # increase max file upload
client_max_body_size 10M; client_max_body_size 10M;
# this is very important, be sure its in your nginx conf - it prevents access to logs etc.
location ~ /system {
deny all;
return 404;
}
location /vendor {
deny all;
return 404;
}
# block .htaccess, CHANGELOG.md, composer.json etc.
# this is to prevent finding software versions
location ~\.(ht|md|json|dist)$ {
deny all;
return 404;
}
# block git files and folders
location ~ /\.git {
return 404;
deny all;
}
location / { location / {
try_files $uri $uri/ /index.php; try_files $uri $uri/ /index.php?$query_string;;
} }
location ~ \.php$ { location ~ \.php$ {
include snippets/fastcgi-php.conf; include snippets/fastcgi-php.conf;
fastcgi_read_timeout 240; fastcgi_read_timeout 240;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
# for ubuntu 22.04+ it will be php8.1-sock # for ubuntu 22.04+ it will be php8.1-fpm.sock
}
location ~ /\.ht {
deny all;
}
location /system {
deny all;
return 404;
} }
} }

16
npm-post-install.js Normal file
View File

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

2142
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

17
package.json Normal file
View File

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

13
phpstan-bootstrap.php Normal file
View File

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

38
phpstan.neon Normal file
View File

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

View File

@@ -1,11 +1,3 @@
<IfModule mod_autoindex.c> <IfModule mod_autoindex.c>
Options -Indexes Options -Indexes
</IfModule> </IfModule>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>

View File

@@ -1,3 +1,3 @@
To play on {{ config.lua.serverName }} you need an account. To play on {{ config.lua.serverName }} you need an account.
All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if config.recaptcha_enabled %}, confirm reCAPTCHA{% endif %}{% if config.account_country %}, country{% endif %} and your email address. All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if setting('core.account_country') %}, country{% endif %} and your email address.
Also you have to agree to the terms presented below. If you have done so, your account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %} will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.<br/><br/> Also you have to agree to the terms presented below. If you have done so, your account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %} will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.<br/><br/>

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