Compare commits

...

555 Commits

Author SHA1 Message Date
slawkens
68118fb7c2 Update phpstan.neon 2024-07-23 08:47:22 +02:00
slawkens
5a69b9a802 Update composer.lock 2024-07-23 08:45:55 +02:00
slawkens
45e63b13c3 Update version to 1.0-RC 2024-07-23 08:35:08 +02:00
slawkens
758a8b3330 Prepare changelog for 1.0-RC
Release Candidate.
2024-07-23 08:30:53 +02:00
slawkens
1843728930 Rename to playerSample 2024-07-23 08:07:59 +02:00
slawkens
cff62ccba4 Another try 2024-07-12 20:54:12 +02:00
slawkens
28f98db9de Fix PHPStan errors in monsters.php 2024-07-12 20:48:27 +02:00
slawkens
da14e125e9 Fix highscores skill links (Thanks @vyroq) 2024-07-12 20:01:12 +02:00
slawkens
cd49dfc799 Set Admin Account verified by default 2024-07-10 18:12:05 +02:00
slawkens
ef79b99b8a Fix monster not found exception 2024-07-10 09:54:54 +02:00
slawkens
9a27403e7d Fixes to account_mail_verify 2024-07-09 23:35:39 +02:00
slawkens
5f63c3b227 Invalidate cached setting 2024-07-09 23:33:00 +02:00
slawkens
203e411b62 Allow account_create_character_create even if account_mail_verify is activated 2024-07-09 23:06:12 +02:00
slawkens
fcb13f3c0f Fixes to account verify - do not allow login without verified email (Thanks @anyeor) 2024-07-09 23:05:36 +02:00
slawkens
d94828772c Rework 5th step of installation, to fix some pointless message about Cache 2024-07-09 22:04:47 +02:00
slawkens
10a739773c Detect tools/ext exists on install to prevent broken installs 2024-07-09 21:29:42 +02:00
slawkens
83b3dc803a Fix 5th step of installer 2024-07-08 19:50:05 +02:00
slawkens
33a47137c9 Fix hooks priority default 2024-06-29 15:09:44 +02:00
slawkens
dc17b701da feat: Hooks priority 2024-06-29 14:05:06 +02:00
slawkens
d30811404b Update players.php 2024-06-28 19:03:06 +02:00
slawkens
a631760dbf Order fraggers by time 2024-06-23 16:10:50 +02:00
slawkens
bc3dcab462 deny all is enough 2024-06-23 09:55:15 +02:00
slawkens
a8d255c04b feat: Plugins pages: subSubFolders 2024-06-14 08:07:52 +02:00
slawkens
813786c768 Update cleanup_players.php 2024-06-14 06:42:45 +02:00
slawkens
0db0ec1aa4 Fix useGuildNick displaying 2024-06-14 06:42:42 +02:00
slawkens
bdc0c43d3f Refactor account routes into sub folders 2024-06-13 22:23:43 +02:00
slawkens
c7a6a539a9 Another approach to fix duplicates - priorities
Priority description: (lower number - higher priority)
1-99 Highest priority - overrides everything, even pages from database, use with caption
100 - default for pages in database
101-999 - recommended range for plugins
1000 - default value for plugins if no other specified
1001 - 9999 - no usage currently
10000 - default myaac routes
2024-06-13 21:35:47 +02:00
slawkens
c1d4b4f80c Make autoload of pages, commands and themes configurable
Not everyone might want them to autoload
2024-06-13 14:36:18 +02:00
slawkens
47a19e85dd Reposition code for setting ranks (addition to previous commit) 2024-06-13 13:07:03 +02:00
slawkens
d9c1b2507c Create guild_rank entries, in case MySQL trigger not loaded 2024-06-13 12:51:29 +02:00
slawkens
4c0739d3e9 Fixed fastRoute duplicate errors 2024-06-13 11:29:06 +02:00
slawkens
afe70a03c5 Fix email_change status 2024-06-11 13:32:22 +02:00
slawkens
3fadf87a7a Fix title on login page 2024-06-11 13:14:15 +02:00
slawkens
c24576165c login.php early exit + fix title 2024-06-11 12:55:02 +02:00
slawkens
1e5c9dcd9b Nothing important, just a space for better look! 2024-06-10 19:43:08 +02:00
slawkens
a04d186c22 Fix highscores frags for TFS 1.x and canary 2024-06-10 18:53:17 +02:00
slawkens
42f99c3edc Fraggers in characters page for TFS 1.x and canary 2024-06-08 23:27:19 +02:00
slawkens
4f4965369d spaces -> tabs 2024-06-05 21:53:58 +02:00
slawkens
57b47ab798 Fix if <flags> are not present in monster.xml 2024-06-05 21:51:50 +02:00
slawkens
9ea2a5067f Order towns by id 2024-06-05 15:10:55 +02:00
slawkens
ec96985872 Revert some breaking change 2024-06-01 18:44:06 +02:00
slawkens
9f2a51b351 Spaces and remove useless function 2024-06-01 15:53:34 +02:00
slawkens
a1d7c94166 Closing tag 2024-06-01 15:51:28 +02:00
slawkens
0c3e3e16dd Set default group_id 2024-06-01 15:51:21 +02:00
slawkens
45dda5e834 Add HOOK_ACCOUNT_CREATE_CHARACTER_* hooks 2024-05-31 22:59:52 +02:00
slawkens
32ae4dde20 Fix closing table elements 2024-05-31 22:57:44 +02:00
slawkens
d3f03fa735 Better place for INSTALL_FINISH hook 2024-05-31 19:21:37 +02:00
slawkens
44eff8092c Fix settings title 2024-05-31 18:30:01 +02:00
slawkens
8ef3d06f1e Fix duplicated routes 2024-05-31 17:22:39 +02:00
slawkens
60bd64a639 Update router.php 2024-05-30 20:40:15 +02:00
slawkens
a1bcb217ec Fixes regarding not working google recaptcha (+few previous commits) 2024-05-30 17:36:07 +02:00
slawkens
933b681a9f Fixed if account_country is disabled 2024-05-30 14:25:31 +02:00
slawkens
e9aea17e1b Close form in proper place 2024-05-30 14:21:52 +02:00
slawkens
060400b074 Revert "Use tables headline for account.create.html.twig"
This reverts commit 64387e085b.
2024-05-30 13:48:59 +02:00
slawkens
6be4a42c5a Revert "Fix form id"
This reverts commit d225c2da26.
2024-05-30 13:48:53 +02:00
slawkens
1e8198635e Enable dev mode on install, prevent noobs asking white page questions 2024-05-30 12:00:26 +02:00
slawkens
be78a0fc45 Do adjustments only if table exist 2024-05-30 11:32:03 +02:00
slawkens
08ac8ebade Add HOOK_INSTALL_FINISH 2024-05-30 11:31:41 +02:00
slawkens
66ecc487a1 One more early exit 2024-05-30 11:18:06 +02:00
slawkens
9e23ec6745 Early exit in 7-finish install 2024-05-30 11:14:16 +02:00
slawkens
968899ef77 Pass $playerSample as parameter to hook 2024-05-30 10:09:31 +02:00
slawkens
3844ad0d71 Fix warnings in basic.js 2024-05-30 09:49:02 +02:00
slawkens
c93bf5a984 create_character_name_min_length => 3 2024-05-30 09:02:19 +02:00
slawkens
50336a810b Fix blessings longer than 3 characters 2024-05-30 08:23:31 +02:00
slawkens
48f6ca0eba Tabs + spaces 2024-05-30 08:20:59 +02:00
slawkens
30107222d4 Add getLongLong function to OTS_Buffer 2024-05-30 08:20:33 +02:00
slawkens
f92b275f70 Update version to beta.2 2024-05-23 23:44:29 +02:00
slawkens
504242fb84 Do not create news about myaac, if any news already exist (on installation) 2024-05-23 23:40:27 +02:00
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
582 changed files with 21278 additions and 14194 deletions

View File

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

5
.gitattributes vendored
View File

@@ -3,8 +3,11 @@
.gitignore export-ignore
.github export-ignore
.editorconfig export-ignore
.travis.yml export-ignore
_config.yml export-ignore
release.sh export-ignore
# cypress
cypress export-ignore
cypress.config.js export-ignore
*.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
on:
pull_request:
branches: [master, develop]
branches: [develop]
push:
branches: [master]
branches: [develop]
jobs:
phplint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: michaelw90/PHP-Lint@master
- uses: actions/checkout@v3
- uses: overtrue/phplint@8.2
with:
path: .
options: --exclude=*.log

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

View File

