Compare commits

..

209 Commits

Author SHA1 Message Date
slawkens
c7fdbac537 Merge branch 'develop' into feature/phpstan 2024-02-18 12:12:19 +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
dbae1ccd04 Merge branch 'develop' into feature/phpstan 2024-02-03 21:13:44 +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
18d2c1cce5 Update phpstan.neon 2024-02-01 23:04:54 +01:00
slawkens
b772a828ba Something from level 4 2024-02-01 23:02:45 +01:00
slawkens
7bf9d81af9 Don't ignore templates folder 2024-02-01 23:02:32 +01:00
slawkens
b95ae42ace phpstan level 3 2024-02-01 22:44:58 +01:00
slawkens
765baf248f Move errors ignoring into phpstan.neon 2024-02-01 22:39:48 +01:00
slawkens
42ce80170e phpstan level 2 2024-02-01 21:30:34 +01:00
slawkens
8705d3eedd Merge branch 'develop' into feature/phpstan 2024-02-01 20:48:02 +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
262284fd68 Update phpstan.neon 2024-01-31 00:47:35 +01:00
slawkens
136659ac9a More fixes 2024-01-31 00:45:59 +01:00
slawkens
f93bcb0557 Fix intend 2024-01-31 00:40:35 +01:00
slawkens
c08f099d98 phpstan v1 + workflow 2024-01-31 00:37:29 +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
346 changed files with 4082 additions and 6182 deletions

View File

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

View File

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

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

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

4
.gitignore vendored
View File

@@ -6,15 +6,18 @@ Thumbs.db
/.htaccess /.htaccess
# composer # composer
composer.phar
composer.lock composer.lock
vendor vendor
# npm # npm
node_modules node_modules
tools/ext
# cypress # cypress
cypress.env.json cypress.env.json
cypress/e2e/2-advanced-examples cypress/e2e/2-advanced-examples
cypress/screenshots
# created by release.sh # created by release.sh
releases releases
@@ -47,6 +50,7 @@ system/cache/*
!system/cache/twig/index.html !system/cache/twig/index.html
!system/cache/signatures/index.html !system/cache/signatures/index.html
!system/cache/plugins/index.html !system/cache/plugins/index.html
!system/cache/persistent/index.html
# logs # logs
system/logs/* system/logs/*

View File

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

View File

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

View File

@@ -10,21 +10,20 @@ Official website: https://my-aac.org
[![OpenTibia Discord](https://img.shields.io/discord/288399552581468162)](https://discord.gg/2J39Wus) [![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) [![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 | | Version | Status | Branch | Requirements |
|:-----------|:------------------------------------------|:--------|:---------------| |:--------|:-----------------------|:--------|:---------------|
| **0.10.x** | **Active development** | develop | **PHP >= 8.0** | | **1.x** | **Active development** | develop | **PHP >= 8.1** |
| 0.9.x | Active support | 0.9 | PHP >= 7.2.5 | | 0.9.x | Not developed anymore | 0.9 | PHP >= 7.2.5 |
| 0.8.x | Active support | master | 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 | | 0.7.x | End Of Life | 0.7 | PHP >= 5.3.3 |
### Requirements ### Requirements
- PHP 8.0 or later
- MySQL database - MySQL database
- PDO PHP Extension - PHP Extensions: pdo, xml, json
- XML PHP Extension - (optional) apache2 mod_rewrite (to use friendly_urls)
- (optional) ZIP PHP Extension - (optional) zip PHP Extension (to install plugins)
- (optional) mod_rewrite to use friendly_urls - (optional) gd PHP Extension (for generating signature images)
### Installation ### Installation
@@ -48,7 +47,8 @@ Official website: https://my-aac.org
### Configuration ### Configuration
Check *config.php* to get more informations. Check *config.php* to get more informations. (Notice: MyAAC 1.0+ doesn't use config.php anymore, it has been moved to Admin Panel - Settings page).
Use *config.local.php* for your local configuration changes. Use *config.local.php* for your local configuration changes.
### Branches ### Branches

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

View File

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

View File

@@ -13,6 +13,9 @@ use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Account editor'; $title = 'Account editor';
csrfProtect();
$admin_base = ADMIN_URL . '?p=accounts'; $admin_base = ADMIN_URL . '?p=accounts';
$use_datatable = true; $use_datatable = true;
@@ -82,7 +85,7 @@ else if (isset($_REQUEST['search'])) {
$account = new OTS_Account(); $account = new OTS_Account();
$account->load($id); $account->load($id);
if (isset($account, $_POST['save']) && $account->isLoaded()) { if (isset($_POST['save']) && $account->isLoaded()) {
$error = false; $error = false;
$_error = ''; $_error = '';
@@ -266,6 +269,9 @@ else if (isset($_REQUEST['search'])) {
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a> <a class="nav-link active" id="accounts-acc-tab" data-toggle="pill" href="#accounts-acc">Account</a>
</li> </li>
<li class="nav-item">
<a class="nav-link" id="accounts-logs-tab" data-toggle="pill" href="#accounts-logs">Logs</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a> <a class="nav-link" id="accounts-chars-tab" data-toggle="pill" href="#accounts-chars">Characters</a>
</li> </li>
@@ -285,7 +291,8 @@ else if (isset($_REQUEST['search'])) {
<div class="card-body"> <div class="card-body">
<div class="tab-content" id="accounts-tabContent"> <div class="tab-content" id="accounts-tabContent">
<div class="tab-pane fade active show" id="accounts-acc"> <div class="tab-pane fade active show" id="accounts-acc">
<form action="<?php echo $admin_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post"> <form action="<?php echo $admin_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post">
<?php csrf(); ?>
<div class="form-group row"> <div class="form-group row">
<?php if (USE_ACCOUNT_NAME): ?> <?php if (USE_ACCOUNT_NAME): ?>
<div class="col-12 col-sm-12 col-lg-4"> <div class="col-12 col-sm-12 col-lg-4">
@@ -324,8 +331,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group">Account Type:</label> <label for="group">Account Type:</label>
<select name="group" id="group" class="form-control"> <select name="group" id="group" class="form-control">
<?php foreach ($acc_type as $id => $a_type): ?> <?php foreach ($acc_type as $_id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($acc_group == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($_id); ?>" <?php echo($acc_group == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -335,8 +342,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group">Account Type:</label> <label for="group">Account Type:</label>
<select name="group" id="group" class="form-control"> <select name="group" id="group" class="form-control">
<?php foreach ($groups->getGroups() as $id => $group): ?> <?php foreach ($groups->getGroups() as $_id => $group): ?>
<option value="<?php echo $id; ?>" <?php echo($acc_group == $id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option> <option value="<?php echo $_id; ?>" <?php echo($acc_group == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -344,8 +351,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="web_flags">Website Access:</label> <label for="web_flags">Website Access:</label>
<select name="web_flags" id="web_flags" class="form-control"> <select name="web_flags" id="web_flags" class="form-control">
<?php foreach ($web_acc as $id => $a_type): ?> <?php foreach ($web_acc as $_id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($account->getWebFlags() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($_id); ?>" <?php echo($account->getWebFlags() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -400,8 +407,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="rl_country">Country:</label> <label for="rl_country">Country:</label>
<select name="rl_country" id="rl_country" class="form-control"> <select name="rl_country" id="rl_country" class="form-control">
<?php foreach ($countries as $id => $a_type): ?> <?php foreach ($countries as $_id => $a_type): ?>
<option value="<?php echo($id); ?>" <?php echo($account->getCountry() == ($id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option> <option value="<?php echo($_id); ?>" <?php echo($account->getCountry() == ($_id) ? 'selected' : ''); ?>><?php echo $a_type; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -423,6 +430,34 @@ else if (isset($_REQUEST['search'])) {
<a href="<?php echo ADMIN_URL; ?>?p=accounts" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a> <a href="<?php echo ADMIN_URL; ?>?p=accounts" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</a>
</form> </form>
</div> </div>
<div class="tab-pane fade" id="accounts-logs">
<div class="row">
<table class="table table-striped table-condensed table-responsive d-md-table">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Action</th>
<th>IP</th>
</tr>
</thead>
<tbody>
<?php
$accountActions = \MyAAC\Models\AccountAction::where('account_id', $account->getId())->orderByDesc('date')->get();
foreach ($accountActions as $i => $log):
$log->ip = ($log->ip != 0 ? long2ip($log->ip) : inet_ntop($log->ipv6));
?>
<tr>
<td><?php echo $i + 1; ?></td>
<td><?= date("M d Y, H:i:s", $log->date); ?></td>
<td><?= $log->action; ?></td>
<td><?= $log->ip; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="tab-pane fade" id="accounts-chars"> <div class="tab-pane fade" id="accounts-chars">
<div class="row"> <div class="row">
<?php <?php
@@ -550,18 +585,20 @@ else if (isset($_REQUEST['search'])) {
<div class="row"> <div class="row">
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post"> <form action="<?php echo $admin_base; ?>" method="post">
<label for="name">Account Name:</label> <?php csrf(); ?>
<label for="search">Account Name:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" name="search" value="<?php echo $search_account; ?>" maxlength="32" size="32"> <input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_account); ?>" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>
</div> </div>
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post"> <form action="<?php echo $admin_base; ?>" method="post">
<label for="name">Account ID:</label> <?php csrf(); ?>
<label for="id">Account ID:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" name="id" value="" maxlength="32" size="32"> <input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,8 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mailer'; $title = 'Mailer';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
@@ -20,7 +22,7 @@ if (!setting('core.mail_enabled')) {
return; return;
} }
$mail_to = isset($_REQUEST['mail_to']) ? stripslashes(trim($_REQUEST['mail_to'])) : null; $mail_to = isset($_POST['mail_to']) ? stripslashes(trim($_POST['mail_to'])) : null;
$mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null; $mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null;
$mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null; $mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null;

View File

@@ -16,6 +16,8 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Account Actions'; $title = 'Mass Account Actions';
csrfProtect();
$hasCoinsColumn = $db->hasColumn('accounts', 'coins'); $hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); $hasPointsColumn = $db->hasColumn('accounts', 'premium_points');
$freePremium = $config['lua']['freePremium']; $freePremium = $config['lua']['freePremium'];
@@ -160,9 +162,9 @@ function admin_give_premdays($days)
displayMessage('Premium Days not supported.'); displayMessage('Premium Days not supported.');
} }
if (isset($_POST['action']) && $_POST['action']) { if (!empty(ACTION) && isRequestMethod('post')) {
$action = $_POST['action']; $action = ACTION;
if (preg_match("/[^A-z0-9_\-]/", $action)) { if (preg_match("/[^A-z0-9_\-]/", $action)) {
displayMessage('Invalid action.'); displayMessage('Invalid action.');

View File

@@ -16,6 +16,8 @@ defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mass Teleport Actions'; $title = 'Mass Teleport Actions';
csrfProtect();
function admin_teleport_position($x, $y, $z) { function admin_teleport_position($x, $y, $z) {
if (!Player::query()->update([ if (!Player::query()->update([
'posx' => $x, 'posy' => $y, 'posz' => $z 'posx' => $x, 'posy' => $y, 'posz' => $z
@@ -38,9 +40,9 @@ function admin_teleport_town($town_id) {
displayMessage('Player\'s town updated.', true); displayMessage('Player\'s town updated.', true);
} }
if (isset($_POST['action']) && $_POST['action']) { if (!empty(ACTION) && isRequestMethod('post')) {
$action = $_POST['action']; $action = ACTION;
if (preg_match("/[^A-z0-9_\-]/", $action)) { if (preg_match("/[^A-z0-9_\-]/", $action)) {
displayMessage('Invalid action.'); displayMessage('Invalid action.');

View File

@@ -8,24 +8,27 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Cache\Cache;
use MyAAC\Models\Menu; use MyAAC\Models\Menu;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Menus'; $title = 'Menus';
csrfProtect();
if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
} }
if (isset($_REQUEST['template'])) { if (isset($_POST['template'])) {
$template = $_REQUEST['template']; $template = $_POST['template'];
if (isset($_REQUEST['menu'])) { if (isset($_POST['menu'])) {
$post_menu = $_REQUEST['menu']; $post_menu = $_POST['menu'];
$post_menu_link = $_REQUEST['menu_link']; $post_menu_link = $_POST['menu_link'];
$post_menu_blank = $_REQUEST['menu_blank']; $post_menu_blank = $_POST['menu_blank'];
$post_menu_color = $_REQUEST['menu_color']; $post_menu_color = $_POST['menu_color'];
if (count($post_menu) != count($post_menu_link)) { if (count($post_menu) != count($post_menu_link)) {
echo 'Menu count is not equal menu links. Something went wrong when sending form.'; echo 'Menu count is not equal menu links. Something went wrong when sending form.';
return; return;
@@ -69,9 +72,10 @@ if (isset($_REQUEST['template'])) {
return; return;
} }
if (isset($_REQUEST['reset_colors'])) { if (isset($_GET['reset_colors'])) {
if (isset($config['menu_default_color'])) { if (isset($config['menu_default_color'])) {
Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]); Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]);
success('Colors has been reset.');
} }
else { else {
warning('There is no default color defined, cannot reset colors.'); warning('There is no default color defined, cannot reset colors.');
@@ -93,6 +97,7 @@ if (isset($_REQUEST['template'])) {
</p> </p>
<?php if (isset($config['menu_default_color'])) {?> <?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?');"> <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 ?>"/> <input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-danger">Reset Colors to default</button> <button type="submit" class="btn btn-danger">Reset Colors to default</button>
</form> </form>
@@ -112,6 +117,7 @@ if (isset($_REQUEST['template'])) {
$last_id = array(); $last_id = array();
?> ?>
<form method="post" id="menus-form" action="?p=menus"> <form method="post" id="menus-form" action="?p=menus">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/> <input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-info">Save</button><br/><br/> <button type="submit" class="btn btn-info">Save</button><br/><br/>
<div class="row"> <div class="row">

View File

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

View File

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

View File

@@ -13,8 +13,10 @@ use MyAAC\Models\Notepad as ModelsNotepad;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Notepad'; $title = 'Notepad';
csrfProtect();
/** /**
* @var $account_logged OTS_Account * @var OTS_Account $account_logged
*/ */
$_content = ''; $_content = '';
$notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first(); $notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first();

View File

@@ -9,11 +9,14 @@
*/ */
use MyAAC\Models\Pages as ModelsPages; use MyAAC\Models\Pages as ModelsPages;
use MyAAC\Admin\Pages;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Pages'; $title = 'Pages';
$use_datatable = true; $use_datatable = true;
csrfProtect();
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
@@ -29,31 +32,36 @@ $enable_tinymce = true;
$access = 0; $access = 0;
// some constants, used mainly by database (cannot by modified without schema changes) // some constants, used mainly by database (cannot by modified without schema changes)
define('PAGE_TITLE_LIMIT', 30); const PAGE_TITLE_LIMIT = 30;
define('PAGE_NAME_LIMIT', 30); const PAGE_NAME_LIMIT = 30;
define('PAGE_BODY_LIMIT', 65535); // maximum page body length const PAGE_BODY_LIMIT = 65535; // maximum page body length
if (!empty($action)) { if (!empty($action) && isRequestMethod('post')) {
if ($action == 'delete' || $action == 'edit' || $action == 'hide') if ($action == 'delete' || $action == 'edit' || $action == 'hide') {
$id = $_REQUEST['id']; $id = $_POST['id'];
if (isset($_REQUEST['name']))
$name = $_REQUEST['name'];
if (isset($_REQUEST['title']))
$p_title = $_REQUEST['title'];
$php = isset($_REQUEST['php']) && $_REQUEST['php'] == 1;
$enable_tinymce = isset($_REQUEST['enable_tinymce']) && $_REQUEST['enable_tinymce'] == 1;
if ($php)
$body = $_REQUEST['body'];
else if (isset($_REQUEST['body'])) {
//$body = $_REQUEST['body'];
$body = html_entity_decode(stripslashes($_REQUEST['body']));
} }
if (isset($_REQUEST['access'])) if (isset($_POST['name'])) {
$access = $_REQUEST['access']; $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(); $errors = array();
$player_id = 1; $player_id = 1;
@@ -70,7 +78,7 @@ if (!empty($action)) {
if (Pages::delete($id, $errors)) if (Pages::delete($id, $errors))
success('Page with id ' . $id . ' has been deleted'); success('Page with id ' . $id . ' has been deleted');
} else if ($action == 'edit') { } else if ($action == 'edit') {
if (isset($id) && !isset($_REQUEST['name'])) { if (isset($id) && !isset($_POST['name'])) {
$_page = Pages::get($id); $_page = Pages::get($id);
$name = $_page['name']; $name = $_page['name'];
$p_title = $_page['title']; $p_title = $_page['title'];
@@ -89,8 +97,9 @@ if (!empty($action)) {
} }
} }
} else if ($action == 'hide') { } else if ($action == 'hide') {
Pages::toggleHidden($id, $errors, $status); if (Pages::toggleHide($id, $errors, $status)) {
success(($status == 1 ? 'Show' : 'Hide') . ' successful.'); success(($status == 0 ? 'Show' : 'Hide') . ' successful.');
}
} }
if (!empty($errors)) if (!empty($errors))
@@ -103,11 +112,11 @@ $pages = ModelsPages::all()->map(function ($e) {
'title' => substr($e->title, 0, 20), 'title' => substr($e->title, 0, 20),
'php' => $e->php == '1', 'php' => $e->php == '1',
'id' => $e->id, 'id' => $e->id,
'hidden' => $e->hidden 'hide' => $e->hide
]; ];
})->toArray(); })->toArray();
$twig->display('admin.pages.form.html.twig', array( $twig->display('admin.pages.form.html.twig', [
'action' => $action, 'action' => $action,
'id' => $action == 'edit' ? $id : null, 'id' => $action == 'edit' ? $id : null,
'name' => $name, 'name' => $name,
@@ -117,136 +126,8 @@ $twig->display('admin.pages.form.html.twig', array(
'body' => isset($body) ? escapeHtml($body) : '', 'body' => isset($body) ? escapeHtml($body) : '',
'groups' => $groups->getGroups(), 'groups' => $groups->getGroups(),
'access' => $access 'access' => $access
)); ]);
$twig->display('admin.pages.html.twig', array( $twig->display('admin.pages.html.twig', [
'pages' => $pages 'pages' => $pages
)); ]);
class Pages
{
static public function verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors)
{
if(!isset($title[0]) || !isset($body[0])) {
$errors[] = 'Please fill all inputs.';
return false;
}
if(strlen($name) > PAGE_NAME_LIMIT) {
$errors[] = 'Page name cannot be longer than ' . PAGE_NAME_LIMIT . ' characters.';
return false;
}
if(strlen($title) > PAGE_TITLE_LIMIT) {
$errors[] = 'Page title cannot be longer than ' . PAGE_TITLE_LIMIT . ' characters.';
return false;
}
if(strlen($body) > PAGE_BODY_LIMIT) {
$errors[] = 'Page content cannot be longer than ' . PAGE_BODY_LIMIT . ' characters.';
return false;
}
if(!isset($player_id) || $player_id == 0) {
$errors[] = 'Player ID is wrong.';
return false;
}
if(!isset($php) || ($php != 0 && $php != 1)) {
$errors[] = 'Enable PHP is wrong.';
return false;
}
if ($php == 1 && !getBoolean(setting('core.admin_pages_php_enable'))) {
$errors[] = 'PHP pages disabled on this server. To enable go to Settings in Admin Panel and enable <strong>Enable PHP Pages</strong>.';
return false;
}
if(!isset($enable_tinymce) || ($enable_tinymce != 0 && $enable_tinymce != 1)) {
$errors[] = 'Enable TinyMCE is wrong.';
return false;
}
if(!isset($access) || $access < 0 || $access > PHP_INT_MAX) {
$errors[] = 'Access is wrong.';
return false;
}
return true;
}
static public function get($id)
{
$row = ModelsPages::find($id);
if ($row) {
return $row->toArray();
}
return false;
}
static public function add($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors)
{
if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
return false;
}
if (!ModelsPages::where('name', $name)->exists())
ModelsPages::create([
'name' => $name,
'title' => $title,
'body' => $body,
'player_id' => $player_id,
'php' => $php ? '1' : '0',
'enable_tinymce' => $enable_tinymce ? '1' : '0',
'access' => $access
]);
else
$errors[] = 'Page with this link already exists.';
return !count($errors);
}
static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors)
{
if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) {
return false;
}
ModelsPages::where('id', $id)->update([
'name' => $name,
'title' => $title,
'body' => $body,
'player_id' => $player_id,
'php' => $php ? '1' : '0',
'enable_tinymce' => $enable_tinymce ? '1' : '0',
'access' => $access
]);
return true;
}
static public function delete($id, &$errors)
{
if (isset($id)) {
$row = ModelsPages::find($id);
if ($row) {
$row->delete();
}
else
$errors[] = 'Page with id ' . $id . ' does not exists.';
} else
$errors[] = 'id not set';
return !count($errors);
}
static public function toggleHidden($id, &$errors, &$status)
{
if (isset($id)) {
$row = ModelsPages::find($id);
if ($row) {
$row->hidden = $row->hidden == 1 ? 0 : 1;
$row->save();
$status = $row->hidden;
}
else {
$errors[] = 'Page with id ' . $id . ' does not exists.';
}
} else
$errors[] = 'id not set';
return !count($errors);
}
}

View File