@@ -6,12 +6,14 @@
Options -MultiViews
</IfModule>
<FilesMatch "^(CHANGELOG\.md|README\.md|composer\.json|composer\.lock|package\.json|package-lock\.json|cypress\.env\.json)$">
Require all denied
</FilesMatch>
<IfModule mod_rewrite.c>
RewriteEngine On
# you can put here your myaac root folder
# path relative to web root
#RewriteBase /myaac/
#RewriteBase /myaac/
RewriteCond %{REQUEST_FILENAME} !-f
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,97 @@
# Changelog
## [0.9.0 - x.x.2020]
## [1.0-RC -23.07.2024]
Changes since 1.0-beta:
### Added
* Feat: Hooks priority (https://github.com/slawkens/myaac/commit/dc17b701da053e04bfa64e21be9247a4f07505e1)
* Make autoload of pages, commands and themes configurable (https://github.com/slawkens/myaac/commit/c1d4b4f80cd6bb85507ee9471e47013955a26a91)
* Fraggers in characters page for TFS 1.x and canary (https://github.com/slawkens/myaac/commit/42f99c3edc8de39cccc5632cb42e88b24579c5a6)
* New hooks: HOOK_INSTALL_FINISH, HOOK_ACCOUNT_CREATE_CHARACTER_* (https://github.com/slawkens/myaac/commit/08ac8ebade106521a5c7396faa5ce7006e629f7c, https://github.com/slawkens/myaac/commit/45dda5e834ff2059faea6ef9be2efa76f1723cbd)
### Changed
* Allow account_create_character_create even if account_mail_verify is activated (https://github.com/slawkens/myaac/commit/203e411b626fe62401a4b74a48420769e512aa39)
* Create guild_rank entries, in case MySQL trigger not loaded (https://github.com/slawkens/myaac/commit/d9c1b2507c81f306970642b35e4bf5f7cc04a6f2, https://github.com/slawkens/myaac/commit/47a19e85dd84e9f3b39a1b29cfc2c04b004832b9)
* Set Admin Account verified by default (https://github.com/slawkens/myaac/commit/cd49dfc79942f3301ce9c0b8d899b9f39bda9a41)
* Refactor account routes into sub folders (https://github.com/slawkens/myaac/commit/bdc0c43d3fd3a51030c3e916bdb9f008468f5ecd)
* Order towns by id (https://github.com/slawkens/myaac/commit/9ea2a5067fc4b75de395f381577b18914132ad84)
* Do not create news about myaac, if any news already exist (on installation (https://github.com/slawkens/myaac/commit/504242fb846b73b56b87bc1e39d070687ad7f5b4)
### Fixed
### Fixed
* Not working google recaptcha plugin (https://github.com/slawkens/myaac/commit/a1bcb217ecf4e21fd58da4ba491da1852029898a)
* Not working account create if account_country is disabled (https://github.com/slawkens/myaac/commit/933b681a9fcdbb6283e0469b3806d2ded492d232)
* Account verify - do not allow login without verified email (Thanks @anyeor, https://github.com/slawkens/myaac/commit/fcb13f3c0fb8ceafda0bd614a229a26a269432bd)
* Detect tools/ext exists on install to prevent broken installs (https://github.com/slawkens/myaac/commit/10a739773c4f2911876bc802a0ee0537c3e00a92)
* Cache reloading each time page refreshes (https://github.com/slawkens/myaac/commit/ec96985872057340112f65073efc0c4bf86dddb0)
* Highscores frags for TFS 1.x and canary (https://github.com/slawkens/myaac/commit/a04d186c22912915f0a7873dfe677ef3b5a23c79)
* Monsters page: monster not found exception (https://github.com/slawkens/myaac/commit/ef79b99b8acc179f14b8475547347d9daca27512)
* Fixed bug if \<flags\> are not present in monster.xml (https://github.com/slawkens/myaac/commit/57b47ab7983f625c7c0ef4f5303a4d07ef172786)
* fastRoute duplicate errors (https://github.com/slawkens/myaac/commit/4c0739d3e93812dff0c33849ea3f38e4e49113ac)
* useGuildNick displaying (https://github.com/slawkens/myaac/commit/0db0ec1aa47e044c26bc403ff5078a2115d086f8)
## [1.0-beta - 18.05.2024]
Minimum PHP version for this release is 8.1.
### Added
* reworked Admin Panel (@Leesneaks, @gpedro, @slawkens)
* updated to Bootstrap v4
* new Menu
* new Dashboard: statistics, server status
* new Admin Bar showed on top when admin logged in
* new page: Server Data, to reload server data
* Towns, NPCs & Items are stored in permanent cache
* new pages: mass account & teleport tools
* changelogs editor
* revised Accounts & Players editors
* option to add/modify admin menus with plugins
* option to enable/disable plugins
* better, updated TinyMCE editor (v6.x)
* with option to upload images
* list of open source libraries used in project page
* auto-loading of themes, commands & pages from plugins/ folder. You need just to place them in correct folder and they will be loaded automatically - this allows better customization, without interfering with core AAC folders. This will allow in the future automatic updates for plugins as well the AAC as whole.
* config.php moved to Admin Panel -> Settings page
* new console script: aac - using symfony/console
* usage: `php aac` (will list all commands by default)
* example: `php aac cache:clear`
* example: `php aac plugin:install theme-example.zip`
* replace POT Query Builder to Eloquent ORM. Not 100% yet - in some places there is still old $db approach used (@gpedro) (https://github.com/slawkens/myaac/pull/230)
* brand new charming installation page (by @fernandomatos)
* using Bootstrap
* new pages router: nikic/fast-route, allowing for better customisation
* Plugin cronjobs: central control of the cronjobs
* Guild Wars support (available as plugin)
* support for login and create account only by email (configurable)
* with no need for account name
* Google ReCAPTCHA v3 support (available as plugin)
* 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
* 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
* 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>
caio <caio.zucoli@gmail.com>
slawkens <slawkens@gmail.com>
tobi132 <52947952+tobi132@users.noreply.github.com>
tobi132 <tobi132@gmx.net>
vankk <nwtr.otland@hotmail.com>
whiteblXK <krzys16001@gmail.com>
xitobuh <jonas.hockert92@gmail.com>
Danilo Pucci <dnlps@hotmail.com>
gpedro <gpedro831@gmail.com>
Matheus Collier <matheuscollier@gmail.com>
SRNT-GG <95472530+SRNT-GG@users.noreply.github.com>

View File

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

View File

@@ -1,24 +1,29 @@
# [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.
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
- PHP 5.6 or later
- MySQL database
- PDO PHP Extension
- XML PHP Extension
- ZIP PHP Extension
- (optional) mod_rewrite to use friendly_urls
- PHP Extensions: pdo, xml, json
- (optional) apache2 mod_rewrite (to use friendly_urls)
- (optional) zip PHP Extension (to install plugins)
- (optional) gd PHP Extension (for generating signature images)
### Installation
@@ -36,13 +41,14 @@ Official website: https://my-aac.org
chmod 660 images/guilds
chmod 660 images/houses
chmod 660 images/gallery
chmod -R 770 system/cache
chmod -R 760 system/cache
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.
### 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.
### Branches
@@ -71,7 +77,13 @@ Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our w
### 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

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
// few things we'll need
require '../common.php';
define('ADMIN_PANEL', true);
define('MYAAC_ADMIN', true);
if(file_exists(BASE . 'config.local.php')) {
require_once BASE . 'config.local.php';
}
const ADMIN_PANEL = true;
const MYAAC_ADMIN = true;
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 = '';
// validate page
$page = isset($_GET['p']) ? $_GET['p'] : '';
if(empty($page) || preg_match("/[^a-zA-Z0-9_\-]/", $page))
$page = $_GET['p'] ?? '';
if(empty($page) || preg_match("/[^a-zA-Z0-9_\-\/.]/", $page))
$page = 'dashboard';
$page = strtolower($page);
@@ -28,44 +25,43 @@ define('PAGE', $page);
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
if(config('env') === 'dev') {
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
}
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
require __DIR__ . '/includes/debugbar.php';
require SYSTEM . 'status.php';
require SYSTEM . 'login.php';
require SYSTEM . 'migrate.php';
require ADMIN . 'includes/functions.php';
require __DIR__ . '/includes/functions.php';
$twig->addGlobal('config', $config);
$twig->addGlobal('status', $status);
if (ACTION == 'logout') {
require SYSTEM . 'logout.php';
}
// if we're not logged in - show login box
if(!$logged || !admin()) {
$page = 'login';
}
// include our page
$file = SYSTEM . 'pages/admin/' . $page . '.php';
$file = __DIR__ . '/pages/' . $page . '.php';
if(!@file_exists($file)) {
$page = '404';
$file = SYSTEM . 'pages/404.php';
if (str_contains($page, 'plugins/')) {
$file = BASE . $page;
}
else {
$page = '404';
$file = SYSTEM . 'pages/404.php';
}
}
ob_start();
include($file);
if($hooks->trigger(HOOK_ADMIN_BEFORE_PAGE)) {
require $file;
}
$content .= ob_get_contents();
ob_end_clean();
// 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
* @link https://my-aac.org
*/
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Account editor';
$admin_base = BASE_URL . 'admin/?p=accounts';
csrfProtect();
$admin_base = ADMIN_URL . '?p=accounts';
$use_datatable = true;
if ($config['account_country'])
if (setting('core.account_country'))
require SYSTEM . 'countries.conf.php';
$nameOrNumberColumn = 'name';
if (USE_ACCOUNT_NUMBER) {
$nameOrNumberColumn = 'number';
}
$hasSecretColumn = $db->hasColumn('accounts', 'secret');
$hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$hasTypeColumn = $db->hasColumn('accounts', 'type');
$hasGroupColumn = $db->hasColumn('accounts', 'group_id');
if ($config['account_country']) {
if (setting('core.account_country')) {
$countries = array();
foreach (array('pl', 'se', 'br', 'us', 'gb') as $c)
$countries[$c] = $config['countries'][$c];
@@ -31,8 +42,8 @@ if ($config['account_country']) {
foreach ($config['countries'] as $code => $c)
$countries[$code] = $c;
}
$web_acc = array("None", "Admin", "Super Admin", "(Admin + Super Admin)");
$acc_type = array("None", "Normal", "Tutor", "Senior Tutor", "Gamemaster", "God");
$web_acc = ACCOUNT_WEB_FLAGS;
$acc_type = setting('core.account_types');
?>
<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ >
@@ -48,16 +59,16 @@ else if (isset($_REQUEST['search'])) {
if (strlen($search_account) < 3 && !Validator::number($search_account)) {
echo_error('Player name is too short.');
} else {
$query = $db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $db->quote($search_account));
$query = $db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $db->quote($search_account));
if ($query->rowCount() == 1) {
$query = $query->fetch();
$id = (int)$query['id'];
} else {
$query = $db->query('SELECT `id`, `name` FROM `accounts` WHERE `name` LIKE ' . $db->quote('%' . $search_account . '%'));
$query = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` LIKE ' . $db->quote('%' . $search_account . '%'));
if ($query->rowCount() > 0 && $query->rowCount() <= 10) {
$str_construct = 'Do you mean?<ul class="mb-0">';
foreach ($query as $row)
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row['name'] . '</a></li>';
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row[$nameOrNumberColumn] . '</a></li>';
$str_construct .= '</ul>';
echo_error($str_construct);
} else if ($query->rowCount() > 10)
@@ -70,12 +81,11 @@ else if (isset($_REQUEST['search'])) {
?>
<div class="row">
<?php
$groups = new OTS_Groups_List();
if ($id > 0) {
$account = new OTS_Account();
$account->load($id);
if (isset($account, $_POST['save']) && $account->isLoaded()) {
if (isset($_POST['save']) && $account->isLoaded()) {
$error = false;
$_error = '';
@@ -146,7 +156,7 @@ else if (isset($_REQUEST['search'])) {
$web_lastlogin = strtotime($_POST['web_lastlogin']);
verify_number($web_lastlogin, 'Web Last login', 11);
if (!$error) {
if (!$error && $hooks->trigger(HOOK_ADMIN_ACCOUNTS_SAVE_POST, ['account_id' => $account->getId(), 'account_email' => $account->getEMail()])) {
if (USE_ACCOUNT_NAME) {
$account->setName($name);
}
@@ -186,8 +196,7 @@ else if (isset($_REQUEST['search'])) {
$account->setCustomField('web_lastlogin', $web_lastlogin);
if (isset($password)) {
$config_salt_enabled = $db->hasColumn('accounts', 'salt');
if ($config_salt_enabled) {
if (USE_ACCOUNT_SALT) {
$salt = generateRandomString(10, false, true, true);
$password = $salt . $password;
$account->setCustomField('salt', $salt);
@@ -196,7 +205,7 @@ else if (isset($_REQUEST['search'])) {
$password = encrypt($password);
$account->setPassword($password);
if ($config_salt_enabled)
if (USE_ACCOUNT_SALT)
$account->setCustomField('salt', $salt);
}
@@ -205,7 +214,7 @@ else if (isset($_REQUEST['search'])) {
}
}
} else if ($id == 0) {
$accounts_db = $db->query('SELECT `id`, `name`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC');
$accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC');
?>
<div class="col-12 col-sm-12 col-lg-10">
<div class="card card-info card-outline">
@@ -217,7 +226,7 @@ else if (isset($_REQUEST['search'])) {
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th><?= ($nameOrNumberColumn == 'number' ? 'Number' : 'Name'); ?></th>
<?php if($hasTypeColumn || $hasGroupColumn): ?>
<th>Position</th>
<?php endif; ?>
@@ -228,7 +237,7 @@ else if (isset($_REQUEST['search'])) {
<?php foreach ($accounts_db as $account_lst): ?>
<tr>
<th><?php echo $account_lst['id']; ?></th>
<td><?php echo $account_lst['name']; ?></a></td>
<td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td>
<?php if($hasTypeColumn || $hasGroupColumn): ?>
<td>
<?php if ($hasTypeColumn) {
@@ -260,6 +269,9 @@ else if (isset($_REQUEST['search'])) {
<li class="nav-item">
<a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a>
</li>
<li class="nav-item">
<a class="nav-link" id="accounts-logs-tab" data-toggle="pill" href="#accounts-logs">Logs</a>
</li>
<li class="nav-item">
<a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a>
</li>
@@ -269,7 +281,7 @@ else if (isset($_REQUEST['search'])) {
</li>
<?php endif;
if ($db->hasTable('store_history')) : ?>
if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) : ?>
<li class="nav-item">
<a class="nav-link" id="accounts-store-tab" data-toggle="pill" href="#accounts-store">Store History</a>
</li>
@@ -279,13 +291,19 @@ else if (isset($_REQUEST['search'])) {
<div class="card-body">
<div class="tab-content" id="accounts-tabContent">
<div class="tab-pane fade active show" id="accounts-acc">
<form action="<?php echo $admin_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post">
<form action="<?php echo $admin_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post">
<?php csrf(); ?>
<div class="form-group row">
<?php if (USE_ACCOUNT_NAME): ?>
<div class="col-12 col-sm-12 col-lg-4">
<label for="name">Account Name:</label>
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getName(); ?>"/>
</div>
<?php elseif (USE_ACCOUNT_NUMBER): ?>
<div class="col-12 col-sm-12 col-lg-4">
<label for="name">Account Number:</label>
<input type="text" class="form-control" id="name" name="name" autocomplete="off" value="<?php echo $account->getNumber(); ?>"/>
</div>
<?php endif; ?>
<div class="col-12 col-sm-12 col-lg-5">
<div class="form-check">
@@ -313,8 +331,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6">
<label for="group">Account Type:</label>
<select name="group" id="group" class="form-control">
<?php foreach ($acc_type as $id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($acc_group == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php foreach ($acc_type as $_id => $a_type): ?>
<option value="<?php echo($_id); ?>" <?php echo($acc_group == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?>
</select>
</div>
@@ -324,8 +342,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6">
<label for="group">Account Type:</label>
<select name="group" id="group" class="form-control">
<?php foreach ($groups->getGroups() as $id => $group): ?>
<option value="<?php echo $id; ?>" <?php echo($acc_group == $id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php foreach ($groups->getGroups() as $_id => $group): ?>
<option value="<?php echo $_id; ?>" <?php echo($acc_group == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php endforeach; ?>
</select>
</div>
@@ -333,8 +351,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6">
<label for="web_flags">Website Access:</label>
<select name="web_flags" id="web_flags" class="form-control">
<?php foreach ($web_acc as $id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($account->getWebFlags() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php foreach ($web_acc as $_id => $a_type): ?>
<option value="<?php echo($_id); ?>" <?php echo($account->getWebFlags() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?>
</select>
</div>
@@ -353,7 +371,7 @@ else if (isset($_REQUEST['search'])) {
</div>
<div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6">
<label for="email">Email:</label><?php echo (config('mail_enabled') ? ' (<a href="' . ADMIN_URL . '?p=mailer&mail_to=' . $account->getEMail() . '">Send Mail</a>)' : ''); ?>
<label for="email">Email:</label><?php echo (setting('core.mail_enabled') ? ' (<a href="' . ADMIN_URL . '?p=mailer&mail_to=' . $account->getEMail() . '">Send Mail</a>)' : ''); ?>
<input type="text" class="form-control" id="email" name="email" autocomplete="off" value="<?php echo $account->getEMail(); ?>"/>
</div>
<?php if ($hasCoinsColumn): ?>
@@ -386,14 +404,16 @@ else if (isset($_REQUEST['search'])) {
autocomplete="off" maxlength="20"
value="<?php echo $account->getLocation(); ?>"/>
</div>
<?php if(setting('core.account_country')): ?>
<div class="col-12 col-sm-12 col-lg-4">
<label for="rl_country">Country:</label>
<select name="rl_country" id="rl_country" class="form-control">
<?php foreach ($countries as $id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($account->getCountry() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php foreach ($countries as $_id => $a_type): ?>
<option value="<?php echo($_id); ?>" <?php echo($account->getCountry() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
</div>
<div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6">
@@ -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>
</form>
</div>
<div class="tab-pane fade" id="accounts-logs">
<div class="row">
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Action</th>
<th>IP</th>
</tr>
</thead>
<tbody>
<?php
$accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
foreach ($accountActions as $i => $log):
$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6));
?>
<tr>
<td><?php echo $i + 1; ?></td>
<td><?= date("M d Y, H:i:s", $log->date); ?></td>
<td><?= $log->action; ?></td>
<td><?= $log->ip; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="tab-pane fade" id="accounts-chars">
<div class="row">
<?php
if (isset($account) && $account->isLoaded()) {
$account_players = $account->getPlayersList();
$account_players->orderBy('id');
$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get();
if (isset($account_players)) { ?>
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
@@ -430,25 +477,13 @@ else if (isset($_REQUEST['search'])) {
</tr>
</thead>
<tbody>
<?php $i= 0;
foreach ($account_players as $i => $player):
$i++;
$player_vocation = $player->getVocation();
$player_promotion = $player->getPromotion();
if (isset($player_promotion)) {
if ((int)$player_promotion > 0)
$player_vocation += ($player_promotion * $config['vocations_amount']);
}
if (isset($config['vocations'][$player_vocation])) {
$vocation_name = $config['vocations'][$player_vocation];
} ?>
<?php foreach ($account_players as $i => $player): ?>
<tr>
<th><?php echo $i; ?></th>
<td><?php echo $player->getName(); ?></td>
<td><?php echo $player->getLevel(); ?></td>
<td><?php echo $vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getId() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
<th><?php echo $i + 1; ?></th>
<td><?php echo $player->name; ?></td>
<td><?php echo $player->level; ?></td>
<td><?php echo $player->vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
</tr>
<?php endforeach ?>
</tbody>
@@ -515,7 +550,7 @@ else if (isset($_REQUEST['search'])) {
} ?>
</div>
<?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">
<?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">
@@ -552,18 +587,20 @@ else if (isset($_REQUEST['search'])) {
<div class="row">
<div class="col-6 col-lg-12">
<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">
<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>
</div>
</form>
</div>
<div class="col-6 col-lg-12">
<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">
<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>
</div>
</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!');
$title = 'Dashboard';
if (isset($_GET['clear_cache'])) {
csrfProtect();
if (isset($_POST['clear_cache'])) {
if (clearCache()) {
success('Cache cleared.');
} 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);
$_status = (isset($_POST['status']) && $_POST['status'] == 'true');
$_status = ($_status ? '0' : '1');
@@ -47,20 +49,15 @@ $tmp = '';
if (fetchDatabaseConfig('site_closed_message', $tmp))
$closed_message = $tmp;
echo '<div class="row">';
$twig->display('admin.dashboard.html.twig', array());
echo '</div>';
$configAdminPanelModules = config('admin_panel_modules');
if (isset($configAdminPanelModules)) {
$settingAdminPanelModules = setting('core.admin_panel_modules');
if (count($settingAdminPanelModules) > 0) {
echo '<div class="row">';
$configAdminPanelModules = explode(',', $configAdminPanelModules);
$twig_loader->prependPath(__DIR__ . '/modules/templates');
foreach ($configAdminPanelModules as $box) {
foreach ($settingAdminPanelModules as $box) {
$file = __DIR__ . '/modules/' . $box . '.php';
if (file_exists($file)) {
include($file);
}
}
echo '</div>';
}
}

View File

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

View File

@@ -10,17 +10,19 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mailer';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) {
echo 'Access denied.';
return;
}
if (!config('mail_enabled')) {
echo 'Mail support disabled.';
if (!setting('core.mail_enabled')) {
echo 'Mail support disabled in config.';
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_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;
$add = '';
if (config('account_mail_verify')) {
if (setting('core.account_mail_verify')) {
note('Note: Sending only to users with verified E-Mail.');
$add = ' AND `email_verified` = 1';
}

View File

@@ -9,10 +9,15 @@
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Account Actions';
csrfProtect();
$hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$freePremium = $config['lua']['freePremium'];
@@ -22,23 +27,22 @@ function admin_give_points($points)
global $db, $hasPointsColumn;
if (!$hasPointsColumn) {
error('Points not supported.');
displayMessage('Points not supported.');
return;
}
$statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points');
if (!$statement) {
error('Failed to prepare query statement.');
displayMessage('Failed to prepare query statement.');
return;
}
if (!$statement->execute([
'points' => $points
])) {
error('Failed to add points.');
if (!Account::query()->increment('premium_points', $points)) {
displayMessage('Failed to add points.');
return;
}
success($points . ' points added to all accounts.');
displayMessage($points . ' points added to all accounts.', true);
}
function admin_give_coins($coins)
@@ -46,24 +50,16 @@ function admin_give_coins($coins)
global $db, $hasCoinsColumn;
if (!$hasCoinsColumn) {
error('Coins not supported.');
displayMessage('Coins not supported.');
return;
}
$statement = $db->prepare('UPDATE `accounts` SET `coins` = `coins` + :coins');
if (!$statement) {
error('Failed to prepare query statement.');
if (!Account::query()->increment('coins', $coins)) {
displayMessage('Failed to add coins.');
return;
}
if (!$statement->execute([
'coins' => $coins
])) {
error('Failed to add coins.');
return;
}
success($coins . ' coins added to all accounts.');
displayMessage($coins . ' coins added to all accounts.', true);
}
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");
if (!$statement) {
error('Failed to prepare query statement.');
displayMessage('Failed to prepare query statement.');
return false;
}
if (!$statement->execute($params)) {
error('Failed to add premium days.');
displayMessage('Failed to add premium days.');
return false;
}
@@ -89,7 +85,7 @@ function admin_give_premdays($days)
global $db, $freePremium;
if ($freePremium) {
error('Premium days not supported. Free Premium enabled.');
displayMessage('Premium days not supported. Free Premium enabled.');
return;
}
@@ -101,14 +97,14 @@ function admin_give_premdays($days)
if (query_add_premium('premend', '`premend` + :value', '`premend` > :now', ['value' => $value, 'now' => $now])) {
// set premend
if (query_add_premium('premend', ':value', '`premend` <= :now', ['value' => $now + $value, 'now' => $now])) {
success($days . ' premium days added to all accounts.');
displayMessage($days . ' premium days added to all accounts.', true);
return;
} else {
error('Failed to execute set query.');
displayMessage('Failed to execute set query.');
return;
}
} else {
error('Failed to execute append query.');
displayMessage('Failed to execute append query.');
return;
}
@@ -123,20 +119,20 @@ function admin_give_premdays($days)
if (query_add_premium('lastday', '`lastday` + :value', '`lastday` > :now', ['value' => $value, 'now' => $now])) {
// set lastday
if (query_add_premium('lastday', ':value', '`lastday` <= :now', ['value' => $now + $value, 'now' => $now])) {
success($days . ' premium days added to all accounts.');
displayMessage($days . ' premium days added to all accounts.', true);
return;
} else {
error('Failed to execute set query.');
displayMessage('Failed to execute set query.');
return;
}
success($days . ' premium days added to all accounts.');
return;
} else {
error('Failed to execute append query.');
displayMessage('Failed to execute append query.');
return;
}
} else {
error('Failed to execute set days query.');
displayMessage('Failed to execute set days query.');
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])) {
// set premium_ends_at
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;
} else {
error('Failed to execute set query.');
displayMessage('Failed to execute set query.');
return;
}
} else {
error('Failed to execute append query.');
displayMessage('Failed to execute append query.');
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)) {
error('Invalid action.');
displayMessage('Invalid action.');
} else {
$value = isset($_POST['value']) ? intval($_POST['value']) : 0;
if (!$value) {
error('Please fill all inputs');
displayMessage('Please fill all inputs');
} else {
switch ($action) {
case 'give-points':
@@ -189,14 +185,27 @@ if (isset($_POST['action']) && $_POST['action']) {
admin_give_premdays($value);
break;
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(
'hasCoinsColumn' => $hasCoinsColumn,
'hasPointsColumn' => $hasPointsColumn,
'freePremium' => $freePremium,
));
function displayMessage($message, $success = false) {
global $twig, $hasCoinsColumn, $hasPointsColumn, $freePremium;
$success ? success($message): error($message);
$twig->display('admin.tools.account.html.twig', array(
'hasCoinsColumn' => $hasCoinsColumn,
'hasPointsColumn' => $hasPointsColumn,
'freePremium' => $freePremium,
));
}

View File

@@ -0,0 +1,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
* @link https://my-aac.org
*/
use MyAAC\Cache\Cache;
use MyAAC\Models\Menu;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Menus';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) {
echo 'Access denied.';
return;
}
if (isset($_REQUEST['template'])) {
$template = $_REQUEST['template'];
if (isset($_POST['template'])) {
$template = $_POST['template'];
if (isset($_REQUEST['menu'])) {
$post_menu = $_REQUEST['menu'];
$post_menu_link = $_REQUEST['menu_link'];
$post_menu_blank = $_REQUEST['menu_blank'];
$post_menu_color = $_REQUEST['menu_color'];
if (isset($_POST['menu'])) {
$post_menu = $_POST['menu'];
$post_menu_link = $_POST['menu_link'];
$post_menu_blank = $_POST['menu_blank'];
$post_menu_color = $_POST['menu_color'];
if (count($post_menu) != count($post_menu_link)) {
echo 'Menu count is not equal menu links. Something went wrong when sending form.';
return;
}
$db->query('DELETE FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($template));
Menu::where('template', $template)->delete();
foreach ($post_menu as $category => $menus) {
foreach ($menus as $i => $menu) {
if (empty($menu)) // don't save empty menu item
continue;
try {
$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) {
warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage());
}
@@ -46,6 +60,7 @@ if (isset($_REQUEST['template'])) {
if ($cache->enabled()) {
$cache->delete('template_menus');
}
success('Saved at ' . date('H:i'));
}
@@ -56,6 +71,17 @@ if (isset($_REQUEST['template'])) {
echo 'Cannot find template config.php file.';
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'])) {
echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus.";
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/>
Not all templates support blank and colorful links.
</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>
<?php
$menus = array();
$menus_db = $db->query('SELECT `name`, `link`, `blank`, `color`, `category`, `ordering` FROM `' . TABLE_PREFIX . 'menu` WHERE `enabled` = 1 AND `template` = ' . $db->quote($template) . ' ORDER BY `ordering` ASC;')->fetchAll();
foreach ($menus_db as $menu) {
$menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']);
}
$menus = Menu::query()
->select('name', 'link', 'blank', 'color', 'category', 'ordering')
->where('enabled', 1)
->where('template', $template)
->orderBy('ordering')
->get()
->groupBy('category')
->toArray();
$last_id = array();
?>
<form method="post" id="menus-form" action="?p=menus">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-info">Save</button><br/><br/>
<div class="row">
<?php foreach ($config['menu_categories'] as $id => $cat): ?>
<div class="col-md-12 col-lg-6">
@@ -91,15 +131,16 @@ if (isset($_REQUEST['template'])) {
<ul class="sortable" id="sortable-<?php echo $id ?>">
<?php
if (isset($menus[$id])) {
foreach ($menus[$id] as $i => $menu):
$i = 0;
foreach ($menus[$id] as $menu):
?>
<li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo $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'] ?>"/>
<input type="hidden" name="menu_blank[<?php echo $id ?>][]" value="0"/>
<label><input class="blank-checkbox" type="checkbox" <?php echo($menu['blank'] == 1 ? 'checked' : '') ?>/><span title="Open in New Window">New Window</span></label>
<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="#<?php echo $menu['color'] ?>"/>
<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo (empty($menu['color']) ? ($config['menu_default_color'] ?? '#ffffff') : $menu['color']); ?>"/>
<a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li>
<?php $last_id[$id] = $i;
<?php $i++; $last_id[$id] = $i;
endforeach;
} ?>
</ul>
@@ -110,7 +151,7 @@ if (isset($_REQUEST['template'])) {
</div>
<div class="row pb-2">
<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
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
$twig->display('admin.menus.js.html.twig', array(
'menus' => $menus,
'last_id' => $last_id
'last_id' => $last_id,
'menu_default_color' => $config['menu_default_color'] ?? '#ffffff'
));
?>
<?php
} 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) {
$file = TEMPLATES . $value['template'] . '/config.php';
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="card card-info card-outline">
<div class="card-header">
@@ -15,7 +15,7 @@
</thead>
<tbody>
{% set i = 0 %}
{% for result in players %}
{% for result in accounts %}
{% set i = i + 1 %}
<tr>
<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
/**
* Account confirm mail
* Keept for compability
* Open Source libraries
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @copyright 2023 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
if($action == 'confirm_email') {
require_once PAGES . 'account/confirm_email.php';
}
?>
$title = 'Open Source';
$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;
}
?>
<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
* @link https://my-aac.org
*/
use MyAAC\Forum;
use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Player editor';
$player_base = BASE_URL . 'admin/?p=players';
csrfProtect();
$player_base = ADMIN_URL . '?p=players';
$use_datatable = true;
require_once LIBS . 'forum.php';
$skills = array(
POT::SKILL_FIST => array('Fist fighting', 'fist'),
@@ -72,7 +78,7 @@ else if (isset($_REQUEST['search'])) {
$player = new OTS_Player();
$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;
if ($player->isOnline())
@@ -196,7 +202,7 @@ else if (isset($_REQUEST['search'])) {
if ($hasBlessingsColumn) {
$blessings = $_POST['blessings'];
verify_number($blessings, 'Blessings', 2);
verify_number($blessings, 'Blessings', 3);
}
$balance = $_POST['balance'];
@@ -207,7 +213,7 @@ else if (isset($_REQUEST['search'])) {
}
$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']);
verify_number($created, 'Created', 11);
@@ -268,7 +274,7 @@ else if (isset($_REQUEST['search'])) {
$player->setLossContainers($loss_containers);
$player->setLossItems($loss_items);
}
if ($db->hasColumn('players', 'blessings'))
if ($hasBlessingsColumn)
$player->setBlessings($blessings);
if ($hasBlessingColumn) {
@@ -284,7 +290,7 @@ else if (isset($_REQUEST['search'])) {
$player->setCustomField('deletion', $deleted ? '1' : '0');
else
$player->setCustomField('deleted', $deleted ? '1' : '0');
$player->setCustomField('hidden', $hidden ? '1' : '0');
$player->setCustomField('hide', $hide ? '1' : '0');
$player->setCustomField('created', $created);
if (isset($comment))
$player->setCustomField('comment', $comment);
@@ -369,7 +375,8 @@ else if (isset($_REQUEST['search'])) {
</li>
</ul>
</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="tab-content" id="tabs-tabContent">
<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">
<label for="group">Group:</label>
<select name="group" id="group" class="form-control custom-select">
<?php foreach ($groups->getGroups() as $id => $group): ?>
<option value="<?php echo $id; ?>" <?php echo($player->getGroup()->getId() == $id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php foreach ($groups->getGroups() as $_id => $group): ?>
<option value="<?php echo $_id; ?>" <?php echo($player->getGroup()->getId() == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php endforeach; ?>
</select>
</div>
@@ -396,8 +403,8 @@ else if (isset($_REQUEST['search'])) {
<label for="vocation">Vocation</label>
<select name="vocation" id="vocation" class="form-control custom-select">
<?php
foreach ($config['vocations'] as $id => $name) {
echo '<option value=' . $id . ($id == $player->getVocation() ? ' selected' : '') . '>' . $name . '</option>';
foreach ($config['vocations'] as $_id => $name) {
echo '<option value=' . $_id . ($_id == $player->getVocation() ? ' selected' : '') . '>' . $name . '</option>';
}
?>
</select>
@@ -407,8 +414,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6">
<label for="sex">Sex:</label>
<select name="sex" id="sex" class="form-control custom-select">>
<?php foreach ($config['genders'] as $id => $sex): ?>
<option value="<?php echo $id; ?>" <?php echo($player->getSex() == $id ? 'selected' : ''); ?>><?php echo strtolower($sex); ?></option>
<?php foreach ($config['genders'] as $_id => $sex): ?>
<option value="<?php echo $_id; ?>" <?php echo($player->getSex() == $_id ? 'selected' : ''); ?>><?php echo strtolower($sex); ?></option>
<?php endforeach; ?>
</select>
</div>
@@ -421,8 +428,8 @@ else if (isset($_REQUEST['search'])) {
$configTowns[$player->getTownId()] = 'Unknown Town';
}
foreach ($configTowns as $id => $town): ?>
<option value="<?php echo $id; ?>" <?php echo($player->getTownId() == $id ? 'selected' : ''); ?>><?php echo $town; ?></option>
foreach ($configTowns as $_id => $town): ?>
<option value="<?php echo $_id; ?>" <?php echo($player->getTownId() == $_id ? 'selected' : ''); ?>><?php echo $town; ?></option>
<?php endforeach; ?>
</select>
</div>
@@ -433,8 +440,8 @@ else if (isset($_REQUEST['search'])) {
<select name="skull" id="skull" class="form-control custom-select">
<?php
foreach ($skull_type as $id => $s_name) {
echo '<option value=' . $id . ($id == $player->getSkull() ? ' selected' : '') . '>' . $s_name . '</option>';
foreach ($skull_type as $_id => $s_name) {
echo '<option value=' . $_id . ($_id == $player->getSkull() ? ' selected' : '') . '>' . $s_name . '</option>';
}
?>
</select>
@@ -478,8 +485,8 @@ else if (isset($_REQUEST['search'])) {
</div>
<div class="col-12 col-sm-12 col-lg-6">
<div class="custom-control custom-switch custom-switch-on-success">
<input type="checkbox" class="custom-control-input" name="hidden" id="hidden" value="true" <?php echo($player->isHidden() ? ' checked' : ''); ?>>
<label class="custom-control-label" for="hidden">Hidden</label>
<input type="checkbox" class="custom-control-input" name="hide" id="hide" value="true" <?php echo($player->isHidden() ? ' checked' : ''); ?>>
<label class="custom-control-label" for="hide">Hidden</label>
</div>
</div>
</div>
@@ -551,22 +558,22 @@ else if (isset($_REQUEST['search'])) {
</div>
<div class="tab-pane fade" id="tabs-skills">
<?php
foreach ($skills as $id => $info) {
foreach ($skills as $_id => $info) {
?>
<div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6">
<?php echo '<label for="skills[' . $id . ']" class="control-label">' . $info[0] . '</label>
<input type="text" class="form-control" id="skills[' . $id . ']" name="skills[' . $id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkill($id) . '"/>'; ?>
<?php echo '<label for="skills[' . $_id . ']" class="control-label">' . $info[0] . '</label>
<input type="text" class="form-control" id="skills[' . $_id . ']" name="skills[' . $_id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkill($_id) . '"/>'; ?>
</div>
<div class="col-12 col-sm-12 col-lg-6">
<?php echo '<label for="skills_tries[' . $id . ']" class="control-label">' . $info[0] . ' tries</label>
<input type="text" class="form-control" id="skills_tries[' . $id . ']" name="skills_tries[' . $id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkillTries($id) . '"/>'; ?>
<?php echo '<label for="skills_tries[' . $_id . ']" class="control-label">' . $info[0] . ' tries</label>
<input type="text" class="form-control" id="skills_tries[' . $_id . ']" name="skills_tries[' . $_id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkillTries($_id) . '"/>'; ?>
</div>
</div>
<?php } ?>
</div>
<div class="tab-pane fade" id="tabs-pos">
<?php $outfit = $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">
<img id="player_outfit" style="margin-left:0;margin-top:0;width:64px;height:64px;" src="<?php echo $outfit; ?>" alt="player outfit"/>
</div>
@@ -619,7 +626,7 @@ else if (isset($_REQUEST['search'])) {
if ($outfitlist) { ?>
<select name="look_type" id="look_type" class="form-control custom-select">
<?php
foreach ($outfitlist as $id => $outfit) {
foreach ($outfitlist as $_id => $outfit) {
if ($outfit['enabled'] == 'yes') ;
echo '<option value=' . $outfit['id'] . ($outfit['id'] == $player->getLookType() ? ' selected' : '') . '>' . $outfit['name'] . ' - ' . ($outfit['type'] == 1 ? 'Male' : 'Female') . '</option>';
}
@@ -634,9 +641,9 @@ else if (isset($_REQUEST['search'])) {
<label for="look_addons" class="control-label">Addons:</label>
<select name="look_addons" id="look_addons" class="form-control custom-select">
<?php
$addon_type = array(0, 1, 2, 3);
foreach ($addon_type as $id => $s_name) {
echo '<option value=' . $s_name . ($id == $player->getLookAddons() ? ' selected' : '') . '>' . $s_name . '</option>';
$addon_type = array("None", "First", "Second", "Both");
foreach ($addon_type as $_id => $s_name) {
echo '<option value=' . $_id . ($_id == $player->getLookAddons() ? ' selected' : '') . '>' . $s_name . '</option>';
}
?>
</select>
@@ -663,7 +670,14 @@ else if (isset($_REQUEST['search'])) {
</div>
<div class="col-12 col-sm-12 col-lg-6">
<label for="lastip" class="control-label">Last IP:</label>
<input type="text" class="form-control" id="lastip" name="lastip" autocomplete="off" maxlength="10" value="<?php echo longToIp($player->getLastIP()); ?>" readonly/>
<input type="text" class="form-control" id="lastip" name="lastip" autocomplete="off" maxlength="10" value="<?php
if (strlen($player->getLastIP()) > 11) {
echo inet_ntop($player->getLastIP());
}
else {
echo longToIp($player->getLastIP());
}
?>" readonly/>
</div>
</div>
<?php if ($db->hasColumn('players', 'loss_experience')): ?>
@@ -694,7 +708,7 @@ else if (isset($_REQUEST['search'])) {
<div class="form-group row">
<div class="col-12">
<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>
</div>
</div>
@@ -737,8 +751,7 @@ else if (isset($_REQUEST['search'])) {
<div class="row">
<?php
if (isset($account) && $account->isLoaded()) {
$account_players = $account->getPlayersList();
$account_players->orderBy('id');
$account_players = Player::where('account_id', $account->getId())->orderBy('id')->get();
if (isset($account_players)) { ?>
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
@@ -751,23 +764,13 @@ else if (isset($_REQUEST['search'])) {
</tr>
</thead>
<tbody>
<?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];
} ?>
<?php foreach ($account_players as $i => $player): ?>
<tr>
<th><?php echo $i; ?></th>
<td><?php echo $player->getName(); ?></td>
<td><?php echo $player->getLevel(); ?></td>
<td><?php echo $vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getId() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
<th><?php echo $i + 1; ?></th>
<td><?php echo $player->name; ?></td>
<td><?php echo $player->level; ?></td>
<td><?php echo $player->vocation_name; ?></td>
<td><a href="?p=players&id=<?php echo $player->getKey() ?>" class=" btn btn-success btn-sm" title="Edit"><i class="fas fa-pencil-alt"></i></a></td>
</tr>
<?php endforeach ?>
</tbody>
@@ -842,7 +845,7 @@ else if (isset($_REQUEST['search'])) {
<?php if($hasLookAddons): ?>
const $addonvalue = $('#look_addons');
$('#look_addons').on('change', () => {
$addonvalue.on('change', () => {
updateOutfit();
});
<?php endif; ?>
@@ -859,7 +862,7 @@ else if (isset($_REQUEST['search'])) {
<?php if($hasLookAddons): ?>
look_addons = '&addons=' + $('#look_addons').val();
<?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>
<?php } ?>
@@ -871,18 +874,20 @@ else if (isset($_REQUEST['search'])) {
<div class="card-body row">
<div class="col-6 col-lg-12">
<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">
<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>
</div>
</form>
</div>
<div class="col-6 col-lg-12">
<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">
<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>
</div>
</form>
@@ -893,7 +898,7 @@ else if (isset($_REQUEST['search'])) {
</div>
<script>
$(document).ready(function () {
$(function () {
$('.player_datatable').DataTable({
"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 - ' . $settingsFile['name']);
$settingsParsed = Settings::display($settingsKeyName, $settingsFile['settings']);
$twig->display('admin.settings.html.twig', [
'settingsParsed' => $settingsParsed['content'],
'settings' => $settingsFile['settings'],
'script' => $settingsParsed['script'],
'settingsKeyName' => $settingsKeyName,
]);

View File

@@ -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;
}
$file = SYSTEM . 'pages/admin/tools/' . $tool . '.php';
$file = ADMIN . 'tools/' . $tool . '.php';
if (@file_exists($file)) {
require $file;

View File

@@ -47,4 +47,3 @@ function version_revert($version)
$release = $version;
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 = [
['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' => 'Add news', 'link' => 'news&action=new&type=1', 'order' => 20],
['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'order' => 30],
['name' => 'Add article', 'link' => 'news&action=new&type=3', 'order' => 40],
['name' => 'View', 'link' => 'news', 'icon' => 'list', 'order' => 10],
['name' => 'Add news', 'link' => 'news&action=new&type=1', 'icon' => 'plus', 'order' => 20],
['name' => 'Add ticker', 'link' => 'news&action=new&type=2', 'icon' => 'plus', 'order' => 30],
['name' => 'Add article', 'link' => 'news&action=new&type=3', 'icon' => 'plus', 'order' => 40],
],
],
['name' => 'Changelogs', 'icon' => 'newspaper', 'order' => 30, 'link' =>
[
['name' => 'View', 'link' => 'changelog', 'order' => 10],
['name' => 'Add', 'link' => 'changelog&action=new', 'order' => 20],
['name' => 'View', 'link' => 'changelog', 'icon' => 'list', 'order' => 10],
['name' => 'Add', 'link' => 'changelog&action=new', 'icon' => 'plus', 'order' => 20],
],
],
['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !config('mail_enabled')],
['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !setting('core.mail_enabled')],
['name' => 'Pages', 'icon' => 'book', 'order' => 50, 'link' =>
[
['name' => 'View', 'link' => 'pages', 'order' => 10],
['name' => 'Add', 'link' => 'pages&action=new', 'order' => 20],
['name' => 'View', 'link' => 'pages', 'icon' => 'list', 'order' => 10],
['name' => 'Add', 'link' => 'pages&action=new', 'icon' => 'plus', 'order' => 20],
],
],
['name' => 'Menus', 'icon' => 'list', 'order' => 60, 'link' => 'menus'],
@@ -28,23 +31,23 @@ $menus = [
['name' => 'Server Data', 'icon' => 'gavel', 'order' => 80, 'link' => 'data'],
['name' => 'Editor', 'icon' => 'edit', 'order' => 90, 'link' =>
[
['name' => 'Accounts', 'link' => 'accounts', 'order' => 10],
['name' => 'Players', 'link' => 'players', 'order' => 20],
['name' => 'Accounts', 'link' => 'accounts', 'icon' => 'users', 'order' => 10],
['name' => 'Players', 'link' => 'players', 'icon' => 'user-astronaut', 'order' => 20],
],
],
['name' => 'Tools', 'icon' => 'tools', 'order' => 100, 'link' =>
[
['name' => 'Mass Account Actions', 'link' => 'tools&tool=account', 'order' => 10],
['name' => 'Mass Teleport Actions', 'link' => 'tools&tool=teleport', 'order' => 20],
['name' => 'Notepad', 'link' => 'notepad', 'order' => 30],
['name' => 'phpinfo', 'link' => 'phpinfo', 'order' => 40],
['name' => 'Mass Account Actions', 'link' => 'mass_account', 'icon' => 'globe', 'order' => 10],
['name' => 'Mass Teleport Actions', 'link' => 'mass_teleport', 'icon' => 'globe', 'order' => 20],
['name' => 'Notepad', 'link' => 'notepad', 'icon' => 'marker', 'order' => 30],
['name' => 'phpinfo', 'link' => 'phpinfo', 'icon' => 'server', 'order' => 40],
],
],
['name' => 'Logs', 'icon' => 'bug', 'order' => 110, 'link' =>
[
['name' => 'Logs', 'link' => 'logs', 'order' => 10],
['name' => 'Reports', 'link' => 'reports', 'order' => 20],
['name' => 'Visitors', 'icon' => 'user', 'link' => 'visitors', 'order' => 30],
['name' => 'Logs', 'link' => 'logs', 'icon' => 'book', 'order' => 10],
['name' => 'Reports', 'link' => 'reports', 'icon' => 'book', 'order' => 20],
['name' => 'Visitors', 'link' => 'visitors', 'icon' => 'user', 'order' => 30],
],
],
];

View File

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

View File

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

View File

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

View File

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

@@ -20,22 +20,24 @@
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @copyright 2024 MyAAC
* @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_VERSION = '0.9.0-dev';
const DATABASE_VERSION = 33;
const MYAAC_VERSION = '1.0-RC';
const DATABASE_VERSION = 40;
const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true));
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']));
// account flags
const FLAG_NONE = 0;
const FLAG_ADMIN = 1;
const FLAG_SUPER_ADMIN = 2;
const FLAG_SUPER_BOTH = 3;
const FLAG_CONTENT_PAGES = 4;
const FLAG_CONTENT_MAILER = 8;
const FLAG_CONTENT_NEWS = 16;
@@ -49,14 +51,27 @@ const FLAG_CONTENT_FAQ = 2048;
const FLAG_CONTENT_MENUS = 4096;
const FLAG_CONTENT_PLAYERS = 8192;
// account access types
const ACCOUNT_WEB_FLAGS = [
FLAG_NONE => 'None',
FLAG_ADMIN =>'Admin',
FLAG_SUPER_ADMIN => 'Super Admin',
FLAG_SUPER_BOTH =>'(Admin + Super Admin)',
];
// news
const NEWS = 1;
const TICKER = 2;
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
const BASE = __DIR__ . '/';
const ADMIN = BASE . 'admin/';
const ADMIN = BASE . ADMIN_PANEL_FOLDER . '/';
const SYSTEM = BASE . 'system/';
const CACHE = SYSTEM . 'cache/';
const LOCALE = SYSTEM . 'locale/';
@@ -93,10 +108,19 @@ const TFS_FIRST = TFS_02;
const TFS_LAST = TFS_03;
// 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;
session_save_path(SESSIONS_DIR);
session_start();
if (!IS_CLI) {
session_save_path(SESSIONS_DIR);
session_start();
}
// basedir
$basedir = '';
@@ -105,7 +129,7 @@ $size = count($tmp) - 1;
for($i = 1; $i < $size; $i++)
$basedir .= '/' . $tmp[$i];
$basedir = str_replace(['/admin', '/install', '/tools'], '', $basedir);
$basedir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $basedir);
define('BASE_DIR', $basedir);
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('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/');
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/');
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
}
require SYSTEM . 'exception.php';
if (file_exists(BASE . 'config.local.php')) {
require BASE . 'config.local.php';
}
/** @var array $config */
ini_set('log_errors', 1);
if(@$config['env'] === 'dev' || defined('MYAAC_INSTALL')) {
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';
@@ -134,3 +173,11 @@ if (!is_file($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": {
"php": "^7.2.5 || ^8.0",
"php": "^8.0",
"ext-pdo": "*",
"ext-pdo_mysql": "*",
"ext-json": "*",
@@ -9,6 +9,24 @@
"phpmailer/phpmailer": "^6.1",
"composer/semver": "^3.2",
"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('#createaccount').submit()
// no errors please
cy.contains('The Following Errors Have Occurred:').should('not.exist')
// ss of post page
cy.screenshot('create-account-page-post')
})
})

View File

@@ -0,0 +1,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
*/
use MyAAC\UsageStatistics;
use MyAAC\Visitors;
require_once 'common.php';
require_once SYSTEM . 'functions.php';
$uri = $_SERVER['REQUEST_URI'];
if(false !== strpos($uri, 'index.php')) {
$uri = str_replace_first('/index.php', '', $uri);
}
$tmp = BASE_DIR;
if(!empty($tmp))
$uri = str_replace(BASE_DIR . '/', '', $uri);
else
if(0 === strpos($uri, '/')) {
$uri = str_replace_first('/', '', $uri);
}
$uri = str_replace(array('index.php/', '?'), '', $uri);
define('URI', $uri);
if(preg_match("/^[A-Za-z0-9-_%'+\/]+\.png$/i", $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]);
chdir(TOOLS . 'signature');
@@ -47,146 +54,21 @@ if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) {
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);
exit;
}
if(file_exists(BASE . 'config.local.php')) {
require_once BASE . 'config.local.php';
}
ini_set('log_errors', 1);
if(config('env') === 'dev') {
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
}
else {
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
}
if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install'))
{
header('Location: ' . BASE_URL . 'install/');
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();
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 . 'login.php';
require_once SYSTEM . 'status.php';
@@ -194,13 +76,52 @@ require_once SYSTEM . 'status.php';
$twig->addGlobal('config', $config);
$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);
// anonymous usage statistics
// sent only when user agrees
if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_statistics']) {
if(setting('core.anonymous_usage_statistics')) {
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days
$should_report = true;
@@ -223,8 +144,7 @@ if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_stat
}
if($should_report) {
require_once LIBS . 'usage_statistics.php';
Usage_Statistics::report();
UsageStatistics::report();
updateDatabaseConfig('last_usage_report', time());
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';
if($config['visitors_counter'])
{
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;
if(setting('core.visitors_counter')) {
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
}
/**

View File

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

View File

@@ -11,13 +11,13 @@ function query($query)
error($error_);
$error = true;
}
return !$error;
}
// define php version id if its not already
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]));
}
@@ -97,4 +97,4 @@ function win_is_writable($path) {
unlink($path);
return true;
}
}

View File

@@ -1,4 +1,4 @@
SET @myaac_database_version = 33;
SET @myaac_database_version = 40;
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',
`date` 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`)
) 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`
(
@@ -67,7 +67,7 @@ CREATE TABLE `myaac_faq`
`question` VARCHAR(255) NOT NULL DEFAULT '',
`answer` VARCHAR(1020) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -80,7 +80,7 @@ CREATE TABLE `myaac_forum_boards`
`guild` INT(11) NOT NULL DEFAULT 0,
`access` INT(11) 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`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
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`)
) 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` (
`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,
`mana` int(11) NOT NULL DEFAULT 0,
`exp` int(11) NOT NULL,
`health` int(11) NOT NULL,
`look` VARCHAR(255) NOT NULL DEFAULT '',
`speed_lvl` int(11) NOT NULL default 1,
`use_haste` tinyint(1) NOT NULL,
`voices` text NOT NULL,
@@ -242,7 +174,7 @@ CREATE TABLE `myaac_news`
`comments` VARCHAR(50) NOT NULL DEFAULT '',
`article_text` VARCHAR(300) 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`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -252,7 +184,7 @@ CREATE TABLE `myaac_news_categories`
`name` VARCHAR(50) NOT NULL DEFAULT "",
`description` VARCHAR(50) NOT NULL DEFAULT "",
`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`)
) 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',
`enable_tinymce` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 - enabled, 0 - disabled',
`access` TINYINT(2) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -296,12 +228,22 @@ CREATE TABLE `myaac_gallery`
`thumb` VARCHAR(255) NOT NULL,
`author` VARCHAR(50) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) 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');
CREATE TABLE `myaac_settings`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT '',
`key` VARCHAR(255) NOT NULL DEFAULT '',
`value` TEXT NOT NULL,
PRIMARY KEY (`id`),
KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE `myaac_spells`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
@@ -320,7 +262,7 @@ CREATE TABLE `myaac_spells`
`item_id` INT(11) NOT NULL DEFAULT 0,
`premium` TINYINT(1) NOT NULL DEFAULT 0,
`vocations` VARCHAR(100) NOT NULL DEFAULT '',
`hidden` TINYINT(1) NOT NULL DEFAULT 0,
`hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -330,6 +272,7 @@ CREATE TABLE `myaac_visitors`
`ip` VARCHAR(45) NOT NULL,
`lastvisit` INT(11) NOT NULL DEFAULT 0,
`page` VARCHAR(2048) NOT NULL,
`user_agent` VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE (`ip`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

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">
.console {

View File

@@ -3,9 +3,9 @@
use Twig\Environment as Twig_Environment;
use Twig\Loader\FilesystemLoader as Twig_FilesystemLoader;
require '../common.php';
const MYAAC_INSTALL = true;
define('MYAAC_INSTALL', true);
require '../common.php';
// includes
require SYSTEM . 'functions.php';
@@ -13,9 +13,6 @@ require BASE . 'install/includes/functions.php';
require BASE . 'install/includes/locale.php';
require SYSTEM . 'clients.conf.php';
if(file_exists(BASE . 'config.local.php'))
require BASE . 'config.local.php';
// ignore undefined index from Twig autoloader
$config['env'] = 'prod';
@@ -26,13 +23,13 @@ $twig = new Twig_Environment($twig_loader, array(
));
// load installation status
$step = isset($_POST['step']) ? $_POST['step'] : 'welcome';
$step = $_REQUEST['step'] ?? 'welcome';
$install_status = array();
if(file_exists(CACHE . 'install.txt')) {
$install_status = unserialize(file_get_contents(CACHE . 'install.txt'));
if(!isset($_POST['step'])) {
if(!isset($_REQUEST['step'])) {
$step = isset($install_status['step']) ? $install_status['step'] : '';
}
}
@@ -70,7 +67,7 @@ if($step == 'database') {
$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;
}
@@ -91,10 +88,6 @@ if($step == 'database') {
break;
}
}
else if($key == 'mail_admin' && !Validator::email($value)) {
$errors[] = $locale['step_config_mail_admin_error'];
break;
}
else if($key == 'timezone' && !in_array($value, DateTimeZone::listIdentifiers())) {
$errors[] = $locale['step_config_timezone_error'];
break;
@@ -110,18 +103,17 @@ if($step == 'database') {
}
}
else if($step == 'admin') {
$config_failed = true;
if(file_exists(BASE . 'config.local.php') && isset($config['installed']) && $config['installed'] && isset($_SESSION['saved'])) {
$config_failed = false;
}
if($config_failed) {
if(!file_exists(BASE . 'config.local.php') || !isset($config['installed']) || !$config['installed']) {
$step = 'database';
}
else {
$_SESSION['saved'] = true;
}
}
else if($step == 'finish') {
$email = $_SESSION['var_email'];
$password = $_SESSION['var_password'];
$password_confirm = $_SESSION['var_password_confirm'];
$player_name = $_SESSION['var_player_name'];
// email check
@@ -163,6 +155,9 @@ else if($step == 'finish') {
else if(!Validator::password($password)) {
$errors[] = $locale['step_admin_password_error_format'];
}
else if($password != $password_confirm) {
$errors[] = $locale['step_admin_password_confirm_error_not_same'];
}
// player name check
if(empty($player_name)) {

View File

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

View File

@@ -2,10 +2,15 @@
defined('MYAAC') or die('Direct access not allowed!');
// configuration
$dirs_required = [
$dirs_required_writable = [
'system/logs',
'system/cache',
];
$dirs_required = [
'tools/ext' => $locale['step_requirements_folder_not_exists_tools_ext'],
];
$dirs_optional = [
GUILD_IMAGES_DIR => $locale['step_requirements_warning_images_guilds'],
GALLERY_DIR => $locale['step_requirements_warning_images_gallery'],
@@ -18,6 +23,7 @@ $extensions_optional = [
'gd' => $locale['step_requirements_warning_player_signatures'],
'zip' => $locale['step_requirements_warning_install_plugins'],
];
/*
*
* @param string $name
@@ -41,7 +47,7 @@ $failed = false;
// start validating
version_check($locale['step_requirements_php_version'], (PHP_VERSION_ID >= 50500), PHP_VERSION);
foreach ($dirs_required as $value)
foreach ($dirs_required_writable as $value)
{
$is_writable = is_writable(BASE . $value) && (MYAAC_OS != 'WINDOWS' || win_is_writable(BASE . $value));
version_check($locale['step_requirements_write_perms'] . ': ' . $value, $is_writable);
@@ -52,6 +58,12 @@ foreach ($dirs_optional as $dir => $errorMsg) {
version_check($locale['step_requirements_write_perms'] . ': ' . $dir, $is_writable, $is_writable ? '' : $errorMsg, true);
}
foreach ($dirs_required as $dir => $errorMsg)
{
$exists = is_dir(BASE . $dir);
version_check($locale['step_requirements_folder_exists'] . ': ' . $dir, $exists, $exists ? '' : $errorMsg);
}
$ini_register_globals = ini_get_bool('register_globals');
version_check('register_long_arrays', !$ini_register_globals, $ini_register_globals ? $locale['on'] : $locale['off']);
@@ -78,4 +90,3 @@ if($failed) {
}
echo '</div>';
?>

View File

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

View File

@@ -1,4 +1,7 @@
<?php
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!');
//ini_set('display_errors', false);
@@ -11,16 +14,12 @@ if(!isset($_SESSION['var_server_path'])) {
}
if(!$error) {
$content = "<?php";
$content .= PHP_EOL;
$content .= '// place for your configuration directives, so you can later easily update myaac';
$content .= PHP_EOL;
$content .= '$config[\'installed\'] = true;';
$content .= PHP_EOL;
// by default, set env to prod
// user can disable when he wants
$content .= '$config[\'env\'] = \'prod\'; // dev or prod';
$content .= PHP_EOL;
$configToSave = [
// by default, set env to prod
// user can disable when he wants
'env' => 'prod',
];
foreach($_SESSION as $key => $value)
{
if(strpos($key, 'var_') !== false)
@@ -32,64 +31,66 @@ if(!$error) {
$value .= '/';
}
if($key === 'var_usage') {
$content .= '$config[\'anonymous_usage_statistics\'] = ' . ((int)$value == 1 ? 'true' : 'false') . ';';
$content .= PHP_EOL;
}
else if(!in_array($key, array('var_account', 'var_account_id', 'var_password', 'var_step', 'var_email', 'var_player_name'), true)) {
$content .= '$config[\'' . str_replace('var_', '', $key) . '\'] = \'' . $value . '\';';
$content .= PHP_EOL;
if(!in_array($key, ['var_usage', 'var_date_timezone', 'var_client', 'var_account', 'var_account_id', 'var_password', 'var_password_confirm', 'var_step', 'var_email', 'var_player_name'], true)) {
$configToSave[str_replace('var_', '', $key)] = $value;
}
}
}
require BASE . 'install/includes/config.php';
$configToSave['gzip_output'] = false;
$configToSave['cache_engine'] = 'auto';
$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true);
if(!$error) {
require BASE . 'install/includes/database.php';
$content = '';
$saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content);
if ($saved) {
success($locale['step_database_config_saved']);
$_SESSION['saved'] = true;
$locale['step_database_importing'] = str_replace('$DATABASE_NAME$', config('database_name'), $locale['step_database_importing']);
success($locale['step_database_importing']);
require BASE . 'config.local.php';
require BASE . 'install/includes/config.php';
if(isset($database_error)) { // we failed connect to the database
error($database_error);
}
else {
$twig->display('install.installer.html.twig', array(
'url' => 'tools/5-database.php',
'message' => $locale['loading_spinner']
));
if (!$error) {
require BASE . 'install/includes/database.php';
if(!$error) {
if(!Validator::email($_SESSION['var_mail_admin'])) {
error($locale['step_config_mail_admin_error']);
$error = true;
}
$content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$content .= PHP_EOL;
$content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$saved = true;
if(!$error) {
$saved = file_put_contents(BASE . 'config.local.php', $content);
}
if($saved) {
success($locale['step_database_config_saved']);
if(!$error) {
$_SESSION['saved'] = true;
}
if (isset($database_error)) { // we failed connect to the database
error($database_error);
}
else {
$_SESSION['config_content'] = $content;
unset($_SESSION['saved']);
if (!$db->hasTable('accounts')) {
$tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
error($tmp);
$error = true;
}
$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>');
if (!$db->hasTable('players')) {
$tmp = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
error($tmp);
$error = true;
}
if (!$db->hasTable('guilds')) {
$tmp = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
error($tmp);
$error = true;
}
if (!$error) {
$twig->display('install.installer.html.twig', array(
'url' => 'tools/5-database.php',
'message' => $locale['loading_spinner']
));
}
}
}
} else {
$_SESSION['config_content'] = $content;
unset($_SESSION['saved']);
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.php</b>', $locale['step_database_error_file']);
error($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>');
}
}
}
@@ -98,7 +99,7 @@ if(!$error) {
<div class="text-center m-3">
<form action="<?php echo BASE_URL; ?>install/" method="post">
<input type="hidden" name="step" id="step" value="admin" />
<?php echo next_buttons(true, $error ? false : true);
<?php echo next_buttons(true, !$error);
?>
</form>
</div>
</div>

View File

@@ -1,151 +1,203 @@
<?php
use MyAAC\Cache\Cache;
use MyAAC\Models\News;
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!');
ini_set('max_execution_time', 300);
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
return;
}
$cache = Cache::getInstance();
if ($cache->enabled()) {
// clear plugin_hooks to have fresh hooks
$cache->delete('plugins_hooks');
}
require SYSTEM . 'init.php';
if($error) {
return;
}
if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER)
$account = $_SESSION['var_account'] ?? null;
else
$account_id = $_SESSION['var_account_id'] ?? null;
$password = $_SESSION['var_password'];
if(USE_ACCOUNT_SALT)
{
$salt = generateRandomString(10, false, true, true);
$password = $salt . $password;
}
$account_db = new OTS_Account();
if(isset($account))
$account_db->find($account);
else
$account_db->load($account_id);
$player_name = $_SESSION['var_player_name'];
$player_db = new OTS_Player();
$player_db->find($player_name);
if(!$player_db->isLoaded())
{
$player = new OTS_Player();
$player->setName($player_name);
$player_used = &$player;
}
else {
require SYSTEM . 'init.php';
if(!$error) {
if(USE_ACCOUNT_NAME)
$account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null;
else
$account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null;
$player_used = &$player_db;
}
$password = $_SESSION['var_password'];
$groups = new OTS_Groups_List();
$player_used->setGroupId($groups->getHighestId());
$config_salt_enabled = $db->hasColumn('accounts', 'salt');
if($config_salt_enabled)
{
$salt = generateRandomString(10, false, true, true);
$password = $salt . $password;
$email = $_SESSION['var_email'];
if($account_db->isLoaded()) {
$account_db->setPassword(encrypt($password));
$account_db->setEMail($email);
$account_db->save();
$account_used = &$account_db;
}
else {
$new_account = new OTS_Account();
if(USE_ACCOUNT_NAME) {
$new_account->create($account);
}
else {
$new_account->create(null, $account_id);
}
$new_account->setPassword(encrypt($password));
$new_account->setEMail($email);
$new_account->save();
$new_account->setCustomField('created', time());
$new_account->logAction('Account created.');
$account_used = &$new_account;
}
if(USE_ACCOUNT_SALT)
$account_used->setCustomField('salt', $salt);
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us');
$account_used->setCustomField('email_verified', 1);
if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId());
if($db->hasColumn('accounts', 'type'))
$account_used->setCustomField('type', 6);
if(!$player_db->isLoaded())
$player->setAccountId($account_used->getId());
else
$player_db->setAccountId($account_used->getId());
success($locale['step_database_created_account']);
setSession('account', $account_used->getId());
setSession('password', encrypt($password));
setSession('remember_me', true);
if($player_db->isLoaded()) {
$player_db->save();
}
else {
$player->save();
}
if(!News::all()->count()) {
$player_id = 0;
$tmpNewsPlayer = \MyAAC\Models\Player::where('name', $player_name)->first();
if($tmpNewsPlayer) {
$player_id = $tmpNewsPlayer->id;
}
News::create([
'type' => 1,
'date' => time(),
'category' => 2,
'title' => 'Hello!',
'body' => 'MyAAC is just READY to use!',
'player_id' => $player_id,
'comments' => 'https://my-aac.org',
'hide' => 0,
]);
News::create([
'type' => 2,
'date' => time(),
'category' => 4,
'title' => 'Hello tickers!',
'body' => 'https://my-aac.org',
'player_id' => $player_id,
'comments' => '',
'hide' => 0,
]);
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';
}
$account_db = new OTS_Account();
if(isset($account))
$account_db->find($account);
else
$account_db->load($account_id);
$player_name = $_SESSION['var_player_name'];
$player_db = new OTS_Player();
$player_db->find($player_name);
if(!$player_db->isLoaded())
{
$player = new OTS_Player();
$player->setName($player_name);
$player_used = &$player;
}
else {
$player_used = &$player_db;
}
$groups = new OTS_Groups_List();
$player_used->setGroupId($groups->getHighestId());
$email = $_SESSION['var_email'];
if($account_db->isLoaded()) {
$account_db->setPassword(encrypt($password));
$account_db->setEMail($email);
$account_db->save();
$account_used = &$account_db;
}
else {
$new_account = new OTS_Account();
if(USE_ACCOUNT_NAME) {
$new_account->create($account);
}
else {
$new_account->create(null, $account_id);
}
$new_account->setPassword(encrypt($password));
$new_account->setEMail($email);
$new_account->unblock();
$new_account->save();
$new_account->setCustomField('created', time());
$new_account->logAction('Account created.');
$account_used = &$new_account;
}
if($config_salt_enabled)
$account_used->setCustomField('salt', $salt);
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us');
if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId());
if($db->hasColumn('accounts', 'type'))
$account_used->setCustomField('type', 5);
if(!$player_db->isLoaded())
$player->setAccountId($account_used->getId());
else
$player_db->setAccountId($account_used->getId());
success($locale['step_database_created_account']);
setSession('account', $account_used->getId());
setSession('password', encrypt($password));
setSession('remember_me', true);
if($player_db->isLoaded()) {
$player_db->save();
}
else {
$player->save();
}
$player_id = 0;
$query = $db->query("SELECT `id` FROM `players` WHERE `name` = " . $db->quote($player_name) . ";");
if($query->rowCount() == 1) {
$query = $query->fetch();
$player_id = $query['id'];
}
$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX ."news` WHERE `title` LIKE 'Hello!';");
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');
INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '2', UNIX_TIMESTAMP(), '4', 'Hello tickets!', 'https://my-aac.org', " . $player_id . ", '', '0');")) {
success($locale['step_database_created_news']);
}
}
$twig->display('install.installer.html.twig', array(
'url' => 'tools/7-finish.php',
'message' => $locale['importing_spinner']
));
if(!isset($_SESSION['installed'])) {
$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_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_exec($curl);
curl_close($curl);
}
else if (ini_get('allow_url_fopen') ) {
file_get_contents($report_url);
}
$_SESSION['installed'] = true;
}
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') !== false)
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
$settings->updateInDatabase('core', $key, $value);
}
}
success('Settings saved.');
$twig->display('install.installer.html.twig', array(
'url' => 'tools/7-finish.php',
'message' => $locale['importing_spinner']
));
if(!isset($_SESSION['installed'])) {
if (!array_key_exists('CI', getenv())) {
$report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL);
if (function_exists('curl_version'))
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $report_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_exec($curl);
curl_close($curl);
}
else if (ini_get('allow_url_fopen') ) {
file_get_contents($report_url);
}
}
$_SESSION['installed'] = true;
}
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') !== false)
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
$hooks->trigger(HOOK_INSTALL_FINISH_END);

View File

@@ -4,14 +4,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MyAAC - <?php echo $locale['installation']; ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="template/style.css" />
<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/js/jquery.min.js"></script>
<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/ext/jquery/jquery.min.js"></script>
</head>
<body>
<div id="body" class="container">
<header id="header" class="pt-5 pb-4 pb-sm-5">
<h1>MyAAC <?php echo $locale['installation']; ?></h1>
</header>
@@ -28,10 +28,10 @@
if ($step == $value) {
$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>
</div>
@@ -71,4 +71,4 @@
<p style="text-align: center;"><?php echo base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); ?></p>
</footer>
</body>
</html>
</html>

View File

@@ -11,8 +11,10 @@ $error = false;
require BASE . 'install/includes/config.php';
ini_set('max_execution_time', 300);
@ob_end_flush();
ob_implicit_flush();
ob_end_flush();
header('X-Accel-Buffering: no');
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')) {
$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']);
@@ -48,6 +32,9 @@ if($db->hasTable(TABLE_PREFIX . 'account_actions')) {
else {
// import schema
try {
$locale['step_database_importing'] = str_replace('$DATABASE_NAME$', config('database_name'), $locale['step_database_importing']);
success($locale['step_database_importing']);
$db->query(file_get_contents(BASE . 'install/includes/schema.sql'));
$locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']);
@@ -73,13 +60,8 @@ else {
success($locale['step_database_adding_field'] . ' accounts.key...');
}
if(!$db->hasColumn('accounts', 'blocked')) {
if(query("ALTER TABLE `accounts` ADD `blocked` TINYINT(1) NOT NULL DEFAULT FALSE COMMENT 'internal usage' AFTER `key`;"))
success($locale['step_database_adding_field'] . ' accounts.blocked...');
}
if(!$db->hasColumn('accounts', 'created')) {
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'blocked') . "`;"))
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'key') . "`;"))
success($locale['step_database_adding_field'] . ' accounts.created...');
}
@@ -159,73 +141,74 @@ if(!$db->hasColumn('accounts', 'premium_points')) {
success($locale['step_database_adding_field'] . ' accounts.premium_points...');
}
if($db->hasColumn('guilds', 'checkdata')) {
if(query("ALTER TABLE `guilds` MODIFY `checkdata` INT NOT NULL DEFAULT 0;"))
success($locale['step_database_modifying_field'] . ' guilds.checkdata...');
}
if(!$db->hasColumn('guilds', 'motd')) {
if(query("ALTER TABLE `guilds` ADD `motd` VARCHAR(255) NOT NULL DEFAULT '';"))
success($locale['step_database_adding_field'] . ' guilds.motd...');
}
else {
if(query("ALTER TABLE `guilds` MODIFY `motd` VARCHAR(255) NOT NULL DEFAULT '';"))
success($locale['step_database_modifying_field'] . ' guilds.motd...');
}
if(!$db->hasColumn('guilds', 'description')) {
if(query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' guilds.description...');
}
if($db->hasColumn('guilds', 'logo_gfx_name')) {
if(query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) {
$tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp);
success($tmp);
if ($db->hasTable('guilds')) {
if ($db->hasColumn('guilds', 'checkdata')) {
if (query("ALTER TABLE `guilds` MODIFY `checkdata` INT NOT NULL DEFAULT 0;"))
success($locale['step_database_modifying_field'] . ' guilds.checkdata...');
}
}
else if(!$db->hasColumn('guilds', 'logo_name')) {
if(query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';"))
success($locale['step_database_adding_field'] . ' guilds.logo_name...');
}
if(!$db->hasColumn('players', 'created')) {
if(query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.created...');
}
if (!$db->hasColumn('guilds', 'motd')) {
if (query("ALTER TABLE `guilds` ADD `motd` VARCHAR(255) NOT NULL DEFAULT '';"))
success($locale['step_database_adding_field'] . ' guilds.motd...');
} else {
if (query("ALTER TABLE `guilds` MODIFY `motd` VARCHAR(255) NOT NULL DEFAULT '';"))
success($locale['step_database_modifying_field'] . ' guilds.motd...');
}
if(!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion')) {
if(query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.deleted...');
}
if (!$db->hasColumn('guilds', 'description')) {
if (query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' guilds.description...');
}
if($db->hasColumn('players', 'hide_char')) {
if(!$db->hasColumn('players', 'hidden')) {
if(query("ALTER TABLE `players` CHANGE `hide_char` `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'players.hidden', $tmp);
if ($db->hasColumn('guilds', 'logo_gfx_name')) {
if (query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) {
$tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp);
success($tmp);
}
} else if (!$db->hasColumn('guilds', 'logo_name')) {
if (query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';"))
success($locale['step_database_adding_field'] . ' guilds.logo_name...');
}
}
else if(!$db->hasColumn('players', 'hidden')) {
if(query("ALTER TABLE `players` ADD `hidden` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.hidden...');
}
if(!$db->hasColumn('players', 'comment')) {
if(query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
if ($db->hasTable('players')) {
if (!$db->hasColumn('players', 'created')) {
if (query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.created...');
}
if($db->hasColumn('players', 'rank_id')) {
if(query("ALTER TABLE players MODIFY `rank_id` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_modifying_field'] . ' players.rank_id...');
if (!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion')) {
if (query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.deleted...');
}
if($db->hasColumn('players', 'guildnick')) {
if(query("ALTER TABLE players MODIFY `guildnick` VARCHAR(255) NOT NULL DEFAULT '';")) {
success($locale['step_database_modifying_field'] . ' players.guildnick...');
if ($db->hasColumn('players', 'hide_char')) {
if (!$db->hasColumn('players', 'hide')) {
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_NEW$', 'players.hide', $tmp);
success($tmp);
}
}
} else if (!$db->hasColumn('players', 'hide')) {
if (query("ALTER TABLE `players` ADD `hide` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.hide...');
}
if (!$db->hasColumn('players', 'comment')) {
if (query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
if ($db->hasColumn('players', 'rank_id')) {
if (query("ALTER TABLE players MODIFY `rank_id` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_modifying_field'] . ' players.rank_id...');
if ($db->hasColumn('players', 'guildnick')) {
if (query("ALTER TABLE players MODIFY `guildnick` VARCHAR(255) NOT NULL DEFAULT '';")) {
success($locale['step_database_modifying_field'] . ' players.guildnick...');
}
}
}
}

View File

@@ -1,6 +1,10 @@
<?php
define('MYAAC_INSTALL', true);
use MyAAC\DataLoader;
use MyAAC\Models\FAQ as ModelsFAQ;
use MyAAC\Plugins;
require_once '../../common.php';
require SYSTEM . 'functions.php';
@@ -8,14 +12,16 @@ require BASE . 'install/includes/functions.php';
require BASE . 'install/includes/locale.php';
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'])) {
warning($locale['already_installed']);
return;
}
}*/
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']));
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;
}
}
@@ -45,19 +51,14 @@ if($success) {
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::load();
// update config.highscores_ids_hidden
require_once SYSTEM . 'migrations/20.php';
$database_migration_20 = true;
$content = '';
if(!databaseMigration20($content)) {
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
warning($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>');
}
// add z_polls tables
require_once SYSTEM . 'migrations/22.php';
@@ -66,6 +67,20 @@ require_once SYSTEM . 'migrations/22.php';
require_once SYSTEM . 'migrations/27.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.',
]);
}
$hooks->trigger(HOOK_INSTALL_FINISH);
$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('$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']);

105
login.php
View File

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

View File

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

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

39
phpstan.neon Normal file
View File

@@ -0,0 +1,39 @@
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\\_]+\(\)#'
- '#Call to an undefined method object::toArray\(\)#'
# 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>
Options -Indexes
</IfModule>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>

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