@@ -8,15 +8,18 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Forum;
use MyAAC\Models\Player; use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Player editor'; $title = 'Player editor';
csrfProtect();
$player_base = ADMIN_URL . '?p=players'; $player_base = ADMIN_URL . '?p=players';
$use_datatable = true; $use_datatable = true;
require_once LIBS . 'forum.php';
$skills = array( $skills = array(
POT::SKILL_FIST => array('Fist fighting', 'fist'), POT::SKILL_FIST => array('Fist fighting', 'fist'),
@@ -75,7 +78,7 @@ else if (isset($_REQUEST['search'])) {
$player = new OTS_Player(); $player = new OTS_Player();
$player->load($id); $player->load($id);
if (isset($player) && $player->isLoaded() && isset($_POST['save'])) {// we want to save if ($player->isLoaded() && isset($_POST['save'])) {// we want to save
$error = false; $error = false;
if ($player->isOnline()) if ($player->isOnline())
@@ -210,7 +213,7 @@ else if (isset($_REQUEST['search'])) {
} }
$deleted = (isset($_POST['deleted']) && $_POST['deleted'] == 'true'); $deleted = (isset($_POST['deleted']) && $_POST['deleted'] == 'true');
$hidden = (isset($_POST['hidden']) && $_POST['hidden'] == 'true'); $hide = (isset($_POST['hide']) && $_POST['hide'] == 'true');
$created = strtotime($_POST['created']); $created = strtotime($_POST['created']);
verify_number($created, 'Created', 11); verify_number($created, 'Created', 11);
@@ -287,7 +290,7 @@ else if (isset($_REQUEST['search'])) {
$player->setCustomField('deletion', $deleted ? '1' : '0'); $player->setCustomField('deletion', $deleted ? '1' : '0');
else else
$player->setCustomField('deleted', $deleted ? '1' : '0'); $player->setCustomField('deleted', $deleted ? '1' : '0');
$player->setCustomField('hidden', $hidden ? '1' : '0'); $player->setCustomField('hide', $hide ? '1' : '0');
$player->setCustomField('created', $created); $player->setCustomField('created', $created);
if (isset($comment)) if (isset($comment))
$player->setCustomField('comment', $comment); $player->setCustomField('comment', $comment);
@@ -372,7 +375,8 @@ else if (isset($_REQUEST['search'])) {
</li> </li>
</ul> </ul>
</div> </div>
<form action="<?php echo $player_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post"> <form action="<?php echo $player_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post">
<?php csrf(); ?>
<div class="card-body"> <div class="card-body">
<div class="tab-content" id="tabs-tabContent"> <div class="tab-content" id="tabs-tabContent">
<div class="tab-pane fade active show" id="tabs-home"> <div class="tab-pane fade active show" id="tabs-home">
@@ -390,8 +394,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="group">Group:</label> <label for="group">Group:</label>
<select name="group" id="group" class="form-control custom-select"> <select name="group" id="group" class="form-control custom-select">
<?php foreach ($groups->getGroups() as $id => $group): ?> <?php foreach ($groups->getGroups() as $_id => $group): ?>
<option value="<?php echo $id; ?>" <?php echo($player->getGroup()->getId() == $id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option> <option value="<?php echo $_id; ?>" <?php echo($player->getGroup()->getId() == $_id ? 'selected' : ''); ?>><?php echo $group->getName(); ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -399,8 +403,8 @@ else if (isset($_REQUEST['search'])) {
<label for="vocation">Vocation</label> <label for="vocation">Vocation</label>
<select name="vocation" id="vocation" class="form-control custom-select"> <select name="vocation" id="vocation" class="form-control custom-select">
<?php <?php
foreach ($config['vocations'] as $id => $name) { foreach ($config['vocations'] as $_id => $name) {
echo '<option value=' . $id . ($id == $player->getVocation() ? ' selected' : '') . '>' . $name . '</option>'; echo '<option value=' . $_id . ($_id == $player->getVocation() ? ' selected' : '') . '>' . $name . '</option>';
} }
?> ?>
</select> </select>
@@ -410,8 +414,8 @@ else if (isset($_REQUEST['search'])) {
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<label for="sex">Sex:</label> <label for="sex">Sex:</label>
<select name="sex" id="sex" class="form-control custom-select">> <select name="sex" id="sex" class="form-control custom-select">>
<?php foreach ($config['genders'] as $id => $sex): ?> <?php foreach ($config['genders'] as $_id => $sex): ?>
<option value="<?php echo $id; ?>" <?php echo($player->getSex() == $id ? 'selected' : ''); ?>><?php echo strtolower($sex); ?></option> <option value="<?php echo $_id; ?>" <?php echo($player->getSex() == $_id ? 'selected' : ''); ?>><?php echo strtolower($sex); ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -424,8 +428,8 @@ else if (isset($_REQUEST['search'])) {
$configTowns[$player->getTownId()] = 'Unknown Town'; $configTowns[$player->getTownId()] = 'Unknown Town';
} }
foreach ($configTowns as $id => $town): ?> foreach ($configTowns as $_id => $town): ?>
<option value="<?php echo $id; ?>" <?php echo($player->getTownId() == $id ? 'selected' : ''); ?>><?php echo $town; ?></option> <option value="<?php echo $_id; ?>" <?php echo($player->getTownId() == $_id ? 'selected' : ''); ?>><?php echo $town; ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
@@ -436,8 +440,8 @@ else if (isset($_REQUEST['search'])) {
<select name="skull" id="skull" class="form-control custom-select"> <select name="skull" id="skull" class="form-control custom-select">
<?php <?php
foreach ($skull_type as $id => $s_name) { foreach ($skull_type as $_id => $s_name) {
echo '<option value=' . $id . ($id == $player->getSkull() ? ' selected' : '') . '>' . $s_name . '</option>'; echo '<option value=' . $_id . ($_id == $player->getSkull() ? ' selected' : '') . '>' . $s_name . '</option>';
} }
?> ?>
</select> </select>
@@ -481,8 +485,8 @@ else if (isset($_REQUEST['search'])) {
</div> </div>
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<div class="custom-control custom-switch custom-switch-on-success"> <div class="custom-control custom-switch custom-switch-on-success">
<input type="checkbox" class="custom-control-input" name="hidden" id="hidden" value="true" <?php echo($player->isHidden() ? ' checked' : ''); ?>> <input type="checkbox" class="custom-control-input" name="hide" id="hide" value="true" <?php echo($player->isHidden() ? ' checked' : ''); ?>>
<label class="custom-control-label" for="hidden">Hidden</label> <label class="custom-control-label" for="hide">Hidden</label>
</div> </div>
</div> </div>
</div> </div>
@@ -554,16 +558,16 @@ else if (isset($_REQUEST['search'])) {
</div> </div>
<div class="tab-pane fade" id="tabs-skills"> <div class="tab-pane fade" id="tabs-skills">
<?php <?php
foreach ($skills as $id => $info) { foreach ($skills as $_id => $info) {
?> ?>
<div class="form-group row"> <div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<?php echo '<label for="skills[' . $id . ']" class="control-label">' . $info[0] . '</label> <?php echo '<label for="skills[' . $_id . ']" class="control-label">' . $info[0] . '</label>
<input type="text" class="form-control" id="skills[' . $id . ']" name="skills[' . $id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkill($id) . '"/>'; ?> <input type="text" class="form-control" id="skills[' . $_id . ']" name="skills[' . $_id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkill($_id) . '"/>'; ?>
</div> </div>
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
<?php echo '<label for="skills_tries[' . $id . ']" class="control-label">' . $info[0] . ' tries</label> <?php echo '<label for="skills_tries[' . $_id . ']" class="control-label">' . $info[0] . ' tries</label>
<input type="text" class="form-control" id="skills_tries[' . $id . ']" name="skills_tries[' . $id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkillTries($id) . '"/>'; ?> <input type="text" class="form-control" id="skills_tries[' . $_id . ']" name="skills_tries[' . $_id . ']" maxlength="10" autocomplete="off" value="' . $player->getSkillTries($_id) . '"/>'; ?>
</div> </div>
</div> </div>
<?php } ?> <?php } ?>
@@ -622,7 +626,7 @@ else if (isset($_REQUEST['search'])) {
if ($outfitlist) { ?> if ($outfitlist) { ?>
<select name="look_type" id="look_type" class="form-control custom-select"> <select name="look_type" id="look_type" class="form-control custom-select">
<?php <?php
foreach ($outfitlist as $id => $outfit) { foreach ($outfitlist as $_id => $outfit) {
if ($outfit['enabled'] == 'yes') ; if ($outfit['enabled'] == 'yes') ;
echo '<option value=' . $outfit['id'] . ($outfit['id'] == $player->getLookType() ? ' selected' : '') . '>' . $outfit['name'] . ' - ' . ($outfit['type'] == 1 ? 'Male' : 'Female') . '</option>'; echo '<option value=' . $outfit['id'] . ($outfit['id'] == $player->getLookType() ? ' selected' : '') . '>' . $outfit['name'] . ' - ' . ($outfit['type'] == 1 ? 'Male' : 'Female') . '</option>';
} }
@@ -638,8 +642,8 @@ else if (isset($_REQUEST['search'])) {
<select name="look_addons" id="look_addons" class="form-control custom-select"> <select name="look_addons" id="look_addons" class="form-control custom-select">
<?php <?php
$addon_type = array("None", "First", "Second", "Both"); $addon_type = array("None", "First", "Second", "Both");
foreach ($addon_type as $id => $s_name) { foreach ($addon_type as $_id => $s_name) {
echo '<option value=' . $id . ($id == $player->getLookAddons() ? ' selected' : '') . '>' . $s_name . '</option>'; echo '<option value=' . $_id . ($_id == $player->getLookAddons() ? ' selected' : '') . '>' . $s_name . '</option>';
} }
?> ?>
</select> </select>
@@ -704,7 +708,7 @@ else if (isset($_REQUEST['search'])) {
<div class="form-group row"> <div class="form-group row">
<div class="col-12"> <div class="col-12">
<label for="comment" class="control-label">Comment:</label> <label for="comment" class="control-label">Comment:</label>
<textarea class="form-control" name="comment" rows="10" cols="50" wrap="virtual"><?php echo $player->getCustomField("comment"); ?></textarea> <textarea class="form-control" id="comment" name="comment" rows="10" cols="50" wrap="virtual"><?php echo $player->getCustomField("comment"); ?></textarea>
<small>[max. length: 2000 chars, 50 lines (ENTERs)]</small> <small>[max. length: 2000 chars, 50 lines (ENTERs)]</small>
</div> </div>
</div> </div>
@@ -841,7 +845,7 @@ else if (isset($_REQUEST['search'])) {
<?php if($hasLookAddons): ?> <?php if($hasLookAddons): ?>
const $addonvalue = $('#look_addons'); const $addonvalue = $('#look_addons');
$('#look_addons').on('change', () => { $addonvalue.on('change', () => {
updateOutfit(); updateOutfit();
}); });
<?php endif; ?> <?php endif; ?>
@@ -870,18 +874,20 @@ else if (isset($_REQUEST['search'])) {
<div class="card-body row"> <div class="card-body row">
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $player_base; ?>" method="post"> <form action="<?php echo $player_base; ?>" method="post">
<label for="name">Player Name:</label> <?php csrf(); ?>
<label for="search">Player Name:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" name="search" value="<?php echo $search_player; ?>" maxlength="32" size="32"> <input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_player); ?>" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>
</div> </div>
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $player_base; ?>" method="post"> <form action="<?php echo $player_base; ?>" method="post">
<label for="name">Player ID:</label> <?php csrf(); ?>
<label for="id">Player ID:</label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" name="id" value="" maxlength="32" size="32"> <input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span> <span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div> </div>
</form> </form>
@@ -892,7 +898,7 @@ else if (isset($_REQUEST['search'])) {
</div> </div>
<script> <script>
$(document).ready(function () { $(function () {
$('.player_datatable').DataTable({ $('.player_datatable').DataTable({
"order": [[0, "asc"]] "order": [[0, "asc"]]
}); });

View File

@@ -7,11 +7,15 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Plugins;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Plugin manager'; $title = 'Plugin manager';
$use_datatable = true;
require_once LIBS . 'plugins.php'; csrfProtect();
$use_datatable = true;
if (!getBoolean(setting('core.admin_plugins_manage_enable'))) { if (!getBoolean(setting('core.admin_plugins_manage_enable'))) {
warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.'); warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.');
@@ -19,23 +23,23 @@ if (!getBoolean(setting('core.admin_plugins_manage_enable'))) {
else { else {
$twig->display('admin.plugins.form.html.twig'); $twig->display('admin.plugins.form.html.twig');
if (isset($_REQUEST['uninstall'])) { if (isset($_POST['uninstall'])) {
$uninstall = $_REQUEST['uninstall']; $uninstall = $_POST['uninstall'];
if (Plugins::uninstall($uninstall)) { if (Plugins::uninstall($uninstall)) {
success('Successfully uninstalled plugin ' . $uninstall); success('Successfully uninstalled plugin ' . $uninstall);
} else { } else {
error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError());
} }
} else if (isset($_REQUEST['enable'])) { } else if (isset($_POST['enable'])) {
$enable = $_REQUEST['enable']; $enable = $_POST['enable'];
if (Plugins::enable($enable)) { if (Plugins::enable($enable)) {
success('Successfully enabled plugin ' . $enable); success('Successfully enabled plugin ' . $enable);
} else { } else {
error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError()); error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError());
} }
} else if (isset($_REQUEST['disable'])) { } else if (isset($_POST['disable'])) {
$disable = $_REQUEST['disable']; $disable = $_POST['disable'];
if (Plugins::disable($disable)) { if (Plugins::disable($disable)) {
success('Successfully disabled plugin ' . $disable); success('Successfully disabled plugin ' . $disable);
} else { } else {
@@ -116,7 +120,7 @@ foreach (get_plugins(true) as $plugin) {
if (!$plugin_info) { if (!$plugin_info) {
warning('Cannot load plugin info ' . $plugin . '.json'); warning('Cannot load plugin info ' . $plugin . '.json');
} else { } else {
$disabled = (strpos($plugin, 'disabled.') !== false); $disabled = (str_contains($plugin, 'disabled.'));
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin); $pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
$plugins[] = array( $plugins[] = array(
'name' => $plugin_info['name'] ?? '', 'name' => $plugin_info['name'] ?? '',

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,7 @@
<?php echo template_header(true); ?> <?php echo template_header(true); ?>
<title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title> <title><?php echo (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];?></title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/adminlte.min.css"> <link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/ext/admin-lte/css/adminlte.min.css">
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/font-awesome.min.css"> <link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/font-awesome.min.css">
<?php if (isset($use_datatable)) { ?> <?php if (isset($use_datatable)) { ?>
<link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/datatables.bs.min.css"> <link rel="stylesheet" href="<?php echo BASE_URL; ?>tools/css/datatables.bs.min.css">
@@ -191,13 +191,13 @@ if ($logged && admin()) {
]); ]);
} }
?> ?>
<script src="<?php echo BASE_URL; ?>tools/js/bootstrap.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/ext/bootstrap/js/bootstrap.min.js"></script>
<script src="<?php echo BASE_URL; ?>tools/js/jquery-ui.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/ext/jquery-ui/jquery-ui.min.js"></script>
<?php if (isset($use_datatable)) { ?> <?php if (isset($use_datatable)) { ?>
<script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/datatables.min.js"></script>
<script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/js/datatables.bs.min.js"></script>
<?php } ?> <?php } ?>
<script src="<?php echo BASE_URL; ?>tools/js/adminlte.min.js"></script> <script src="<?php echo BASE_URL; ?>tools/ext/admin-lte/js/adminlte.min.js"></script>
<?php $hooks->trigger(HOOK_ADMIN_BODY_END); ?> <?php $hooks->trigger(HOOK_ADMIN_BODY_END); ?>
</body> </body>
</html> </html>

View File

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

View File

@@ -1,4 +1,8 @@
<?php <?php
use MyAAC\Hooks;
use MyAAC\Settings;
const MYAAC_ADMIN = true; const MYAAC_ADMIN = true;
require '../../common.php'; require '../../common.php';
@@ -6,16 +10,13 @@ require SYSTEM . 'functions.php';
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';
require SYSTEM . 'login.php'; require SYSTEM . 'login.php';
// event system
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
if(!admin()) { if(!admin()) {
http_response_code(500); http_response_code(500);
die('Access denied.'); die('Access denied.');
} }
csrfProtect();
if (!isset($_REQUEST['plugin'])) { if (!isset($_REQUEST['plugin'])) {
http_response_code(500); http_response_code(500);
die('Please enter plugin name.'); die('Please enter plugin name.');

View File

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

View File

@@ -13,14 +13,19 @@
"nikic/fast-route": "^1.3", "nikic/fast-route": "^1.3",
"matomo/device-detector": "^6.0", "matomo/device-detector": "^6.0",
"illuminate/database": "^10.18", "illuminate/database": "^10.18",
"peppeocchi/php-cron-scheduler": "4.*" "peppeocchi/php-cron-scheduler": "4.*",
"symfony/console": "^6.4",
"symfony/string": "^6.4"
}, },
"require-dev": { "require-dev": {
"filp/whoops": "^2.15" "filp/whoops": "^2.15",
"maximebf/debugbar": "dev-master",
"phpstan/phpstan": "^1.10"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"MyAAC\\": "system/src" "MyAAC\\": "system/src"
} },
"files": ["system/src/global.php"]
} }
} }

View File

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

View File

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

View File

@@ -82,7 +82,7 @@ describe('Check Public Pages', () => {
it('Go to last kills page', () => { it('Go to last kills page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/lastkills', url: Cypress.env('URL') + '/last-kills',
method: 'GET', method: 'GET',
}) })
}) })
@@ -132,7 +132,7 @@ describe('Check Public Pages', () => {
it('Go to server info page', () => { it('Go to server info page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/serverInfo', url: Cypress.env('URL') + '/server-info',
method: 'GET', method: 'GET',
}) })
}) })
@@ -160,7 +160,7 @@ describe('Check Public Pages', () => {
it('Go to experience table page', () => { it('Go to experience table page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/experienceTable', url: Cypress.env('URL') + '/exp-table',
method: 'GET', method: 'GET',
}) })
}) })

106
index.php
View File

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

View File

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

View File

@@ -1,4 +1,4 @@
SET @myaac_database_version = 36; SET @myaac_database_version = 40;
CREATE TABLE `myaac_account_actions` CREATE TABLE `myaac_account_actions`
( (
@@ -44,11 +44,11 @@ CREATE TABLE `myaac_changelog`
`where` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - server, 2 - site', `where` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - server, 2 - site',
`date` INT(11) NOT NULL DEFAULT 0, `date` INT(11) NOT NULL DEFAULT 0,
`player_id` INT(11) NOT NULL DEFAULT 0, `player_id` INT(11) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
INSERT INTO `myaac_changelog` (`id`, `type`, `where`, `date`, `body`, `hidden`) VALUES (1, 3, 2, UNIX_TIMESTAMP(), 'MyAAC installed. (:', 0); INSERT INTO `myaac_changelog` (`id`, `type`, `where`, `date`, `body`, `hide`) VALUES (1, 3, 2, UNIX_TIMESTAMP(), 'MyAAC installed. (:', 0);
CREATE TABLE `myaac_config` CREATE TABLE `myaac_config`
( (
@@ -67,7 +67,7 @@ CREATE TABLE `myaac_faq`
`question` VARCHAR(255) NOT NULL DEFAULT '', `question` VARCHAR(255) NOT NULL DEFAULT '',
`answer` VARCHAR(1020) NOT NULL DEFAULT '', `answer` VARCHAR(1020) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` INT(11) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -80,7 +80,7 @@ CREATE TABLE `myaac_forum_boards`
`guild` INT(11) NOT NULL DEFAULT 0, `guild` INT(11) NOT NULL DEFAULT 0,
`access` INT(11) NOT NULL DEFAULT 0, `access` INT(11) NOT NULL DEFAULT 0,
`closed` TINYINT(1) NOT NULL DEFAULT 0, `closed` TINYINT(1) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`, `closed`) VALUES (NULL, 'News', 'News commenting', 0, 1); INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`, `closed`) VALUES (NULL, 'News', 'News commenting', 0, 1);
@@ -127,14 +127,9 @@ CREATE TABLE `myaac_menu`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
/* MENU_CATEGORY_SHOP tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop Offer', 'gifts', 6, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop History', 'gifts/history', 6, 2);
CREATE TABLE `myaac_monsters` ( CREATE TABLE `myaac_monsters` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`hidden` tinyint(1) NOT NULL default 0, `hide` tinyint(1) NOT NULL default 0,
`name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL,
`mana` int(11) NOT NULL DEFAULT 0, `mana` int(11) NOT NULL DEFAULT 0,
`exp` int(11) NOT NULL, `exp` int(11) NOT NULL,
@@ -179,7 +174,7 @@ CREATE TABLE `myaac_news`
`comments` VARCHAR(50) NOT NULL DEFAULT '', `comments` VARCHAR(50) NOT NULL DEFAULT '',
`article_text` VARCHAR(300) NOT NULL DEFAULT '', `article_text` VARCHAR(300) NOT NULL DEFAULT '',
`article_image` VARCHAR(100) NOT NULL DEFAULT '', `article_image` VARCHAR(100) NOT NULL DEFAULT '',
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -189,7 +184,7 @@ CREATE TABLE `myaac_news_categories`
`name` VARCHAR(50) NOT NULL DEFAULT "", `name` VARCHAR(50) NOT NULL DEFAULT "",
`description` VARCHAR(50) NOT NULL DEFAULT "", `description` VARCHAR(50) NOT NULL DEFAULT "",
`icon_id` INT(2) NOT NULL DEFAULT 0, `icon_id` INT(2) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -220,7 +215,7 @@ CREATE TABLE `myaac_pages`
`php` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 - plain html, 1 - php', `php` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 - plain html, 1 - php',
`enable_tinymce` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 - enabled, 0 - disabled', `enable_tinymce` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 - enabled, 0 - disabled',
`access` TINYINT(2) NOT NULL DEFAULT 0, `access` TINYINT(2) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE (`name`) UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -233,7 +228,7 @@ CREATE TABLE `myaac_gallery`
`thumb` VARCHAR(255) NOT NULL, `thumb` VARCHAR(255) NOT NULL,
`author` VARCHAR(50) NOT NULL DEFAULT '', `author` VARCHAR(50) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` INT(11) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
@@ -267,7 +262,7 @@ CREATE TABLE `myaac_spells`
`item_id` INT(11) NOT NULL DEFAULT 0, `item_id` INT(11) NOT NULL DEFAULT 0,
`premium` TINYINT(1) NOT NULL DEFAULT 0, `premium` TINYINT(1) NOT NULL DEFAULT 0,
`vocations` VARCHAR(100) NOT NULL DEFAULT '', `vocations` VARCHAR(100) NOT NULL DEFAULT '',
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE (`name`) UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;

View File

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

View File

@@ -1,4 +1,7 @@
<?php <?php
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
//ini_set('display_errors', false); //ini_set('display_errors', false);

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,6 +2,8 @@
use MyAAC\Models\BoostedCreature; use MyAAC\Models\BoostedCreature;
use MyAAC\Models\PlayerOnline; use MyAAC\Models\PlayerOnline;
use MyAAC\Models\Account;
use MyAAC\Models\Player;
require_once 'common.php'; require_once 'common.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';

View File

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

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

433
package-lock.json generated
View File

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

View File

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

13
phpstan-bootstrap.php Normal file
View File

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

38
phpstan.neon Normal file
View File

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

View File

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

View File

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

View File

@@ -1,19 +0,0 @@
<?php
require_once __DIR__ . '/../../common.php';
require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php';
require_once SYSTEM . 'hooks.php';
$hooks = new Hooks();
$hooks->load();
use GO\Scheduler;
// Create a new scheduler
$scheduler = new Scheduler();
$hooks->trigger(HOOK_CRONJOB, ['scheduler' => $scheduler]);
// Let the scheduler execute jobs which are due.
$scheduler->run();

View File

@@ -1,50 +0,0 @@
<?php
require_once __DIR__ . '/../../common.php';
require_once SYSTEM . 'functions.php';
require_once SYSTEM . 'init.php';
if(!IS_CLI) {
echo 'This script can be run only in command line mode.' . PHP_EOL;
exit(1);
}
if (MYAAC_OS !== 'LINUX') {
echo 'This script can be run only on linux.' . PHP_EOL;
exit(1);
}
$job = '* * * * * /usr/bin/php ' . SYSTEM . 'bin/cronjob.php >> ' . SYSTEM . 'logs/cron.log 2>&1';
if (cronjob_exists($job)) {
echo 'MyAAC cronjob already installed.' . PHP_EOL;
exit(0);
}
exec ('crontab -l', $content);
$content = implode(' ', $content);
$content .= PHP_EOL . $job;
file_put_contents(CACHE . 'cronjob', $content . PHP_EOL);
exec('crontab ' . CACHE. 'cronjob');
echo 'Installed crontab successfully.' . PHP_EOL;
function cronjob_exists($command)
{
$cronjob_exists=false;
exec('crontab -l', $crontab);
if(isset($crontab)&&is_array($crontab)) {
$crontab = array_flip($crontab);
if(isset($crontab[$command])){
$cronjob_exists = true;
}
}
return $cronjob_exists;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,11 +9,17 @@
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
use MyAAC\Cache\Cache;
use MyAAC\CsrfToken;
use MyAAC\Items;
use MyAAC\Models\Config; use MyAAC\Models\Config;
use MyAAC\Models\Guild; use MyAAC\Models\Guild;
use MyAAC\Models\House; use MyAAC\Models\House;
use MyAAC\Models\Pages; use MyAAC\Models\Pages;
use MyAAC\Models\Player; use MyAAC\Models\Player;
use MyAAC\News;
use MyAAC\Plugins;
use MyAAC\Settings;
use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\PHPMailer;
use Twig\Loader\ArrayLoader as Twig_ArrayLoader; use Twig\Loader\ArrayLoader as Twig_ArrayLoader;
@@ -43,7 +49,10 @@ function warning($message, $return = false) {
return message($message, 'warning', $return); return message($message, 'warning', $return);
} }
function note($message, $return = false) { function note($message, $return = false) {
return message($message, 'note', $return); return info($message, $return);
}
function info($message, $return = false) {
return message($message, 'info', $return);
} }
function error($message, $return = false) { function error($message, $return = false) {
return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return); return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return);
@@ -96,7 +105,7 @@ function getPlayerLink($name, $generate = true): string
function getMonsterLink($name, $generate = true): string function getMonsterLink($name, $generate = true): string
{ {
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'creatures/' . urlencode($name); $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'monsters/' . urlencode($name);
if(!$generate) return $url; if(!$generate) return $url;
return generateLink($url, $name); return generateLink($url, $name);
@@ -133,7 +142,6 @@ function getGuildLink($name, $generate = true): string
} }
function getItemNameById($id) { function getItemNameById($id) {
require_once LIBS . 'items.php';
$item = Items::get($id); $item = Items::get($id);
return !empty($item['name']) ? $item['name'] : ''; return !empty($item['name']) ? $item['name'] : '';
} }
@@ -193,7 +201,7 @@ function getFlagImage($country): string
* @param mixed $v Variable to check. * @param mixed $v Variable to check.
* @return bool Value boolean status. * @return bool Value boolean status.
*/ */
function getBoolean($v): bool function getBoolean(mixed $v): bool
{ {
if(is_bool($v)) { if(is_bool($v)) {
return $v; return $v;
@@ -202,6 +210,10 @@ function getBoolean($v): bool
if(is_numeric($v)) if(is_numeric($v))
return (int)$v > 0; return (int)$v > 0;
if (is_null($v)) {
return false;
}
$v = strtolower($v); $v = strtolower($v);
return $v === 'yes' || $v === 'true'; return $v === 'yes' || $v === 'true';
} }
@@ -249,7 +261,7 @@ function generateRandomString($length, $lowCase = true, $upCase = false, $numeri
function getForumBoards() function getForumBoards()
{ {
global $db, $canEdit; global $db, $canEdit;
$sections = $db->query('SELECT `id`, `name`, `description`, `closed`, `guild`, `access`' . ($canEdit ? ', `hidden`, `ordering`' : '') . ' FROM `' . TABLE_PREFIX . 'forum_boards` ' . (!$canEdit ? ' WHERE `hidden` != 1' : '') . $sections = $db->query('SELECT `id`, `name`, `description`, `closed`, `guild`, `access`' . ($canEdit ? ', `hide`, `ordering`' : '') . ' FROM `' . TABLE_PREFIX . 'forum_boards` ' . (!$canEdit ? ' WHERE `hide` != 1' : '') .
' ORDER BY `ordering`;'); ' ORDER BY `ordering`;');
if($sections) if($sections)
return $sections->fetchAll(); return $sections->fetchAll();
@@ -406,7 +418,10 @@ function delete_guild($id)
if(count($rank_list) > 0) { if(count($rank_list) > 0) {
$rank_list->orderBy('level'); $rank_list->orderBy('level');
global $db, $ots; global $db;
/**
* @var OTS_GuildRank $rank_in_guild
*/
foreach($rank_list as $rank_in_guild) { foreach($rank_list as $rank_in_guild) {
if($db->hasTable('guild_members')) if($db->hasTable('guild_members'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;'); $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;');
@@ -465,20 +480,30 @@ function tickers()
*/ */
function template_place_holder($type): string function template_place_holder($type): string
{ {
global $twig, $template_place_holders; global $twig, $template_place_holders, $debugBar;
$ret = ''; $ret = '';
if (isset($debugBar)) {
$debugBarRenderer = $debugBar->getJavascriptRenderer();
}
if(array_key_exists($type, $template_place_holders) && is_array($template_place_holders[$type])) if(array_key_exists($type, $template_place_holders) && is_array($template_place_holders[$type]))
$ret = implode($template_place_holders[$type]); $ret = implode($template_place_holders[$type]);
if($type === 'head_start') { if($type === 'head_start') {
$ret .= template_header(); $ret .= template_header();
if (isset($debugBar)) {
$ret .= $debugBarRenderer->renderHead();
}
} }
elseif ($type === 'body_start') { elseif ($type === 'body_start') {
$ret .= $twig->render('browsehappy.html.twig'); $ret .= $twig->render('browsehappy.html.twig');
} }
elseif($type === 'body_end') { elseif($type === 'body_end') {
$ret .= template_ga_code(); $ret .= template_ga_code();
if (isset($debugBar)) {
$ret .= $debugBarRenderer->render();
}
} }
return $ret; return $ret;
@@ -688,11 +713,8 @@ function getSkillName($skillId, $suffix = true)
/** /**
* Performs flag check on the current logged in user. * Performs flag check on the current logged in user.
* Table in database: accounts, field: website_flags * Table in database: accounts, field: website_flags
*
* @param int @flag Flag to be verified.
* @return bool If user got flag.
*/ */
function hasFlag($flag) { function hasFlag(int $flag): bool {
global $logged, $logged_flags; global $logged, $logged_flags;
return ($logged && ($logged_flags & $flag) == $flag); return ($logged && ($logged_flags & $flag) == $flag);
} }
@@ -765,7 +787,7 @@ function get_browser_languages()
$languages = str_replace(' ', '', $languages); $languages = str_replace(' ', '', $languages);
foreach(explode(',', $languages) as $language_list) foreach(explode(',', $languages) as $language_list)
$ret[] .= substr($language_list, 0, 2); $ret[] = substr($language_list, 0, 2);
return $ret; return $ret;
} }
@@ -784,6 +806,10 @@ function get_templates()
$ret[] = $file; $ret[] = $file;
} }
foreach (Plugins::getThemes() as $name => $path) {
$ret[] = $name;
}
return $ret; return $ret;
} }
@@ -855,9 +881,6 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
else else
$tmp_body = $body . '<br/><br/>' . $signature_html; $tmp_body = $body . '<br/><br/>' . $signature_html;
define('MAIL_MAIL', 0);
define('MAIL_SMTP', 1);
$mailOption = setting('core.mail_option'); $mailOption = setting('core.mail_option');
if($mailOption == MAIL_SMTP) if($mailOption == MAIL_SMTP)
{ {
@@ -868,10 +891,6 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->Username = setting('core.smtp_user'); $mailer->Username = setting('core.smtp_user');
$mailer->Password = setting('core.smtp_pass'); $mailer->Password = setting('core.smtp_pass');
define('SMTP_SECURITY_NONE', 0);
define('SMTP_SECURITY_SSL', 1);
define('SMTP_SECURITY_TLS', 2);
$security = setting('core.smtp_security'); $security = setting('core.smtp_security');
$tmp = ''; $tmp = '';
@@ -1045,6 +1064,28 @@ function unsetSession($key) {
unset($_SESSION[setting('core.session_prefix') . $key]); unset($_SESSION[setting('core.session_prefix') . $key]);
} }
function csrf(bool $return = false): string {
return CsrfToken::create($return);
}
function csrfToken(): string {
return CsrfToken::get();
}
function isValidToken(): bool {
$token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null;
return (!isRequestMethod('post') || (isset($token) && CsrfToken::isValid($token)));
}
function csrfProtect(): void
{
if (!isValidToken()) {
$lastUri = BASE_URL . str_replace_first('/', '', getSession('last_uri'));
echo 'Request has been cancelled due to security reasons - token is invalid. Go <a href="' . $lastUri . '">back</a>';
exit();
}
}
function getTopPlayers($limit = 5) { function getTopPlayers($limit = 5) {
global $db; global $db;
@@ -1162,64 +1203,70 @@ function setting($key)
function clearCache() function clearCache()
{ {
require_once LIBS . 'news.php';
News::clearCache(); News::clearCache();
$cache = Cache::getInstance(); $cache = Cache::getInstance();
if($cache->enabled()) { if($cache->enabled()) {
$tmp = ''; $keysToClear = [
'status', 'templates',
'config_lua',
'towns', 'groups', 'vocations',
'visitors', 'views_counter', 'failed_logins',
'template_menus',
'last_kills',
'hooks', 'plugins_hooks', 'plugins_routes', 'plugins_settings', 'plugins_themes', 'plugins_commands',
'settings',
];
if ($cache->fetch('status', $tmp)) foreach (get_templates() as $template) {
$cache->delete('status'); $keysToClear[] = 'template_ini_' . $template;
}
if ($cache->fetch('templates', $tmp)) // highscores cache
$cache->delete('templates'); $configHighscoresPerPage = setting('core.highscores_per_page');
$skills = [POT::SKILL_FIST, POT::SKILL_CLUB, POT::SKILL_SWORD, POT::SKILL_AXE, POT::SKILL_DIST, POT::SKILL_SHIELD, POT::SKILL_FISH, POT::SKILL_LEVEL, POT::SKILL__MAGLEVEL, SKILL_FRAGS, SKILL_BALANCE];
foreach ($skills as $skill) {
// config('vocations') may be empty after previous cache clear
$vocations = (config('vocations') ?? []) + ['all'];
foreach ($vocations as $vocation) {
for($page = 0; $page < 10; $page++) {
$cacheKey = 'highscores_' . $skill . '_' . strtolower($vocation) . '_' . $page . '_' . $configHighscoresPerPage;
$keysToClear[] = $cacheKey;
}
}
}
if ($cache->fetch('config_lua', $tmp)) foreach ($keysToClear as $item) {
$cache->delete('config_lua'); $tmp = '';
if ($cache->fetch($item, $tmp)) {
$cache->delete($item);
}
}
if ($cache->fetch('vocations', $tmp)) global $db;
$cache->delete('vocations'); $db->setClearCacheAfter(true);
if ($cache->fetch('towns', $tmp))
$cache->delete('towns');
if ($cache->fetch('groups', $tmp))
$cache->delete('groups');
if ($cache->fetch('visitors', $tmp))
$cache->delete('visitors');
if ($cache->fetch('views_counter', $tmp))
$cache->delete('views_counter');
if ($cache->fetch('failed_logins', $tmp))
$cache->delete('failed_logins');
global $template_name;
if ($cache->fetch('template_ini' . $template_name, $tmp))
$cache->delete('template_ini' . $template_name);
if ($cache->fetch('plugins_hooks', $tmp))
$cache->delete('plugins_hooks');
if ($cache->fetch('plugins_routes', $tmp))
$cache->delete('plugins_routes');
} }
deleteDirectory(CACHE . 'signatures', ['index.html'], true); deleteDirectory(CACHE . 'signatures', ['index.html'], true);
deleteDirectory(CACHE . 'twig', ['index.html'], true); deleteDirectory(CACHE . 'twig', ['index.html'], true);
deleteDirectory(CACHE . 'plugins', ['index.html'], true); deleteDirectory(CACHE . 'plugins', ['index.html'], true);
deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html'], true); deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html', 'persistent'], true);
// routes cache // routes cache
clearRouteCache();
global $hooks;
$hooks->trigger(HOOK_CACHE_CLEAR, ['cache' => Cache::getInstance()]);
return true;
}
function clearRouteCache(): void
{
$routeCacheFile = CACHE . 'route.cache'; $routeCacheFile = CACHE . 'route.cache';
if (file_exists($routeCacheFile)) { if (file_exists($routeCacheFile)) {
unlink($routeCacheFile); unlink($routeCacheFile);
} }
return true;
} }
function getCustomPageInfo($name) function getCustomPageInfo($name)
@@ -1261,13 +1308,6 @@ function getCustomPage($name, &$success): string
else else
$tmp = $page['body']; $tmp = $page['body'];
$php_errors = array();
function error_handler($errno, $errstr) {
global $php_errors;
$php_errors[] = array('errno' => $errno, 'errstr' => $errstr);
}
set_error_handler('error_handler');
global $config; global $config;
if(setting('core.backward_support')) { if(setting('core.backward_support')) {
global $SQL, $main_content, $subtopic; global $SQL, $main_content, $subtopic;
@@ -1277,11 +1317,6 @@ function getCustomPage($name, &$success): string
eval($tmp); eval($tmp);
$content .= ob_get_contents(); $content .= ob_get_contents();
ob_end_clean(); ob_end_clean();
restore_error_handler();
if(isset($php_errors[0]) && superAdmin()) {
var_dump($php_errors);
}
} }
else { else {
$oldLoader = $twig->getLoader(); $oldLoader = $twig->getLoader();
@@ -1451,7 +1486,7 @@ function echo_success($message)
function echo_error($message) function echo_error($message)
{ {
global $error; global $error;
echo '<div class="col-12 alert alert-error mb-2">' . $message . '</div>'; echo '<div class="col-12 alert alert-danger mb-2">' . $message . '</div>';
$error = true; $error = true;
} }
@@ -1525,18 +1560,19 @@ function right($str, $length) {
return substr($str, -$length); return substr($str, -$length);
} }
function getCreatureImgPath($creature){ function getMonsterImgPath($monster): string
$creature_path = setting('core.monsters_images_url'); {
$creature_gfx_name = trim(strtolower($creature)) . setting('core.monsters_images_extension'); $monster_path = setting('core.monsters_images_url');
if (!file_exists($creature_path . $creature_gfx_name)) { $monster_gfx_name = trim(strtolower($monster)) . setting('core.monsters_images_extension');
$creature_gfx_name = str_replace(" ", "", $creature_gfx_name); if (!file_exists($monster_path . $monster_gfx_name)) {
if (file_exists($creature_path . $creature_gfx_name)) { $monster_gfx_name = str_replace(" ", "", $monster_gfx_name);
return $creature_path . $creature_gfx_name; if (file_exists($monster_path . $monster_gfx_name)) {
return $monster_path . $monster_gfx_name;
} else { } else {
return $creature_path . 'nophoto.png'; return $monster_path . 'nophoto.png';
} }
} else { } else {
return $creature_path . $creature_gfx_name; return $monster_path . $monster_gfx_name;
} }
} }
@@ -1606,7 +1642,7 @@ function getGuildLogoById($id)
$guild = Guild::where('id', intval($id))->select('logo_name')->first(); $guild = Guild::where('id', intval($id))->select('logo_name')->first();
if ($guild) { if ($guild) {
$guildLogo = $query->logo_name; $guildLogo = $guild->logo_name;
if (!empty($guildLogo) && file_exists(GUILD_IMAGES_DIR . $guildLogo)) { if (!empty($guildLogo) && file_exists(GUILD_IMAGES_DIR . $guildLogo)) {
$logo = $guildLogo; $logo = $guildLogo;
@@ -1624,8 +1660,15 @@ function displayErrorBoxWithBackButton($errors, $action = null) {
]); ]);
} }
function makeLinksClickable($text, $blank = true) {
return preg_replace('!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9@:%_+.~#?&;//=]+)!i', '<a href="$1"' . (!$blank ?: ' target="_blank"') . '>$1</a>', $text);
}
function isRequestMethod(string $method): bool {
return strtolower($_SERVER['REQUEST_METHOD']) == strtolower($method);
}
// validator functions // validator functions
require_once LIBS . 'validator.php';
require_once SYSTEM . 'compat/base.php'; require_once SYSTEM . 'compat/base.php';
// custom functions // custom functions

View File

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

View File

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

View File

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

View File

@@ -370,7 +370,14 @@ class POT
throw new RuntimeException('Please install PHP pdo extension. MyAAC will not work without it.'); throw new RuntimeException('Please install PHP pdo extension. MyAAC will not work without it.');
} }
$this->db = new OTS_DB_MySQL($params); global $debugBar;
if (isset($debugBar)) {
$this->db = new DebugBar\DataCollector\PDO\TraceablePDO(new OTS_DB_MySQL($params));
$debugBar->addCollector(new DebugBar\DataCollector\PDO\PDOCollector($this->db));
}
else {
$this->db = new OTS_DB_MySQL($params);
}
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} }

View File

@@ -952,7 +952,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
return $query['group_id']; return $query['group_id'];
} }
return 0; return 1;
} }
public function getAccGroupId() public function getAccGroupId()

View File

@@ -12,6 +12,8 @@
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/ */
use MyAAC\Cache\Cache;
/** /**
* MySQL connection interface. * MySQL connection interface.
* *
@@ -26,6 +28,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
{ {
private $has_table_cache = array(); private $has_table_cache = array();
private $has_column_cache = array(); private $has_column_cache = array();
private $clearCacheAfter = false;
/** /**
* Creates database connection. * Creates database connection.
* *
@@ -94,7 +98,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
} }
global $config; global $config;
if(class_exists('Cache') && ($cache = Cache::getInstance()) && $cache->enabled()) { $cache = Cache::getInstance();
if($cache->enabled()) {
$tmp = null; $tmp = null;
$need_revalidation = true; $need_revalidation = true;
if($cache->fetch('database_checksum', $tmp) && $tmp) { if($cache->fetch('database_checksum', $tmp) && $tmp) {
@@ -117,12 +122,15 @@ class OTS_DB_MySQL extends OTS_Base_DB
} }
} }
$driverAttributes = []; // debugbar dont like persistent connection
if (config('env') !== 'dev' && !getBoolean(config('enable_debugbar'))) {
$driverAttributes[PDO::ATTR_PERSISTENT] = $params['persistent'];
}
if(isset($params['socket'][0])) { if(isset($params['socket'][0])) {
$dns[] = 'unix_socket=' . $params['socket']; $dns[] = 'unix_socket=' . $params['socket'];
parent::__construct('mysql:' . implode(';', $dns), $user, $password, array( parent::__construct('mysql:' . implode(';', $dns), $user, $password, $driverAttributes);
PDO::ATTR_PERSISTENT => $params['persistent']
));
return; return;
} }
@@ -135,19 +143,25 @@ class OTS_DB_MySQL extends OTS_Base_DB
$dns[] = 'port=' . $params['port']; $dns[] = 'port=' . $params['port'];
} }
parent::__construct('mysql:' . implode(';', $dns), $user, $password, array( parent::__construct('mysql:' . implode(';', $dns), $user, $password, $driverAttributes);
PDO::ATTR_PERSISTENT => $params['persistent']
));
} }
public function __destruct() public function __destruct()
{ {
global $config; global $config;
if(class_exists('Cache') && ($cache = Cache::getInstance()) && $cache->enabled()) { $cache = Cache::getInstance();
$cache->set('database_tables', serialize($this->has_table_cache), 3600); if($cache->enabled()) {
$cache->set('database_columns', serialize($this->has_column_cache), 3600); if ($this->clearCacheAfter) {
$cache->set('database_checksum', serialize(sha1($config['database_host'] . '.' . $config['database_name'])), 3600); $cache->delete('database_tables');
$cache->delete('database_columns');
$cache->delete('database_checksum');
}
else {
$cache->set('database_tables', serialize($this->has_table_cache), 3600);
$cache->set('database_columns', serialize($this->has_column_cache), 3600);
$cache->set('database_checksum', serialize(sha1($config['database_host'] . '.' . $config['database_name'])), 3600);
}
} }
if($this->logged) { if($this->logged) {
@@ -235,6 +249,11 @@ class OTS_DB_MySQL extends OTS_Base_DB
} }
} }
} }
public function setClearCacheAfter($clearCache)
{
$this->clearCacheAfter = $clearCache;
}
} }
/**#@-*/ /**#@-*/

View File

@@ -8,6 +8,8 @@
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/ */
use MyAAC\Cache\Cache;
/** /**
* List of groups. * List of groups.
* *

View File

@@ -41,9 +41,10 @@
class OTS_Monster extends DOMDocument class OTS_Monster extends DOMDocument
{ {
private $loaded = false; private $loaded = false;
public function loadXML($source , $options = 0) public function loadXML(string $source , int $options = 0): bool
{ {
$this->loaded = parent::loadXML($source, $options); $this->loaded = parent::loadXML($source, $options);
return $this->loaded;
} }
public function loaded() public function loaded()

View File

@@ -90,7 +90,7 @@ class OTS_Player extends OTS_Row_DAO
* @version 0.1.2 * @version 0.1.2
* @var array * @var array
*/ */
private $data = array('sex' => 0, 'vocation' => 0, 'experience' => 0, 'level' => 1, 'maglevel' => 0, 'health' => 100, 'healthmax' => 100, 'mana' => 100, 'manamax' => 100, 'manaspent' => 0, 'soul' => 0, 'lookbody' => 10, 'lookfeet' => 10, 'lookhead' => 10, 'looklegs' => 10, 'looktype' => 136, 'lookaddons' => 0, 'posx' => 0, 'posy' => 0, 'posz' => 0, 'cap' => 0, 'lastlogin' => 0, 'lastip' => 0, 'save' => true, 'skulltime' => 0, 'skull' => 0, 'balance' => 0, 'lastlogout' => 0, 'blessings' => 0, 'stamina' => 0, 'online' => 0, 'comment' => '', 'created' => 0, 'hidden' => 0); private $data = array('sex' => 0, 'vocation' => 0, 'experience' => 0, 'level' => 1, 'maglevel' => 0, 'health' => 100, 'healthmax' => 100, 'mana' => 100, 'manamax' => 100, 'manaspent' => 0, 'soul' => 0, 'lookbody' => 10, 'lookfeet' => 10, 'lookhead' => 10, 'looklegs' => 10, 'looktype' => 136, 'lookaddons' => 0, 'posx' => 0, 'posy' => 0, 'posz' => 0, 'cap' => 0, 'lastlogin' => 0, 'lastip' => 0, 'save' => true, 'skulltime' => 0, 'skull' => 0, 'balance' => 0, 'lastlogout' => 0, 'blessings' => 0, 'stamina' => 0, 'online' => 0, 'comment' => '', 'created' => 0, 'hide' => 0);
/** /**
* Player skills. * Player skills.
@@ -231,7 +231,7 @@ class OTS_Player extends OTS_Row_DAO
} }
else { else {
// SELECT query on database // SELECT query on database
$this->data = $this->db->query('SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`' . ($this->db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `save`, `conditions`, `' . $__load['skull_time'] . '` as `skulltime`, `' . $__load['skull_type'] . '` as `skull`' . $__load['guild_info'] . ', `town_id`' . $__load['loss_experience'] . $__load['loss_items'] . ', `balance`' . ($__load['blessings'] ? ', `blessings`' : '') . ($__load['direction'] ? ', `direction`' : '') . ($__load['stamina'] ? ', `stamina`' : '') . ($__load['world_id'] ? ', `world_id`' : '') . ($__load['online'] ? ', `online`' : '') . ', `' . ($__load['deletion'] ? 'deletion' : 'deleted') . '`' . ($__load['promotion'] ? ', `promotion`' : '') . ($__load['marriage'] ? ', `marriage`' : '') . ', `comment`, `created`, `hidden` FROM `players` WHERE `id` = ' . (int)$id)->fetch(); $this->data = $this->db->query('SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`' . ($this->db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `save`, `conditions`, `' . $__load['skull_time'] . '` as `skulltime`, `' . $__load['skull_type'] . '` as `skull`' . $__load['guild_info'] . ', `town_id`' . $__load['loss_experience'] . $__load['loss_items'] . ', `balance`' . ($__load['blessings'] ? ', `blessings`' : '') . ($__load['direction'] ? ', `direction`' : '') . ($__load['stamina'] ? ', `stamina`' : '') . ($__load['world_id'] ? ', `world_id`' : '') . ($__load['online'] ? ', `online`' : '') . ', `' . ($__load['deletion'] ? 'deletion' : 'deleted') . '`' . ($__load['promotion'] ? ', `promotion`' : '') . ($__load['marriage'] ? ', `marriage`' : '') . ', `comment`, `created`, `hide` FROM `players` WHERE `id` = ' . (int)$id)->fetch();
} }
// loads skills // loads skills
@@ -521,17 +521,17 @@ class OTS_Player extends OTS_Row_DAO
public function isHidden() public function isHidden()
{ {
if( !isset($this->data['hidden']) ) if( !isset($this->data['hide']) )
{ {
throw new E_OTS_NotLoaded(); throw new E_OTS_NotLoaded();
} }
return $this->data['hidden'] == 1; return $this->data['hide'] == 1;
} }
public function setHidden($hidden) public function setHidden($hidden)
{ {
$this->data['hidden'] = (int) $hidden; $this->data['hide'] = (int) $hidden;
} }
public function getMarriage() public function getMarriage()

View File

@@ -7,6 +7,9 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\CsrfToken;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
if(isset($account_logged) && $account_logged->isLoaded()) { if(isset($account_logged) && $account_logged->isLoaded()) {
@@ -15,6 +18,8 @@ if(isset($account_logged) && $account_logged->isLoaded()) {
unsetSession('password'); unsetSession('password');
unsetSession('remember_me'); unsetSession('remember_me');
CsrfToken::generate();
$logged = false; $logged = false;
unset($account_logged); unset($account_logged);

View File

@@ -1,5 +1,7 @@
<?php <?php
use MyAAC\Plugins;
if(!$db->hasTable('myaac_menu')) { if(!$db->hasTable('myaac_menu')) {
$db->query(" $db->query("
CREATE TABLE `myaac_menu` CREATE TABLE `myaac_menu`
@@ -14,8 +16,8 @@ CREATE TABLE `myaac_menu`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
"); ");
require_once LIBS . 'plugins.php';
Plugins::installMenus('kathrine', require TEMPLATES . 'kathrine/menus.php');
Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php');
} }
Plugins::installMenus('kathrine', require TEMPLATES . 'kathrine/menus.php');
Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php');

View File

@@ -1,5 +1,7 @@
<?php <?php
use MyAAC\Settings;
$query = $db->query("SELECT `id` FROM `players` WHERE (`name` = " . $db->quote("Rook Sample") . " OR `name` = " . $db->quote("Sorcerer Sample") . " OR `name` = " . $db->quote("Druid Sample") . " OR `name` = " . $db->quote("Paladin Sample") . " OR `name` = " . $db->quote("Knight Sample") . " OR `name` = " . $db->quote("Account Manager") . ") ORDER BY `id`;"); $query = $db->query("SELECT `id` FROM `players` WHERE (`name` = " . $db->quote("Rook Sample") . " OR `name` = " . $db->quote("Sorcerer Sample") . " OR `name` = " . $db->quote("Druid Sample") . " OR `name` = " . $db->quote("Paladin Sample") . " OR `name` = " . $db->quote("Knight Sample") . " OR `name` = " . $db->quote("Account Manager") . ") ORDER BY `id`;");
$highscores_ignored_ids = array(); $highscores_ignored_ids = array();

View File

@@ -1,37 +1,47 @@
<?php <?php
$downloadsPage = <<<HTML
<p>&nbsp;</p>
<p>&nbsp;</p>
<div style="text-align: center;">We're using official Tibia Client <strong>{{ config.client / 100 }}</strong><br>
<p>Download Tibia Client <strong>{{ config.client / 100 }}</strong>&nbsp;for Windows <a href="https://drive.google.com/drive/folders/0B2-sMQkWYzhGSFhGVlY2WGk5czQ" target="_blank" rel="noopener">HERE</a>.</p>
<h2>IP Changer:</h2>
<a href="https://static.otland.net/ipchanger.exe" target="_blank" rel="noopener">HERE</a></div>
HTML;
$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX . "pages` WHERE `name` LIKE " . $db->quote('downloads') . " LIMIT 1;"); $query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX . "pages` WHERE `name` LIKE " . $db->quote('downloads') . " LIMIT 1;");
if($query->rowCount() === 0) { if($query->rowCount() === 0) {
$db->exec("INSERT INTO `myaac_pages` (`id`, `name`, `title`, `body`, `date`, `player_id`, `php`, `access`, `hidden`) VALUES $db->exec("INSERT INTO `myaac_pages` (`id`, `name`, `title`, `body`, `date`, `player_id`, `php`, `access`, `hide`) VALUES
(null, 'downloads', 'Downloads', '<p>&nbsp;</p> (null, 'downloads', 'Downloads', {$db->quote($downloadsPage)}, 0, 1, 0, 0, 0);");
<p>&nbsp;</p>
<div style=\"text-align: center;\">We''re using official Tibia Client <strong>{{ config.client / 100 }}</strong><br />
<p>Download Tibia Client <strong>{{ config.client / 100 }}</strong>&nbsp;for Windows <a href=\"https://drive.google.com/drive/folders/0B2-sMQkWYzhGSFhGVlY2WGk5czQ\" target=\"_blank\" rel=\"noopener\">HERE</a>.</p>
<h2>IP Changer:</h2>
<a href=\"https://static.otland.net/ipchanger.exe\" target=\"_blank\" rel=\"noopener\">HERE</a></div>', 0, 1, 0, 1, 0);");
} }
$commandsPage = <<<HTML
<table class="myaac-table" style="border-collapse: collapse; width: 100%; height: 72px; border-width: 1px;" border="1"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup>
<thead>
<tr style="height: 18px;">
<td style="height: 18px; border-width: 1px; text-align: center;"><span style="color: #ffffff;"><strong>Words</strong></span></td>
<td style="height: 18px; border-width: 1px; text-align: center;"><strong>Description</strong></td>
</tr>
</thead>
<tbody>
<tr style="height: 18px;">
<td style="height: 18px; border-width: 1px;">!example</td>
<td style="height: 18px; border-width: 1px;">This is just an example</td>
</tr>
<tr style="height: 18px;">
<td style="height: 18px; border-width: 1px;">!buyhouse</td>
<td style="height: 18px; border-width: 1px;">Buy house you are looking at</td>
</tr>
<tr style="height: 18px;">
<td style="height: 18px; border-width: 1px;"><em>!aol</em></td>
<td style="height: 18px; border-width: 1px;">Buy AoL</td>
</tr>
</tbody>
</table>
HTML;
$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX . "pages` WHERE `name` LIKE " . $db->quote('commands') . " LIMIT 1;"); $query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX . "pages` WHERE `name` LIKE " . $db->quote('commands') . " LIMIT 1;");
if($query->rowCount() === 0) { if($query->rowCount() === 0) {
$db->exec("INSERT INTO `myaac_pages` (`id`, `name`, `title`, `body`, `date`, `player_id`, `php`, `access`, `hidden`) VALUES $db->exec("INSERT INTO `myaac_pages` (`id`, `name`, `title`, `body`, `date`, `player_id`, `php`, `access`, `hide`) VALUES
(null, 'commands', 'Commands', '<table style=\"border-collapse: collapse; width: 87.8471%; height: 57px;\" border=\"1\"> (null, 'commands', 'Commands', {$db->quote($commandsPage)}, 0, 1, 0, 0, 0);");
<tbody>
<tr style=\"height: 18px;\">
<td style=\"width: 33.3333%; background-color: #505050; height: 18px;\"><span style=\"color: #ffffff;\"><strong>Words</strong></span></td>
<td style=\"width: 33.3333%; background-color: #505050; height: 18px;\"><span style=\"color: #ffffff;\"><strong>Description</strong></span></td>
</tr>
<tr style=\"height: 18px; background-color: #f1e0c6;\">
<td style=\"width: 33.3333%; height: 18px;\"><em>!example</em></td>
<td style=\"width: 33.3333%; height: 18px;\">This is just an example</td>
</tr>
<tr style=\"height: 18px; background-color: #d4c0a1;\">
<td style=\"width: 33.3333%; height: 18px;\"><em>!buyhouse</em></td>
<td style=\"width: 33.3333%; height: 18px;\">Buy house you are looking at</td>
</tr>
<tr style=\"height: 18px; background-color: #f1e0c6;\">
<td style=\"width: 33.3333%; height: 18px;\"><em>!aol</em></td>
<td style=\"width: 33.3333%; height: 18px;\">Buy AoL</td>
</tr>
</tbody>
</table>', 0, 1, 0, 1, 0);");
} }

View File

@@ -1,5 +1,7 @@
<?php <?php
use MyAAC\Cache\Cache;
$db->exec('DROP TABLE IF EXISTS `' . TABLE_PREFIX . 'hooks`;'); $db->exec('DROP TABLE IF EXISTS `' . TABLE_PREFIX . 'hooks`;');
$cache = Cache::getInstance(); $cache = Cache::getInstance();

View File

@@ -2,7 +2,7 @@
$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX . "pages` WHERE `name` LIKE " . $db->quote('rules_on_the_page') . " LIMIT 1;"); $query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX . "pages` WHERE `name` LIKE " . $db->quote('rules_on_the_page') . " LIMIT 1;");
if($query->rowCount() === 0) { if($query->rowCount() === 0) {
$db->exec("INSERT INTO `myaac_pages` (`id`, `name`, `title`, `body`, `date`, `player_id`, `php`, `enable_tinymce`, `access`, `hidden`) VALUES $db->exec("INSERT INTO `myaac_pages` (`id`, `name`, `title`, `body`, `date`, `player_id`, `php`, `enable_tinymce`, `access`, `hide`) VALUES
(null, 'rules_on_the_page', 'Rules', '1. Names (null, 'rules_on_the_page', 'Rules', '1. Names
a) Names which contain insulting (e.g. \"Bastard\"), racist (e.g. \"Nigger\"), extremely right-wing (e.g. \"Hitler\"), sexist (e.g. \"Bitch\") or offensive (e.g. \"Copkiller\") language. a) Names which contain insulting (e.g. \"Bastard\"), racist (e.g. \"Nigger\"), extremely right-wing (e.g. \"Hitler\"), sexist (e.g. \"Bitch\") or offensive (e.g. \"Copkiller\") language.
b) Names containing parts of sentences (e.g. \"Mike returns\"), nonsensical combinations of letters (e.g. \"Fgfshdsfg\") or invalid formattings (e.g. \"Thegreatknight\"). b) Names containing parts of sentences (e.g. \"Mike returns\"), nonsensical combinations of letters (e.g. \"Fgfshdsfg\") or invalid formattings (e.g. \"Thegreatknight\").
@@ -27,5 +27,5 @@ a) Excessive killing of characters who are not marked with a \"skull\" on worlds
A violation of the Tibia Rules may lead to temporary banishment of characters and accounts. In severe cases removal or modification of character skills, attributes and belongings, as well as the permanent removal of accounts without any compensation may be considered. The sanction is based on the seriousness of the rule violation and the previous record of the player. It is determined by the gamemaster imposing the banishment. A violation of the Tibia Rules may lead to temporary banishment of characters and accounts. In severe cases removal or modification of character skills, attributes and belongings, as well as the permanent removal of accounts without any compensation may be considered. The sanction is based on the seriousness of the rule violation and the previous record of the player. It is determined by the gamemaster imposing the banishment.
These rules may be changed at any time. All changes will be announced on the official website.', 0, 1, 0, 0, 1, 0);"); These rules may be changed at any time. All changes will be announced on the official website.', 0, 1, 0, 0, 0, 0);");
} }

View File

@@ -2,17 +2,56 @@
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'elements')) { if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'elements')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `elements` TEXT NOT NULL AFTER `immunities`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `elements` TEXT NOT NULL AFTER `immunities`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'pushable')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `pushable` TINYINT(1) NOT NULL DEFAULT '0' AFTER `convinceable`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `pushable` TINYINT(1) NOT NULL DEFAULT '0' AFTER `convinceable`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'canpushitems')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canpushitems` TINYINT(1) NOT NULL DEFAULT '0' AFTER `pushable`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canpushitems` TINYINT(1) NOT NULL DEFAULT '0' AFTER `pushable`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'canpushcreatures')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canpushcreatures` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canpushitems`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canpushcreatures` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canpushitems`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'canwalkonenergy')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canwalkonenergy` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canpushitems`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canwalkonenergy` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canpushitems`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'canwalkonpoison')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canwalkonpoison` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canwalkonenergy`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canwalkonpoison` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canwalkonenergy`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'canwalkonfire')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canwalkonfire` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canwalkonpoison`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `canwalkonfire` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canwalkonpoison`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'runonhealth')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `runonhealth` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canwalkonfire`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `runonhealth` TINYINT(1) NOT NULL DEFAULT '0' AFTER `canwalkonfire`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'hostile')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `hostile` TINYINT(1) NOT NULL DEFAULT '0' AFTER `runonhealth`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `hostile` TINYINT(1) NOT NULL DEFAULT '0' AFTER `runonhealth`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'attackable')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `attackable` TINYINT(1) NOT NULL DEFAULT '0' AFTER `hostile`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `attackable` TINYINT(1) NOT NULL DEFAULT '0' AFTER `hostile`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'rewardboss')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `rewardboss` TINYINT(1) NOT NULL DEFAULT '0' AFTER `attackable`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `rewardboss` TINYINT(1) NOT NULL DEFAULT '0' AFTER `attackable`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'defense')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `defense` INT(11) NOT NULL DEFAULT '0' AFTER `rewardboss`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `defense` INT(11) NOT NULL DEFAULT '0' AFTER `rewardboss`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'armor')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `armor` INT(11) NOT NULL DEFAULT '0' AFTER `defense`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `armor` INT(11) NOT NULL DEFAULT '0' AFTER `defense`;");
}
if(!$db->hasColumn(TABLE_PREFIX . 'monsters', 'summons')) {
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `summons` TEXT NOT NULL AFTER `loot`;"); $db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `summons` TEXT NOT NULL AFTER `loot`;");
} }

8
system/migrations/37.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
// 2023-11-11
// Add Guest page access
use MyAAC\Models\Pages;
Pages::query()->where('access', 1)->update(['access' => 0]);

5
system/migrations/38.php Normal file
View File

@@ -0,0 +1,5 @@
<?php
// 2023-11-11
// execute highscores_ids_hidden once again, cause of settings
require __DIR__ . '/20.php';

18
system/migrations/39.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
// 2024-01-27
// change hidden to hide (Eloquent model reserved keyword)
if (!$db->hasColumn('players', 'hide')) {
$db->exec("ALTER TABLE `players` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
}
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "changelog` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "faq` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "forum_boards` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "monsters` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "news` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "news_categories` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "pages` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "gallery` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");
$db->exec("ALTER TABLE `" . TABLE_PREFIX . "spells` CHANGE `hidden` `hide` TINYINT(1) NOT NULL DEFAULT 0;");

12
system/migrations/40.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
// 2024-02-03
// update pages links
use MyAAC\Models\Menu;
Menu::where('link', 'lastkills')->update(['link' => 'last-kills']);
Menu::where('link', 'serverInfo')->update(['link' => 'server-info']);
Menu::where('link', 'experienceStages')->update(['link' => 'exp-stages']);
Menu::where('link', 'experienceTable')->update(['link' => 'exp-table']);
Menu::where('link', 'creatures')->update(['link' => 'monsters']);

View File

@@ -40,7 +40,7 @@ if($player_name != null) {
if (isset($_POST['changecommentsave']) && $_POST['changecommentsave'] == 1) { if (isset($_POST['changecommentsave']) && $_POST['changecommentsave'] == 1) {
if(empty($errors)) { if(empty($errors)) {
$player->hidden = $new_hideacc; $player->hide = $new_hideacc;
$player->comment = $new_comment; $player->comment = $new_comment;
$player->save(); $player->save();
$account_logged->logAction('Changed comment for character <b>' . $player->name . '</b>.'); $account_logged->logAction('Changed comment for character <b>' . $player->name . '</b>.');

View File

@@ -92,18 +92,22 @@ else
<tr> <tr>
<td width="30">&nbsp;</td> <td width="30">&nbsp;</td>
<td align=left> <td align=left>
<form action="' . getLink('account/email') . '" method="post"><input type="hidden" name="changeemailsave" value=1 > <form action="' . getLink('account/email') . '" method="post">
' . csrf(true) . '
<input type="hidden" name="changeemailsave" value=1 >
<INPUT TYPE=image NAME="I Agree" SRC="' . $template_path . '/images/global/buttons/sbutton_iagree.gif" BORDER=0 WIDTH=120 HEIGHT=17> <INPUT TYPE=image NAME="I Agree" SRC="' . $template_path . '/images/global/buttons/sbutton_iagree.gif" BORDER=0 WIDTH=120 HEIGHT=17>
</form> </form>
</td> </td>
<td align=left> <td align=left>
<form action="' . getLink('account/email') . '" method="post"> <form action="' . getLink('account/email') . '" method="post">
' . csrf(true) . '
<input type="hidden" name="emailchangecancel" value=1 > <input type="hidden" name="emailchangecancel" value=1 >
' . $twig->render('buttons.cancel.html.twig') . ' ' . $twig->render('buttons.cancel.html.twig') . '
</form> </form>
</td> </td>
<td align=right> <td align=right>
<form action="?subtopic=accountmanagement" method="post" > <form action="' . getLink('account/manage') . '" method="post" >
' . csrf(true) . '
' . $twig->render('buttons.back.html.twig') . ' ' . $twig->render('buttons.back.html.twig') . '
</form> </form>
</td> </td>
@@ -125,6 +129,7 @@ else
<td> <td>
<table border="0" cellspacing="0" cellpadding="0" > <table border="0" cellspacing="0" cellpadding="0" >
<form action="' .getLink('account/email') . '" method="post" > <form action="' .getLink('account/email') . '" method="post" >
' . csrf(true) . '
<tr> <tr>
<td style="border:0px;" > <td style="border:0px;" >
<input type="hidden" name="emailchangecancel" value="1" > <input type="hidden" name="emailchangecancel" value="1" >
@@ -137,6 +142,7 @@ else
<td> <td>
<table border="0" cellspacing="0" cellpadding="0" > <table border="0" cellspacing="0" cellpadding="0" >
<form action="' . getLink('account/manage') . '" method="post" > <form action="' . getLink('account/manage') . '" method="post" >
' . csrf(true) . '
<tr> <tr>
<td style="border:0px;" > <td style="border:0px;" >
' . $twig->render('buttons.back.html.twig') . ' ' . $twig->render('buttons.back.html.twig') . '
@@ -158,7 +164,7 @@ if(isset($_POST['emailchangecancel']) && $_POST['emailchangecancel'] == 1) {
$account_logged->setCustomField("email_new", ""); $account_logged->setCustomField("email_new", "");
$account_logged->setCustomField("email_new_time", 0); $account_logged->setCustomField("email_new_time", 0);
$custom_buttons = '<div style="text-align:center"><table border="0" cellspacing="0" cellpadding="0" ><form action="?subtopic=accountmanagement" method="post" ><tr><td style="border:0px;" >' . $twig->render('buttons.back.html.twig') . '</td></tr></form></table></div>'; $custom_buttons = '<div style="text-align:center"><table border="0" cellspacing="0" cellpadding="0" ><form action="' . getLink('account/manage') . '" method="post" ><tr><td style="border:0px;" >' . $twig->render('buttons.back.html.twig') . '</td></tr></form></table></div>';
$twig->display('success.html.twig', array( $twig->display('success.html.twig', array(
'title' => 'Email Address Change Cancelled', 'title' => 'Email Address Change Cancelled',

View File

@@ -18,18 +18,18 @@ if(!$logged) {
} }
$new_password = $_POST['newpassword'] ?? NULL; $new_password = $_POST['newpassword'] ?? NULL;
$new_password2 = $_POST['newpassword2'] ?? NULL; $new_password_confirm = $_POST['newpassword_confirm'] ?? NULL;
$old_password = $_POST['oldpassword'] ?? NULL; $old_password = $_POST['oldpassword'] ?? NULL;
if(empty($new_password) && empty($new_password2) && empty($old_password)) { if(empty($new_password) && empty($new_password_confirm) && empty($old_password)) {
$twig->display('account.change_password.html.twig'); $twig->display('account.change_password.html.twig');
} }
else else
{ {
if(empty($new_password) || empty($new_password2) || empty($old_password)){ if(empty($new_password) || empty($new_password_confirm) || empty($old_password)){
$errors[] = 'Please fill in form.'; $errors[] = 'Please fill in form.';
} }
$password_strlen = strlen($new_password); $password_strlen = strlen($new_password);
if($new_password != $new_password2) { if($new_password != $new_password_confirm) {
$errors[] = 'The new passwords do not match!'; $errors[] = 'The new passwords do not match!';
} }

View File

@@ -8,6 +8,9 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\CreateCharacter;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Create Account'; $title = 'Create Account';
@@ -21,7 +24,6 @@ if($logged)
} }
if(setting('core.account_create_character_create')) { if(setting('core.account_create_character_create')) {
require_once LIBS . 'CreateCharacter.php';
$createCharacter = new CreateCharacter(); $createCharacter = new CreateCharacter();
} }
@@ -50,7 +52,7 @@ if($save)
$email = $_POST['email']; $email = $_POST['email'];
$password = $_POST['password']; $password = $_POST['password'];
$password2 = $_POST['password2']; $password_confirm = $_POST['password_confirm'];
// account // account
if(!config('account_login_by_email')) { if(!config('account_login_by_email')) {
@@ -81,7 +83,7 @@ if($save)
if(empty($password)) { if(empty($password)) {
$errors['password'] = 'Please enter the password for your new account.'; $errors['password'] = 'Please enter the password for your new account.';
} }
elseif($password != $password2) { elseif($password != $password_confirm) {
$errors['password'] = 'Passwords are not the same.'; $errors['password'] = 'Passwords are not the same.';
} }
else if(!Validator::password($password)) { else if(!Validator::password($password)) {
@@ -134,7 +136,7 @@ if($save)
'email' => $email, 'email' => $email,
'country' => $country, 'country' => $country,
'password' => $password, 'password' => $password,
'password2' => $password2, 'password_confirm' => $password_confirm,
'accept_rules' => isset($_POST['accept_rules']) ? $_POST['accept_rules'] === 'true' : false, 'accept_rules' => isset($_POST['accept_rules']) ? $_POST['accept_rules'] === 'true' : false,
); );
@@ -267,7 +269,7 @@ if($save)
$_POST['account_login'] = USE_ACCOUNT_NAME ? $account_name : $account_id; $_POST['account_login'] = USE_ACCOUNT_NAME ? $account_name : $account_id;
} }
$_POST['password_login'] = $password2; $_POST['password_login'] = $password_confirm;
require PAGES . 'account/login.php'; require PAGES . 'account/login.php';
header('Location: ' . getLink('account/manage')); header('Location: ' . getLink('account/manage'));

View File

@@ -8,6 +8,9 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\CreateCharacter;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Create Character'; $title = 'Create Character';
@@ -30,7 +33,6 @@ $character_created = false;
$save = isset($_POST['save']) && $_POST['save'] == 1; $save = isset($_POST['save']) && $_POST['save'] == 1;
$errors = array(); $errors = array();
if($save) { if($save) {
require_once LIBS . 'CreateCharacter.php';
$createCharacter = new CreateCharacter(); $createCharacter = new CreateCharacter();
$character_created = $createCharacter->doCreate($character_name, $character_sex, $character_vocation, $character_town, $account_logged, $errors); $character_created = $createCharacter->doCreate($character_name, $character_sex, $character_vocation, $character_town, $account_logged, $errors);

View File

@@ -61,16 +61,18 @@ if(isset($_POST['deletecharactersave']) && $_POST['deletecharactersave'] == 1) {
} }
} }
$ownerid = 'ownerid'; if(empty($errors)) {
if($db->hasColumn('guilds', 'owner_id')) $ownerid = 'ownerid';
$ownerid = 'owner_id'; if ($db->hasColumn('guilds', 'owner_id'))
$guild = $db->query('SELECT `name` FROM `guilds` WHERE `' . $ownerid . '` = '.$player->getId()); $ownerid = 'owner_id';
if($guild->rowCount() > 0) { $guild = $db->query('SELECT `name` FROM `guilds` WHERE `' . $ownerid . '` = ' . $player->getId());
$errors[] = 'You cannot delete a character when they own a guild.'; if ($guild->rowCount() > 0) {
$errors[] = 'You cannot delete a character when they own a guild.';
}
} }
if(empty($errors)) { if(empty($errors)) {
//dont show table "delete character" again // don't show table "delete character" again
$show_form = false; $show_form = false;
/** @var OTS_DB_MySQL $db */ /** @var OTS_DB_MySQL $db */
if ($db->hasColumn('players', 'deletion')) if ($db->hasColumn('players', 'deletion'))

View File

@@ -59,6 +59,7 @@ if(!$logged && isset($_POST['account_login'], $_POST['password_login']))
&& (!isset($t) || $t['attempts'] < 5) && (!isset($t) || $t['attempts'] < 5)
) )
{ {
session_regenerate_id();
setSession('account', $account_logged->getId()); setSession('account', $account_logged->getId());
setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password)); setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password));
if($remember_me) { if($remember_me) {

View File

@@ -55,7 +55,7 @@ elseif($action == 'step1' && $action_type == 'email')
</TD></TR></FORM></TABLE></TABLE>'; </TD></TR></FORM></TABLE></TABLE>';
else else
{ {
$insec = $account->getCustomField('email_next') - time(); $insec = (int)$account->getCustomField('email_next') - time();
$minutesleft = floor($insec / 60); $minutesleft = floor($insec / 60);
$secondsleft = $insec - ($minutesleft * 60); $secondsleft = $insec - ($minutesleft * 60);
$timeleft = $minutesleft.' minutes '.$secondsleft.' seconds'; $timeleft = $minutesleft.' minutes '.$secondsleft.' seconds';
@@ -95,7 +95,7 @@ elseif($action == 'sendcode')
<p>Account name: '.$account->getName().'</p> <p>Account name: '.$account->getName().'</p>
<br /> <br />
To do so, please click this link: To do so, please click this link:
<p><a href="' . getLink('account/lost') . '?action=checkcode&code='.$newcode.'&character='.urlencode($nick).'">'.BASE_URL.'/?subtopic=lostaccount&action=checkcode&code='.$newcode.'&character='.urlencode($nick).'</a></p> <p><a href="' . getLink('account/lost') . '?action=checkcode&code='.$newcode.'&character='.urlencode($nick).'">' . getLink('account/lost') . '?action=checkcode&code='.$newcode.'&character='.urlencode($nick).'</a></p>
<p>or open page: <i>' . getLink('account/lost') . '?action=checkcode</i> and in field "code" write <b>'.$newcode.'</b></p> <p>or open page: <i>' . getLink('account/lost') . '?action=checkcode</i> and in field "code" write <b>'.$newcode.'</b></p>
<br/> <br/>
<p>If you did not request a password change, you may ignore this message and your password will remain unchanged.'; <p>If you did not request a password change, you may ignore this message and your password will remain unchanged.';
@@ -118,7 +118,7 @@ elseif($action == 'sendcode')
} }
else else
{ {
$insec = $account->getCustomField('email_next') - time(); $insec = (int)$account->getCustomField('email_next') - time();
$minutesleft = floor($insec / 60); $minutesleft = floor($insec / 60);
$secondsleft = $insec - ($minutesleft * 60); $secondsleft = $insec - ($minutesleft * 60);
$timeleft = $minutesleft.' minutes '.$secondsleft.' seconds'; $timeleft = $minutesleft.' minutes '.$secondsleft.' seconds';
@@ -172,7 +172,7 @@ elseif($action == 'step1' && $action_type == 'reckey')
else else
echo 'Invalid player name format. If you have other characters on account try with other name.'; echo 'Invalid player name format. If you have other characters on account try with other name.';
echo '<BR /><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center"> echo '<BR /><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center">
<a href="?subtopic=lostaccount" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div> <a href="' . getLink('account/lost') . '" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div>
</TD></TR></FORM></TABLE></TABLE>'; </TD></TR></FORM></TABLE></TABLE>';
} }
elseif($action == 'step2') elseif($action == 'step2')
@@ -232,7 +232,7 @@ elseif($action == 'step2')
} }
</script>'; </script>';
echo 'Set new password and e-mail to your account.<BR> echo 'Set new password and e-mail to your account.<BR>
<FORM ACTION="?subtopic=lostaccount&action=step3" onsubmit="return validate_form(this)" METHOD=post> <FORM ACTION="' . getLink('account/lost') . '?action=step3" onsubmit="return validate_form(this)" METHOD=post>
<INPUT TYPE=hidden NAME="character" VALUE=""> <INPUT TYPE=hidden NAME="character" VALUE="">
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Please enter new password and e-mail</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Please enter new password and e-mail</B></TD></TR>
@@ -261,7 +261,7 @@ elseif($action == 'step2')
else else
echo 'Invalid player name format. If you have other characters on account try with other name.'; echo 'Invalid player name format. If you have other characters on account try with other name.';
echo '<BR /><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center"> echo '<BR /><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center">
<a href="?subtopic=lostaccount&action=step1&action_type=reckey&nick='.urlencode($nick).'" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div> <a href="' . getLink('account/lost') . '?action=step1&action_type=reckey&nick='.urlencode($nick).'" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div>
</TD></TR></FORM></TABLE></TABLE>'; </TD></TR></FORM></TABLE></TABLE>';
} }
elseif($action == 'step3') elseif($action == 'step3')
@@ -304,7 +304,7 @@ elseif($action == 'step3')
$account->setCustomField('salt', $salt); $account->setCustomField('salt', $salt);
echo 'Your account name, new password and new e-mail.<BR> echo 'Your account name, new password and new e-mail.<BR>
<FORM ACTION="?subtopic=accountmanagement" onsubmit="return validate_form(this)" METHOD=post> <FORM ACTION="' . getLink('account/manage') . '" onsubmit="return validate_form(this)" METHOD=post>
<INPUT TYPE=hidden NAME="character" VALUE=""> <INPUT TYPE=hidden NAME="character" VALUE="">
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Your account name, new password and new e-mail</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Your account name, new password and new e-mail</B></TD></TR>
@@ -361,7 +361,7 @@ elseif($action == 'step3')
else else
echo 'Invalid player name format. If you have other characters on account try with other name.'; echo 'Invalid player name format. If you have other characters on account try with other name.';
echo '<BR /><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center"> echo '<BR /><TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center">
<a href="?subtopic=lostaccount&action=step1&action_type=reckey&nick='.urlencode($nick).'" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div> <a href="' . getLink('account/lost') . '?action=step1&action_type=reckey&nick='.urlencode($nick).'" border="0"><IMG SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" NAME="Back" ALT="Back" BORDER=0 WIDTH=120 HEIGHT=18></a></div>
</TD></TR></FORM></TABLE></TABLE>'; </TD></TR></FORM></TABLE></TABLE>';
} }
elseif($action == 'checkcode') elseif($action == 'checkcode')
@@ -370,7 +370,7 @@ elseif($action == 'checkcode')
$character = stripslashes(trim($_REQUEST['character'])); $character = stripslashes(trim($_REQUEST['character']));
if(empty($code) || empty($character)) if(empty($code) || empty($character))
echo 'Please enter code from e-mail and name of one character from account. Then press Submit.<BR> echo 'Please enter code from e-mail and name of one character from account. Then press Submit.<BR>
<FORM ACTION="?subtopic=lostaccount&action=checkcode" METHOD=post> <FORM ACTION="' . getLink('account/lost') . '?action=checkcode" METHOD=post>
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Code & character name</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Code & character name</B></TD></TR>
<TR><TD BGCOLOR="'.$config['darkborder'].'"> <TR><TD BGCOLOR="'.$config['darkborder'].'">
@@ -418,7 +418,7 @@ elseif($action == 'checkcode')
} }
</script> </script>
Please enter new password to your account and repeat to make sure you remember password.<BR> Please enter new password to your account and repeat to make sure you remember password.<BR>
<FORM ACTION="?subtopic=lostaccount&action=setnewpassword" onsubmit="return validate_form(this)" METHOD=post> <FORM ACTION="' . getLink('account/lost') . '?action=setnewpassword" onsubmit="return validate_form(this)" METHOD=post>
<INPUT TYPE=hidden NAME="character" VALUE="'.$character.'"> <INPUT TYPE=hidden NAME="character" VALUE="'.$character.'">
<INPUT TYPE=hidden NAME="code" VALUE="'.$code.'"> <INPUT TYPE=hidden NAME="code" VALUE="'.$code.'">
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
@@ -441,7 +441,7 @@ elseif($action == 'checkcode')
} }
if(!empty($error)) if(!empty($error))
echo '<span style="color: red"><b>'.$error.'</b></span><br />Please enter code from e-mail and name of one character from account. Then press Submit.<BR> echo '<span style="color: red"><b>'.$error.'</b></span><br />Please enter code from e-mail and name of one character from account. Then press Submit.<BR>
<FORM ACTION="?subtopic=lostaccount&action=checkcode" METHOD=post> <FORM ACTION="' . getLink('account/lost') . '?action=checkcode" METHOD=post>
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Code & character name</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Code & character name</B></TD></TR>
<TR><TD BGCOLOR="'.$config['darkborder'].'"> <TR><TD BGCOLOR="'.$config['darkborder'].'">
@@ -462,7 +462,7 @@ elseif($action == 'setnewpassword')
echo ''; echo '';
if(empty($code) || empty($character) || empty($newpassword)) if(empty($code) || empty($character) || empty($newpassword))
echo '<span style="color: red"><b>Error. Try again.</b></span><br />Please enter code from e-mail and name of one character from account. Then press Submit.<BR> echo '<span style="color: red"><b>Error. Try again.</b></span><br />Please enter code from e-mail and name of one character from account. Then press Submit.<BR>
<BR><FORM ACTION="?subtopic=lostaccount&action=checkcode" METHOD=post> <BR><FORM ACTION="' . getLink('account/lost') . '?action=checkcode" METHOD=post>
<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center"> <TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center">
<INPUT TYPE=image NAME="Back" ALT="Back" SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" BORDER=0 WIDTH=120 HEIGHT=18></div> <INPUT TYPE=image NAME="Back" ALT="Back" SRC="'.$template_path.'/images/global/buttons/sbutton_back.gif" BORDER=0 WIDTH=120 HEIGHT=18></div>
</TD></TR></FORM></TABLE></TABLE>'; </TD></TR></FORM></TABLE></TABLE>';
@@ -518,7 +518,7 @@ elseif($action == 'setnewpassword')
</TABLE> </TABLE>
<BR> <BR>
<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center"> <TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%><TR><TD><div style="text-align:center">
<FORM ACTION="?subtopic=accountmanagement" METHOD=post> <FORM ACTION="' . getLink('account/manage') . '" METHOD=post>
<INPUT TYPE=image NAME="Login" ALT="Login" SRC="'.$template_path.'/images/global/buttons/sbutton_login.gif" BORDER=0 WIDTH=120 HEIGHT=18></div> <INPUT TYPE=image NAME="Login" ALT="Login" SRC="'.$template_path.'/images/global/buttons/sbutton_login.gif" BORDER=0 WIDTH=120 HEIGHT=18></div>
</TD></TR></FORM></TABLE></TABLE>'; </TD></TR></FORM></TABLE></TABLE>';
} }
@@ -533,7 +533,7 @@ elseif($action == 'setnewpassword')
} }
if(!empty($error)) if(!empty($error))
echo '<span style="color: red"><b>'.$error.'</b></span><br />Please enter code from e-mail and name of one character from account. Then press Submit.<BR> echo '<span style="color: red"><b>'.$error.'</b></span><br />Please enter code from e-mail and name of one character from account. Then press Submit.<BR>
<FORM ACTION="?subtopic=lostaccount&action=checkcode" METHOD=post> <FORM ACTION="' . getLink('account/lost') . '?action=checkcode" METHOD=post>
<TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%> <TABLE CELLSPACING=1 CELLPADDING=4 BORDER=0 WIDTH=100%>
<TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Code & character name</B></TD></TR> <TR><TD BGCOLOR="'.$config['vdarkborder'].'" class="white"><B>Code & character name</B></TD></TR>
<TR><TD BGCOLOR="'.$config['darkborder'].'"> <TR><TD BGCOLOR="'.$config['darkborder'].'">

View File

@@ -18,6 +18,16 @@ if(!$logged) {
return; return;
} }
if(isset($_REQUEST['redirect']))
{
$redirect = urldecode($_REQUEST['redirect']);
$twig->display('account.redirect.html.twig', array(
'redirect' => $redirect
));
return;
}
$groups = new OTS_Groups_List(); $groups = new OTS_Groups_List();
$freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS; $freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS;

View File

@@ -27,7 +27,7 @@ $configBans = [];
$configBans['hasType'] = false; $configBans['hasType'] = false;
$configBans['hasReason'] = false; $configBans['hasReason'] = false;
$limit = 'LIMIT ' . ($configBansPerPage + 1) . (isset($offset) ? ' OFFSET ' . $offset : ''); $limit = 'LIMIT ' . ($configBansPerPage + 1) . ' OFFSET ' . $offset;
if ($db->hasTable('account_bans')) { if ($db->hasTable('account_bans')) {
$bansQuery = $db->query('SELECT * FROM `account_bans` ORDER BY `banned_at` DESC ' . $limit); $bansQuery = $db->query('SELECT * FROM `account_bans` ORDER BY `banned_at` DESC ' . $limit);
} }

View File

@@ -1,370 +0,0 @@
<?php
/**
* Bug tracker
*
* @package MyAAC
* @author Gesior <jerzyskalski@wp.pl>
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\BugTracker;
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Bug tracker';
if(!$logged)
{
echo 'You are not logged in. <a href="?subtopic=accountmanagement&redirect=' . BASE_URL . urlencode('?subtopic=bugtracker') . '">Log in</a> to post on the bug tracker.<br /><br />';
return;
}
$showed = $post = $reply = false;
// type (1 = question; 2 = answer)
// status (1 = open; 2 = new message; 3 = closed;)
$dark = $config['darkborder'];
$light = $config['lightborder'];
$tags = array(1 => "[MAP]", "[WEBSITE]", "[CLIENT]", "[MONSTER]", "[NPC]", "[OTHER]");
if(admin() and isset($_REQUEST['control']) && $_REQUEST['control'] == "true")
{
if(empty($_REQUEST['id']) and empty($_REQUEST['acc']) or !is_numeric($_REQUEST['acc']) or !is_numeric($_REQUEST['id']) )
$bug[1] = BugTracker::where('type', 1)->orderByDesc('uid')->get()->toArray();
if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id']) and !empty($_REQUEST['acc']) and is_numeric($_REQUEST['acc']))
$bug[2] = BugTracker::where('type', 1)->where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->get()->toArray();
if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id']) and !empty($_REQUEST['acc']) and is_numeric($_REQUEST['acc']))
{
if(!empty($_REQUEST['reply']))
$reply=true;
$account = new OTS_Account();
$account->load($_REQUEST['acc']);
$account->isLoaded();
$players = $account->getPlayersList();
if(!$reply)
{
if($bug[2]['status'] == 2)
$value = '<span style="color: green">[OPEN]</span>';
elseif($bug[2]['status'] == 3)
$value = '<span style="color: red">[CLOSED]</span>';
elseif($bug[2]['status'] == 1)
$value = '<span style="color: blue">[NEW ANSWER]</span>';
echo '<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR='.$config['vdarkborder'].'><TD COLSPAN=2 CLASS=white><B>Bug Tracker</B></TD></TR>';
echo '<TR BGCOLOR="'.$dark.'"><td width=40%><i><b>Subject</b></i></td><td>'.$tags[$bug[2]['tag']].' '.$bug[2]['subject'].' '.$value.'</td></tr>';
echo '<TR BGCOLOR="'.$light.'"><td><i><b>Posted by</b></i></td><td>';
foreach($players as $player)
{
echo ''.$player->getName().'<br>';
}
echo '</td></tr>';
echo '<TR BGCOLOR="'.$dark.'"><td colspan=2><i><b>Description</b></i></td></tr>';
echo '<TR BGCOLOR="'.$light.'"><td colspan=2>'.nl2br($bug[2]['text']).'</td></tr>';
echo '</TABLE>';
$answers = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->orderBy('reply')->get()->toArray();
foreach($answers as $answer)
{
if($answer['who'] == 1)
$who = '<span style="color: red">[ADMIN]</span>';
else
$who = '<span style="color: green">[PLAYER]</span>';
echo '<br><TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR='.$config['vdarkborder'].'><TD COLSPAN=2 CLASS=white><B>Answer #'.$answer['reply'].'</B></TD></TR>';
echo '<TR BGCOLOR="'.$dark.'"><td width=70%><i><b>Posted by</b></i></td><td>'.$who.'</td></tr>';
echo '<TR BGCOLOR="'.$light.'"><td colspan=2><i><b>Description</b></i></td></tr>';
echo '<TR BGCOLOR="'.$dark.'"><td colspan=2>'.nl2br($answer['text']).'</td></tr>';
echo '</TABLE>';
}
if($bug[2]['status'] != 3)
echo '<br><a href="?subtopic=bugtracker&control=true&id='.$_REQUEST['id'].'&acc='.$_REQUEST['acc'].'&reply=true"><b>[REPLY]</b></a>';
}
else
{
if($bug[2]['status'] != 3)
{
$reply = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->max('reply');
$reply = $reply + 1;
$iswho = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->orderByDesc('reply')->first()->toArray();
if(isset($_POST['finish']))
{
if(empty($_POST['text']))
$error[] = '<span style="color: black"><b>Description cannot be empty.</b></span>';
if($iswho['who'] == 1)
$error[] = '<span style="color: black"><b>You must wait for User answer.</b></span>';
if(empty($_POST['status']))
$error[] = '<span style="color: black"><b>Status cannot be empty.</b></span>';
if(!empty($error))
{
foreach($error as $errors)
echo ''.$errors.'<br>';
}
else
{
$type = 2;
$INSERT = BugTracker::create([
'account' => $_REQUEST['aac'],
'id' => $_REQUEST['id'],
'text' => $_POST['text'],
'reply' => $reply,
'type' => $type,
'who' => 1,
]);
$UPDATE = Bugtracker::where('id', $_REQUEST['id'])->where('account', $_REQUEST['acc'])->update([
'status' => $_POST['status']
]);
header('Location: ?subtopic=bugtracker&control=true&id='.$_REQUEST['id'].'&acc='.$_REQUEST['acc'].'');
}
}
echo '<br><form method="post" action=""><table><tr><td><i>Description</i></td><td><textarea name="text" rows="15" cols="35"></textarea></td></tr><tr><td>Status[OPEN]</td><td><input type=radio name=status value=2></td></tr><tr><td>Status[CLOSED]</td><td><input type=radio name=status value=3></td></tr></table><br><input type="submit" name="finish" value="Submit" class="input2"/></form>';
}
else
{
echo '<br><span style="color: black"><b>You can\'t add answer to closed bug thread.</b></span>';
}
}
$post=true;
}
if(!$post)
{
echo '<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR='.$config['vdarkborder'].'><TD colspan=2 CLASS=white><B>Bug Tracker Admin</B></TD></TR>';
$i=1;
foreach($bug[1] as $report)
{
if($report['status'] == 2)
$value = '<span style="color: green">[OPEN]</span>';
elseif($report['status'] == 3)
$value = '<span style="color: red">[CLOSED]</span>';
elseif($report['status'] == 1)
$value = '<span style="color: blue">[NEW ANSWER]</span>';
echo '<TR BGCOLOR="' . getStyle($i) . '"><td width=75%><a href="?subtopic=bugtracker&control=true&id='.$report['id'].'&acc='.$report['account'].'">'.$tags[$report['tag']].' '.$report['subject'].'</a></td><td>'.$value.'</td></tr>';
$showed=true;
$i++;
}
echo '</TABLE>';
}
}
else
{
$acc = $account_logged->getId();
$account_players = $account_logged->getPlayersList();
foreach($account_players as $player)
{
$allow=true;
}
if(!empty($_REQUEST['id']))
$id = addslashes(htmlspecialchars(trim($_REQUEST['id'])));
if(empty($_REQUEST['id']))
$bug[1] = BugTracker::where('account', $account_logged->getId())->where('type', 1)->orderBy('id')->get()->toArray();
if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id']))
$bug[2] = BugTracker::where('account', $account_logged->getId())->where('type', 1)->where('id', $id)->get()->toArray();
else
$bug[2] = NULL;
if(!empty($_REQUEST['id']) and $bug[2] != NULL)
{
if(!empty($_REQUEST['reply']))
$reply=true;
if(!$reply)
{
if($bug[2]['status'] == 1)
$value = '<span style="color: green">[OPEN]</span>';
elseif($bug[2]['status'] == 2)
$value = '<span style="color: blue">[NEW ANSWER]</span>';
elseif($bug[2]['status'] == 3)
$value = '<span style="color: red">[CLOSED]</span>';
echo '<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR='.$config['vdarkborder'].'><TD COLSPAN=2 CLASS=white><B>Bug Tracker</B></TD></TR>';
echo '<TR BGCOLOR="'.$dark.'"><td width=40%><i><b>Subject</b></i></td><td>'.$tags[$bug[2]['tag']].' '.$bug[2]['subject'].' '.$value.'</td></tr>';
echo '<TR BGCOLOR="'.$light.'"><td colspan=2><i><b>Description</b></i></td></tr>';
echo '<TR BGCOLOR="'.$dark.'"><td colspan=2>'.nl2br($bug[2]['text']).'</td></tr>';
echo '</TABLE>';
$answers = Bugtracker::where('account', $account_logged->getId())->where('id', $id)->where('type', 2)->orderBy('reply')->get()->toArray();
foreach($answers as $answer)
{
if($answer['who'] == 1)
$who = '<span style="color: red">[ADMIN]</span>';
else
$who = '<span style="color: green">[YOU]</span>';
echo '<br><TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR='.$config['vdarkborder'].'><TD COLSPAN=2 CLASS=white><B>Answer #'.$answer['reply'].'</B></TD></TR>';
echo '<TR BGCOLOR="'.$dark.'"><td width=70%><i><b>Posted by</b></i></td><td>'.$who.'</td></tr>';
echo '<TR BGCOLOR="'.$light.'"><td colspan=2><i><b>Description</b></i></td></tr>';
echo '<TR BGCOLOR="'.$dark.'"><td colspan=2>'.nl2br($answer['text']).'</td></tr>';
echo '</TABLE>';
}
if($bug[2]['status'] != 3)
echo '<br><a href="?subtopic=bugtracker&id='.$id.'&reply=true"><b>[REPLY]</b></a>';
}
else
{
if($bug[2]['status'] != 3)
{
$reply = BugTracker::where('account', $aac)->where('id', $id)->where('type', 2)->max('reply');
$reply = $reply + 1;
$iswho = BugTracker::where('account', $acc)->where('id', $id)->where('type', 2)->orderByDesc('reply')->first()->toArray();
if(isset($_POST['finish']))
{
if(empty($_POST['text']))
$error[] = '<span style="color: black"><b>Description cannot be empty.</b></span>';
if($iswho['who'] == 0)
$error[] = '<span style="color: black"><b>You must wait for Administrator answer.</b></span>';
if(!$allow)
$error[] = '<span style="color: black"><b>You haven\'t any characters on account.</b></span>';
if(!empty($error))
{
foreach($error as $errors)
echo ''.$errors.'<br>';
}
else
{
$type = 2;
$INSERT = BugTracker::create([
'account' => $acc,
'id' => $id,
'text' => $_POST['text'],
'reply' => $reply,
'type' => $type
]);
$UPDATE = BugTracker::where('id', $id)->where('account', $acc)->update([
'status' => 1
]);
header('Location: ?subtopic=bugtracker&id='.$id.'');
}
}
echo '<br><form method="post" action=""><table><tr><td><i>Description</i></td><td><textarea name="text" rows="15" cols="35"></textarea></td></tr></table><br><input type="submit" name="finish" value="Submit" class="input2"/></form>';
}
else
{
echo '<br><span style="color: black"><b>You can\'t add answer to closed bug thread.</b></span>';
}
}
$post=true;
}
elseif(!empty($_REQUEST['id']) and $bug[2] == NULL)
{
echo '<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR='.$config['vdarkborder'].'><TD CLASS=white><B>Bug Tracker</B></TD></TR>';
echo '<TR BGCOLOR="'.$dark.'"><td><i>Bug doesn\'t exist.</i></td></tr>';
echo '</TABLE>';
$post=true;
}
if(!$post)
{
if(!isset($_REQUEST['add']) || $_REQUEST['add'] != TRUE)
{
echo '<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR='.$config['vdarkborder'].'><TD colspan=2 CLASS=white><B>Bug Tracker</B></TD></TR>';
foreach($bug[1] as $report)
{
if($report['status'] == 1)
$value = '<span style="color: green">[OPEN]</span>';
elseif($report['status'] == 2)
$value = '<span style="color: blue">[NEW ANSWER]</span>';
elseif($report['status'] == 3)
$value = '<span style="color: red">[CLOSED]</span>';
if(is_int($report['id'] / 2))
{
$bgcolor = $dark;
}
else
{
$bgcolor = $light;
}
echo '<TR BGCOLOR="'.$bgcolor.'"><td width=75%><a href="?subtopic=bugtracker&id='.$report['id'].'">'.$tags[$report['tag']].' '.$report['subject'].'</a></td><td>'.$value.'</td></tr>';
$showed=true;
}
if(!$showed)
{
echo '<TR BGCOLOR="'.$dark.'"><td><i>You don\'t have reported any bugs.</i></td></tr>';
}
echo '</TABLE>';
echo '<br><a href="?subtopic=bugtracker&add=true"><b>[ADD REPORT]</b></a>';
}
elseif(isset($_REQUEST['add']) && $_REQUEST['add'] == TRUE)
{
$thread = BugTracker::where('account', $acc)->where('type', 1)->orderByDesc('id')->get()->toArray();
$id_next = BugTracker::where('account', $acc)->where('type', 1)->max('id');
$id_next = $id_next + 1;
if(empty($thread))
$thread['status'] = 3;
if(isset($_POST['submit']))
{
if($thread['status'] != 3)
$error[] = '<span style="color: black"><b>Can be only 1 open bug thread.</b></span>';
if(empty($_POST['subject']))
$error[] = '<span style="color: black"><b>Subject cannot be empty.</b></span>';
if(empty($_POST['text']))
$error[] = '<span style="color: black"><b>Description cannot be empty.</b></span>';
if(!$allow)
$error[] = '<span style="color: black"><b>You haven\'t any characters on account.</b></span>';
if(empty($_POST['tags']))
$error[] = '<span style="color: black"><b>Tag cannot be empty.</b></span>';
if(!empty($error))
{
foreach($error as $errors)
echo ''.$errors.'<br>';
}
else
{
$type = 1;
$status = 1;
$INSERT = BugTracker::create([
'account' => $acc,
'id' => $id_next,
'text' => $_POST['text'],
'type' => $type,
'subject' => $_POST['subject'],
'reply' => 0,
'status' => $status,
'tag' => $_POST['tags']
]);
header('Location: ?subtopic=bugtracker&id='.$id_next.'');
}
}
echo '<br><form method="post" action=""><table><tr><td><i>Subject</i></td><td><input type=text name="subject"/></td></tr><tr><td><i>Description</i></td><td><textarea name="text" rows="15" cols="35"></textarea></td></tr><tr><td>TAG</td><td><select name="tags"><option value="">SELECT</option>';
for($i = 1; $i <= count($tags); $i++)
{
echo '<option value="' . $i . '">' . $tags[$i] . '</option>';
}
echo '</select></tr></tr></table><br><input type="submit" name="submit" value="Submit" class="input2"/></form>';
}
}
}
if(admin() and empty($_REQUEST['control']))
{
echo '<br><br><a href="?subtopic=bugtracker&control=true">[ADMIN PANEL]</a>';
}

View File

@@ -19,7 +19,7 @@ $next_page = false;
$canEdit = hasFlag(FLAG_CONTENT_NEWS) || superAdmin(); $canEdit = hasFlag(FLAG_CONTENT_NEWS) || superAdmin();
$changelogs = Changelog::isPublic()->orderByDesc('id')->limit($limit + 1)->offset($offset)->get()->toArray(); $changelogs = Changelog::isPublic()->orderByDesc('date')->limit($limit + 1)->offset($offset)->get()->toArray();
$i = 0; $i = 0;
foreach($changelogs as $key => &$log) foreach($changelogs as $key => &$log)

View File

@@ -342,8 +342,8 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil
$signature_url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . urlencode($player->getName()) . '.png'; $signature_url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . urlencode($player->getName()) . '.png';
} }
$hidden = $player->isHidden(); $hide = $player->isHidden();
if(!$hidden) { if(!$hide) {
// check if account has been banned // check if account has been banned
$bannedUntil = ''; $bannedUntil = '';
$banned = array(); $banned = array();
@@ -363,7 +363,7 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil
$query = $db->query('SELECT `id` FROM `players` WHERE `account_id` = ' . $account->getId() . ' ORDER BY `name`')->fetchAll(); $query = $db->query('SELECT `id` FROM `players` WHERE `account_id` = ' . $account->getId() . ' ORDER BY `name`')->fetchAll();
foreach($query as $p) { foreach($query as $p) {
$_player = new OTS_Player(); $_player = new OTS_Player();
$fields = array('id', 'name', 'vocation', 'level', 'online', 'deleted', 'hidden'); $fields = array('id', 'name', 'vocation', 'level', 'online', 'deleted', 'hide');
$_player->load($p['id'], $fields, false); $_player->load($p['id'], $fields, false);
if($_player->isLoaded() && !$_player->isHidden()) { if($_player->isLoaded() && !$_player->isHidden()) {
$account_players[] = $_player; $account_players[] = $_player;
@@ -404,7 +404,8 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil
'frags' => $frags, 'frags' => $frags,
'signature_url' => isset($signature_url) ? $signature_url : null, 'signature_url' => isset($signature_url) ? $signature_url : null,
'player_link' => getPlayerLink($player->getName(), false), 'player_link' => getPlayerLink($player->getName(), false),
'hidden' => $hidden, 'hide' => $hide,
'hidden' => $hide,
'bannedUntil' => isset($bannedUntil) ? $bannedUntil : null, 'bannedUntil' => isset($bannedUntil) ? $bannedUntil : null,
'account_players' => isset($account_players) ? $account_players : null, 'account_players' => isset($account_players) ? $account_players : null,
'search_form' => generate_search_form(), 'search_form' => generate_search_form(),

View File

@@ -1,86 +1,3 @@
<?php <?php
/**
* Creatures
*
* @package MyAAC
* @author Gesior <jerzyskalski@wp.pl>
* @author Slawkens <slawkens@gmail.com>
* @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Monster; require 'monsters.php';
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Creatures';
if (empty($_REQUEST['name'])) {
// display list of monsters
$preview = setting('core.monsters_images_preview');
$creatures = Monster::where('hidden', '!=', 1)->when(!empty($_REQUEST['boss']), function ($query) {
$query->where('rewardboss', 1);
})->get()->toArray();
if ($preview) {
foreach($creatures as $key => &$creature)
{
$creature['img_link'] = getCreatureImgPath($creature['name']);
}
}
$twig->display('creatures.html.twig', array(
'creatures' => $creatures,
'preview' => $preview
));
return;
}
// display monster
$creature_name = urldecode(stripslashes(ucwords(strtolower($_REQUEST['name']))));
$creature = Monster::where('hidden', '!=', 1)->where('name', $creature_name)->first()->toArray();
if (isset($creature['name'])) {
function sort_by_chance($a, $b)
{
if ($a['chance'] == $b['chance']) {
return 0;
}
return ($a['chance'] > $b['chance']) ? -1 : 1;
}
$title = $creature['name'] . " - Creatures";
$creature['img_link']= getCreatureImgPath($creature_name);
$voices = json_decode($creature['voices'], true);
$summons = json_decode($creature['summons'], true);
$elements = json_decode($creature['elements'], true);
$immunities = json_decode($creature['immunities'], true);
$loot = json_decode($creature['loot'], true);
usort($loot, 'sort_by_chance');
foreach ($loot as &$item) {
$item['name'] = getItemNameById($item['id']);
$item['rarity_chance'] = round($item['chance'] / 1000, 2);
$item['rarity'] = getItemRarity($item['chance']);
$item['tooltip'] = ucfirst($item['name']) . '<br/>Chance: ' . $item['rarity'] . (setting('core.monsters_loot_percentage') ? ' ('. $item['rarity_chance'] .'%)' : '') . '<br/>Max count: ' . $item['count'];
}
$creature['loot'] = isset($loot) ? $loot : null;
$creature['voices'] = isset($voices) ? $voices : null;
$creature['summons'] = isset($summons) ? $summons : null;
$creature['elements'] = isset($elements) ? $elements : null;
$creature['immunities'] = isset($immunities) ? $immunities : null;
$twig->display('creature.html.twig', array(
'creature' => $creature,
));
} else {
echo "Creature with name <b>" . $creature_name . "</b> doesn't exist.";
}
// back button
$twig->display('creatures.back_button.html.twig');

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