Compare commits

...

580 Commits

Author SHA1 Message Date
slawkens
bb830bce44 Release v1.7 2025-06-22 08:55:29 +02:00
slawkens
566c2a9151 Move out of $cache->enabled 2025-06-22 08:48:24 +02:00
slawkens
0f48f12e2e Update admin.plugins.outdated.html.twig 2025-06-19 18:53:11 +02:00
Slawomir Boczek
0ea247ce7e Feature/plugins versions check (#310)
* Check plugins versions from plugins.my-aac.org/api

* Improve plugin update check messaging

Updated the success message when checking for plugin updates to clarify the source. Added an informational message when outdated plugins are found to improve user feedback.

* Use configurable API URI for plugin updates

Replaces hardcoded plugin API URI with a configurable value from config, defaulting to the official API. Also fixes a typo in the success message.
2025-06-19 16:46:22 +02:00
slawkens
b329da52aa Use apcu_clear_cache 2025-06-17 17:52:23 +02:00
slawkens
c720ccc451 Add missing csrf() 2025-06-15 19:35:12 +02:00
slawkens
8dc42b6544 Nothing important: just formatting 2025-06-15 19:05:47 +02:00
slawkens
dca904e61d Add missing csrf() 2025-06-15 19:05:19 +02:00
slawkens
29faa4f695 Add missing csrf() in success.html.twig 2025-06-15 19:03:03 +02:00
slawkens
4767120043 Update online.html.twig 2025-06-14 21:19:52 +02:00
slawkens
9a90e4aae2 Revamped online page 2025-06-14 21:12:47 +02:00
slawkens
ba4ed6a04b Add LabelV120, LabelV150, LabelV200 2025-06-14 20:52:38 +02:00
slawkens
a7efacdbac Delete online.form, use revamped characters.form 2025-06-14 20:50:54 +02:00
Goosey
577037becc fix: boostedcreatures for 13.40 (#307)
* boostedcreatures fix for 13.40

Fixes the boosted boss/creature display on the login page for 13.40 running the default cipsoft client.

* Adjust version

---------

Co-authored-by: slawkens <slawkens@gmail.com>
2025-06-14 15:58:08 +02:00
slawkens
b8abc11b96 Update list.php 2025-06-14 11:33:47 +02:00
slawkens
4def6a6cae Style 2025-06-14 10:39:45 +02:00
slawkens
e6100a1b72 New hook: HOOK_GUILDS_AFTER_MANAGE_BUTTON 2025-06-14 10:36:38 +02:00
slawkens
522f6c11d8 Add OTS_Player->isNameLocked() 2025-06-14 08:26:43 +02:00
slawkens
00c3635c5f Add $config['site']['serverPath'] for better compatibility with Gesior 2025-06-14 00:59:10 +02:00
slawkens
c074a48f24 New hook: HOOK_ACCOUNT_MANAGE_AFTER_CHARACTERS 2025-06-14 00:44:00 +02:00
slawkens
e222957893 OTS_Toolbox::getVocationName($id, $promotion); 2025-06-13 22:25:36 +02:00
slawkens
d423ddd07a Nothing important: convert to tabs 2025-06-13 22:14:20 +02:00
slawkens
4d4f7759d3 Update visitors.php 2025-06-13 21:31:04 +02:00
slawkens
9510640ba9 Ignore empty values 2025-06-13 21:25:13 +02:00
slawkens
98b13c91a4 Update notice about how to enable Visitors Counter 2025-06-13 21:24:52 +02:00
slawkens
0c95bcfd06 Better $title inventing 2025-06-13 21:03:09 +02:00
slawkens
524e982a0e Release v1.6.1 2025-06-11 05:51:39 +02:00
slawkens
fffb427eae Update account.generate_recovery_key.html.twig 2025-06-09 21:18:45 +02:00
slawkens
10cd71a663 Add missing csrf() into account manage actions 2025-06-09 21:18:42 +02:00
slawkens
0812fe025d Update settings_save.php 2025-06-09 21:14:44 +02:00
slawkens
309c1fb715 Remove deprecated TinyMCE plugin - template 2025-06-09 14:24:36 +02:00
slawkens
8d29fdb98b Set TinyMCE license key to gpl (Avoid warning message in browser console) 2025-06-09 14:24:22 +02:00
slawkens
f782850307 Move counter & visitors code before router
In case someone wants to include that info on page
2025-06-06 22:10:13 +02:00
slawkens
835dda9659 Remove duplicated code - account redirect, already in account/manage 2025-06-05 19:08:53 +02:00
slawkens
dcc703b1eb Remove optional param, make it required for few routes 2025-06-05 18:11:44 +02:00
slawkens
9d8e9d27bd Ignore duplicated route exception 2025-06-05 18:11:31 +02:00
slawkens
db09980de1 Start v1.6.1-dev 2025-06-03 22:57:33 +02:00
slawkens
2dba778167 Update example.json 2025-06-03 18:38:02 +02:00
slawkens
ce2af2bb7a Update CHANGELOG-1.x.md 2025-06-03 17:33:17 +02:00
slawkens
dc839abfbb Release v1.6 2025-06-03 16:59:55 +02:00
slawkens
01d49692ed Update CHANGELOG-1.x.md 2025-06-03 16:59:20 +02:00
slawkens
de6603a513 Allow [] in character name (again), example: [God] Test 2025-06-03 16:49:45 +02:00
slawkens
dd731fd49b Revert previous commit partially 2025-06-03 16:43:43 +02:00
slawkens
064b929841 Allow [] in character name (for :string) 2025-06-03 16:39:02 +02:00
slawkens
c61747dc75 Update coins.html.twig 2025-06-03 10:17:08 +02:00
slawkens
207d6bc691 feat: AutoLoad plugins init.php, by default disabled 2025-06-03 08:52:33 +02:00
slawkens
8fdea94376 Add globals into $hooks->executeFIlter 2025-06-03 08:39:48 +02:00
slawkens
c961a1ebf8 Two new hooks for pages loaded from database (custom pages)
HOOK_BEFORE_PAGE_CUSTOM,
HOOK_AFTER_PAGE_CUSTOM
2025-06-03 06:21:44 +02:00
slawkens
770ffcfc52 Fix warnings in CLI (part 2) 2025-05-29 16:10:46 +02:00
slawkens
756d94bb3e Fix warning from CLI 2025-05-29 16:08:23 +02:00
slawkens
6e0f591383 Do not allow access to tools/ folder after install 2025-05-29 12:22:16 +02:00
slawkens
fb91281140 Fix phpstan workflow 2025-05-29 09:35:20 +02:00
slawkens
d8a6090be3 Add new setting/configurable: site_url, prevents domain spoofing 2025-05-29 09:27:29 +02:00
slawkens
52109f5cca Another solution 2025-05-28 14:13:04 +02:00
slawkens
4b7b121550 Try fix workflow 2025-05-28 14:08:50 +02:00
slawkens
28886551e8 feat: Add new account coins setting 2025-05-28 13:33:36 +02:00
slawkens
7d435ff643 Add getNPCsCount 2025-05-24 11:54:00 +02:00
slawkens
ae847ff9a6 Nothing important: tabs 2025-05-24 11:51:06 +02:00
slawkens
45ef390829 Nothing important 2025-05-24 11:42:59 +02:00
slawkens
84d502bf10 Fixes regarding csrf + refactor some parts of AAC (guilds + forum)
Replace $account_logged->getPlayers() with getPlayersList()
$_REQUEST['todo'] -> $_REQUEST['post']
$guild_errors -> $errors
2025-05-24 11:42:42 +02:00
slawkens
e776bd52be Forum boards admin links: csrf + refactor 2025-05-24 11:28:56 +02:00
slawkens
6e793390c6 Remove unneeded enctype="multipart/form-data" 2025-05-24 11:20:36 +02:00
slawkens
6eda38603c Protect against csrf in more places (accounts & guilds pages) 2025-05-24 09:52:56 +02:00
slawkens
72cdd290da Fix link to Contributing 2025-05-23 17:38:14 +02:00
slawkens
40d65a6613 OTS_ServerInfo -> set timeout out of class
Possibility to use the class without MyAAC
2025-05-23 16:11:57 +02:00
slawkens
43153b2b0c Nothing important: tabs 2025-05-23 16:08:02 +02:00
slawkens
2ea549002a Nothing important: tabs 2025-05-23 15:58:23 +02:00
slawkens
4a30fb495d Fix CHANGELOG-1.x.md loading 2025-05-23 09:13:20 +02:00
slawkens
4d8f5f31ae Update Plugins.php 2025-05-23 09:04:48 +02:00
slawkens
be7b27c31a Fix links not working in admin dashboard modules 2025-05-23 09:04:45 +02:00
slawkens
7d213f479a feat: autoload install.php 2025-05-23 08:50:38 +02:00
slawkens
e574943707 feat: autoload settings.php 2025-05-23 08:39:09 +02:00
slawkens
1e9b10d648 Fix twig variables: logged + account_logged being not set directly after login 2025-05-15 19:11:20 +02:00
slawkens
7c92d1c197 Start v1.5.1-dev 2025-05-14 15:11:20 +02:00
slawkens
3111d66df9 Fix install, where $twig is not present in tools 2025-05-14 14:09:28 +02:00
slawkens
e45dd88a93 Release v1.5 2025-05-14 14:03:03 +02:00
slawkens
5ed1aec28e Add db variable to twig 2025-05-14 13:37:23 +02:00
slawkens
7e4d28c648 Fix more php 8.4 warnings 2025-05-14 13:23:34 +02:00
slawkens
3b2669fb3b Update tables.headline.html.twig 2025-05-14 13:23:25 +02:00
slawkens
6fe3bff163 Update 45.php 2025-05-14 10:56:12 +02:00
slawkens
ae5be41e11 Separate migration 44 with 45 2025-05-14 10:52:06 +02:00
slawkens
83a6f4b61d Add php 8.4 to phpstan 2025-05-14 10:42:18 +02:00
slawkens
ee360386d8 Addition to previous commit 2025-05-14 10:39:11 +02:00
slawkens
bf06bed385 Update schema.sql 2025-05-14 10:22:42 +02:00
slawkens
3949d84e5d Rename server-info -> ots-info, changelog -> change-log + move rules to admin panel
Due to conflict with apache2 server-info mod
2025-05-14 10:22:25 +02:00
slawkens
a161cff003 Add note about highscores being updated x minutes + allow ttl 0 to disable 2025-05-14 10:00:27 +02:00
slawkens
3befde2a1e Do not return -1 in case of freePremium, makes things harder 2025-05-14 09:18:55 +02:00
slawkens
5367df2381 Add latest client versions (14.00 - 15.01) 2025-05-13 16:29:40 +02:00
slawkens
c48b800631 Fix login.php boosted creature & boss (not sure exact version, but should be 14.12 or around)
Thanks @opentibiabr team
2025-05-13 16:29:19 +02:00
slawkens
ef6549c17c nothing important: tabs & spaces 2025-05-13 15:20:25 +02:00
slawkens
629fd18ea1 Update cypress version to ^14.3.3 2025-05-12 17:36:50 +02:00
slawkens
da15105118 Fix typo, @gpedro I hate you! :PPP 2025-05-12 17:36:34 +02:00
slawkens
4ca58b4178 Fix PHP 8.4 deprecation warnings
"Implicitly marking parameter $var as nullable is deprecated, the explicit nullable type must be used instead"
2025-05-09 13:45:46 +02:00
slawkens
03e2752139 Use optionally separate folder for views (thanks @Scrollog for idea) 2025-05-09 13:38:48 +02:00
slawkens
2fece725a4 Improve cypress workflow: add php 8.4 + ignore upload warnings 2025-05-09 13:23:04 +02:00
slawkens
c24c580796 Fix installMenus when theme/template was removed from disc 2025-05-09 13:09:44 +02:00
slawkens
620a47da72 Update Hooks.php 2025-05-08 20:05:27 +02:00
slawkens
9b75011224 New filter: HOOK_FILTER_ROUTES 2025-05-08 20:05:18 +02:00
slawkens
5b4b7b8a97 triggerFilter -> pass by reference (faster x5) 2025-05-08 20:05:08 +02:00
Slawomir Boczek
99997eb57d Feature/twig hooks filters (#258)
* feat: Hooks filters

* Cleanup
2025-05-08 20:04:54 +02:00
slawkens
73a5829974 Better monster images (no image not found anymore) + use cache 2025-05-05 21:21:54 +02:00
slawkens
497338c2d6 Update robots.txt 2025-05-04 17:20:23 +02:00
slawkens
beb348fe27 testing something 2025-05-04 17:20:12 +02:00
slawkens
5b1bd4f005 Update robots.txt 2025-05-04 17:00:22 +02:00
slawkens
f09606d01b Just testing something 2025-05-04 16:54:49 +02:00
slawkens
67ab425bb9 Add float & double types to the Settings 2025-05-04 09:14:30 +02:00
slawkens
113473f256 Add optional param _page_only for single-page apps etc. 2025-05-03 22:04:08 +02:00
slawkens
d6ac4e8d85 Update index.php 2025-05-03 21:04:13 +02:00
Slawomir Boczek
6845869838 Hoping for a better appear in search engines.. 2025-04-27 17:50:57 +02:00
slawkens
0fbd4bf1be nginx: block additionally *.sql 2025-04-24 13:44:38 +02:00
slawkens
1e45d5c393 Optimize .htaccess FilesMatch: Block access to *.md/json/dist/sql 2025-04-24 13:43:50 +02:00
slawkens
dbea69f314 Fix if user removes the menu category 2025-04-23 20:41:50 +02:00
slawkens
4e6aa0f262 Fix boostedCreature fetch on login.php 2025-04-23 18:05:14 +02:00
slawkens
fa1f927082 Update login.php 2025-04-23 18:04:54 +02:00
slawkens
de0512f11a Start v1.4.1-dev 2025-04-22 15:57:23 +02:00
slawkens
93c09b3380 Release v1.4 2025-04-22 13:42:55 +02:00
slawkens
d47195a787 Do not autoload sub-folders if autoload pages is disabled 2025-04-22 13:30:11 +02:00
slawkens
b618084d50 Fix headline.php: change image format to .png cause of black background 2025-04-21 23:43:57 +02:00
slawkens
d0d0af289d Refactor code + use clearCache() instead 2025-04-20 21:32:46 +02:00
slawkens
1d0c173e7d Clear cache on plugin enable/disable, fixes some issues with plugin pages 2025-04-20 21:30:59 +02:00
slawkens
4e7c894cf2 Nothing.. 2025-04-20 21:29:37 +02:00
slawkens
b71555d60d Update router.php 2025-04-20 21:29:22 +02:00
slawkens
c2bf94fb23 Fix: display 404 error instead of 500 when page has been removed from filesystem 2025-04-20 20:40:10 +02:00
João
8cf3409077 SQL Syntax Standardization (#298)
* Update schema.sql

* Update schema.sql
2025-04-18 23:17:35 +02:00
slawkens
e0043b1300 Fix warning 2025-04-18 20:44:11 +02:00
slawkens
86cb5821f6 README.md corrections
* Add links to docs & faq
* add info about 2.x dev version
* fix some grammar typos
2025-04-18 19:42:33 +02:00
slawkens
82a533d88c Add $db->hasTableAndColumns($table, $columns), credits to @opentibiabr Team 2025-04-18 18:12:56 +02:00
slawkens
ceaa0639e6 feat: admin-pages (can add admin pages through plugins)
Also possibility to overwrite default myaac admin pages
2025-04-18 13:57:53 +02:00
slawkens
6844f4392a Change logout button color 2025-04-06 23:46:52 +02:00
slawkens
6d8f4718a1 pages in theme folder have precedence over normal pages 2025-04-06 22:37:36 +02:00
slawkens
f40b986b59 Small changes in account.login.html.twig
* change inputs width to 100%
* fix form closing
* formatting
2025-04-06 17:00:59 +02:00
slawkens
190697ce98 Update config.php 2025-04-06 16:43:30 +02:00
slawkens
64f6d3abca Add noSubmit option to buttons.base 2025-04-06 16:43:19 +02:00
slawkens
e6f05a2731 Plugin name is required, version is optional 2025-04-06 16:41:28 +02:00
slawkens
6a0356aa0f Update version 2025-04-04 21:31:17 +02:00
slawkens
50d649dbde Release v1.3.3 2025-04-04 21:25:19 +02:00
slawkens
6c568fd36a Fix uninstall plugin when plugin is disabled 2025-04-04 21:08:49 +02:00
slawkens
fa6b6aa153 Display more info when error parsing config.lua value 2025-04-04 20:07:42 +02:00
slawkens
ae639d65b0 PHP 8 things 2025-04-03 20:39:27 +02:00
slawkens
35e2483de8 Change root folder to /var/www/html, like in default config 2025-04-02 19:48:23 +02:00
slawkens
bbf923e1a6 Update common.php 2025-04-01 07:56:29 +02:00
slawkens
211b6ea698 Update CHANGELOG-1.x.md 2025-04-01 07:37:43 +02:00
slawkens
6d156ae080 Update CHANGELOG-1.x.md 2025-04-01 07:29:43 +02:00
slawkens
a5b3940e59 Prepare to release 1.3.2 2025-04-01 07:28:36 +02:00
slawkens
dbf73d0b61 Show/hide IP Ban Protection options depending on the value (enabled/disabled) 2025-03-31 20:38:42 +02:00
slawkens
65696f63e3 Fix debugbar/admin panel menu when using custom base_dir 2025-03-31 18:13:45 +02:00
slawkens
6341093578 Update version 2025-03-30 07:10:16 +02:00
slawkens
d25c71857f Do not require init.php in cache:clear command 2025-03-30 07:10:05 +02:00
slawkens
7dcb5c4a1f Update version to 1.x-dev 2025-03-26 22:02:56 +01:00
slawkens
ff1723b756 Release v1.3.1 2025-03-19 20:37:44 +01:00
slawkens
1a5771ad51 Fix migrate:run command 2025-03-16 20:33:53 +01:00
slawkens
6fac883659 Replace links with from accountmanagement to account/manage 2025-03-16 12:39:07 +01:00
slawkens
4a6896b446 getPremDays: returns -1 if freePremium 2025-03-15 22:48:59 +01:00
slawkens
0852fba6f0 Release v1.3 2025-03-10 20:26:25 +01:00
slawkens
9239a4f419 Fix the second "Save" button -> addition to previous commit 2025-03-10 12:46:33 +01:00
slawkens
00fe1adc15 Fix: add possibility to remove all menu items 2025-03-10 10:48:12 +01:00
slawkens
c2f55791c0 Nothing important, just better code style 2025-03-03 20:07:59 +01:00
slawkens
464492d826 Update OTS_Account.php 2025-02-26 16:16:45 +01:00
slawkens
887b5068ad Fix house links 2025-02-15 12:15:35 +01:00
slawkens
4c5cc8b573 Change monster link to $_GET ?name= 2025-02-15 12:03:44 +01:00
slawkens
529bdcf016 Use latest outfit-images host from @gesior 2025-02-12 18:20:24 +01:00
slawkens
3e3f4bb5a5 Fix long title on headline.php 2025-02-12 16:17:03 +01:00
slawkens
aa52df6e2e Fix menu colors once again, plus add !important tag 2025-02-09 20:54:47 +01:00
slawkens
3b31915c22 Update CHANGELOG.md 2025-02-09 12:25:56 +01:00
slawkens
1c6cda4df9 Update year 2025-02-09 11:50:14 +01:00
slawkens
cf51f7aa8d Release v1.2 2025-02-09 11:32:34 +01:00
slawkens
ed89b99cd1 Addition to previous commit, allow list types with spaces 2025-02-09 01:29:32 +01:00
slawkens
9d7fc98e1e Fix if vocation name has more words 2025-02-09 01:16:15 +01:00
slawkens
f646856e20 Unification of the variable menu_default_links_color 2025-02-09 01:02:14 +01:00
slawkens
f97f8cbe87 Move admin.menus.header html to twig 2025-02-09 00:47:46 +01:00
slawkens
3da3e62c5b Option to reset menus 2025-02-09 00:42:11 +01:00
slawkens
d5dd7297b5 Fix deprecation warnings from jquery 2025-02-09 00:03:39 +01:00
slawkens
73de93a561 Rework menus: Different categories can have different colors 2025-02-08 23:56:58 +01:00
slawkens
ae1161d770 Add template_name to twig variables 2025-02-08 23:43:15 +01:00
slawkens
4455964db4 Update cypress.yml 2025-02-02 22:41:31 +01:00
slawkens
84870dbf2d Update release.sh 2025-02-02 22:39:06 +01:00
slawkens
329153fda6 Fix branch name in workflows 2025-02-02 22:38:40 +01:00
slawkens
4b6024dc45 Save settings in a transaction 2025-02-02 22:36:18 +01:00
slawkens
28fef952f8 feat: Settings: enable Save button only if changes has been made 2025-02-02 22:36:17 +01:00
slawkens
4fda4f643b feat: Settings: password input with hide/show options 2025-02-02 21:55:16 +01:00
slawkens
19686725dc Add HOOK_INIT, executed just after $hooks are loaded 2025-02-02 16:17:49 +01:00
slawkens
a73fb1003e Fix HOOK_STARTUP location 2025-02-02 16:17:24 +01:00
slawkens
b46ddb43d0 Twig session(key) function + reworked session functions to accept multi-array like in Laravel
Important: getSession returns NULL now instead of false if session value not found
2025-02-02 16:16:59 +01:00
slawkens
de468a8dcd Fixed need to click on button second time 2025-02-02 14:22:57 +01:00
slawkens
ea51ad27c3 Fix online status + vocation for TFS 0.x 2025-02-01 00:35:22 +01:00
dependabot[bot]
d2a4748a59 Bump twig/twig from 3.18.0 to 3.19.0 (#284)
Bumps [twig/twig](https://github.com/twigphp/Twig) from 3.18.0 to 3.19.0.
- [Changelog](https://github.com/twigphp/Twig/blob/3.x/CHANGELOG)
- [Commits](https://github.com/twigphp/Twig/compare/v3.18.0...v3.19.0)

---
updated-dependencies:
- dependency-name: twig/twig
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-29 20:00:58 +01:00
slawkens
a1ed209591 Update README.md 2025-01-27 22:58:32 +01:00
slawkens
34321613d6 Start v1.1.1 2025-01-27 22:57:40 +01:00
slawkens
19b290feb7 Update CHANGELOG.md 2025-01-27 22:48:32 +01:00
slawkens
9ab25abcdf Release v1.1 2025-01-27 22:30:18 +01:00
slawkens
ea753278a0 Secure direct access to template.php 2025-01-27 22:15:00 +01:00
slawkens
4d749b8815 Fix error in CLI, where BASE_URL is not defined 2025-01-24 21:42:52 +01:00
slawkens
07012f786b Ignore lua/ folder 2025-01-22 21:45:07 +01:00
slawkens
a45ceab83a Make players.comment and guilds.description VARCHAR 2025-01-22 21:44:58 +01:00
slawkens
669c447fca Fix hook ACCOUNT_LOGIN_BEFORE_ACCOUNT location 2025-01-21 21:45:28 +01:00
slawkens
da43b32ff0 Nothing important, code refactor 2025-01-21 20:43:59 +01:00
slawkens
cbe0d187b4 Formatting and types hint 2025-01-20 16:31:54 +01:00
slawkens
c5d5bb8067 Adjust mailer settings to latest gmail 2025-01-18 16:18:47 +01:00
slawkens
e85ce193be Add forum to the list 2025-01-18 11:18:21 +01:00
slawkens
3fb2675b5a Fix tibiacom menus 2025-01-18 11:11:35 +01:00
slawkens
b7de8b32eb Revert "Fix menus like char-bazaar/auctions-history etc."
This reverts commit dd47423157.
2025-01-18 11:05:15 +01:00
slawkens
89be68731e Update CHANGELOG.md 2025-01-18 00:11:18 +01:00
slawkens
10dd818b13 Optimize $player->isOnline() function 2025-01-17 22:49:40 +01:00
slawkens
13a1598a46 Nothing important: Convert spaces to tabs 2025-01-17 22:38:27 +01:00
slawkens
4f6178eca0 Initialize menus with menu_categories
If user add custom categories, it will fix an issue where Menu is not collapsed
2025-01-17 21:07:02 +01:00
slawkens
dc2b5afd99 functions_custom.php are not optional 2025-01-17 17:12:21 +01:00
slawkens
11cee81c5f Additional fix to previous commit 2025-01-17 16:36:05 +01:00
slawkens
d639e77d04 tibiacom: Fix the closing MenuBottom if there are extra categories 2025-01-17 16:24:30 +01:00
slawkens
dd47423157 Fix menus like char-bazaar/auctions-history etc. 2025-01-17 11:16:19 +01:00
slawkens
b02c7f4239 Fix note message 2025-01-14 19:29:47 +01:00
slawkens
b5b2e3fd78 Update CHANGELOG.md 2025-01-14 00:19:16 +01:00
slawkens
030d15f0cd Fix branch name 2025-01-14 00:17:33 +01:00
slawkens
b6b7592226 Release v1.0.1 2025-01-13 23:17:58 +01:00
slawkens
fb10741a02 Fix typo in account word 2025-01-13 23:15:57 +01:00
slawkens
5e9c868dfa Fix tibiacom account & news menu links 2025-01-13 23:05:16 +01:00
slawkens
0904b1bb87 Fix phpstan 2025-01-13 22:23:43 +01:00
slawkens
faa60f5e9a Fix phpstan and phplint branches 2025-01-13 22:15:48 +01:00
slawkens
620e0f62e4 Fix cypress run workflow 2025-01-13 22:10:52 +01:00
slawkens
2ae2ec3353 Fix link to monsters 2025-01-13 22:09:15 +01:00
slawkens
b323d9cee1 Update cypress to ^13.17.0 2025-01-13 22:09:04 +01:00
slawkens
4f1d1d8043 Update tinymce to ^7.2.0 2025-01-13 21:50:37 +01:00
slawkens
8e5a3afc6e Update myaac version 2025-01-13 21:41:49 +01:00
slawkens
a7311301e2 Update composer.lock 2025-01-13 21:40:16 +01:00
slawkens
ac10236154 Update twig dependency to ^3.11 (disable dependabot alert) 2025-01-13 21:40:09 +01:00
slawkens
dc95bc4bad Merge branch 'master' of https://github.com/slawkens/myaac 2025-01-13 21:18:50 +01:00
dependabot[bot]
0dc7da472f Bump nesbot/carbon from 2.72.5 to 2.72.6 (#276)
Bumps [nesbot/carbon](https://github.com/CarbonPHP/carbon) from 2.72.5 to 2.72.6.
- [Release notes](https://github.com/CarbonPHP/carbon/releases)
- [Commits](https://github.com/CarbonPHP/carbon/compare/2.72.5...2.72.6)

---
updated-dependencies:
- dependency-name: nesbot/carbon
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-13 21:16:29 +01:00
slawkens
43421e56ea Update nginx-sample.conf 2025-01-13 20:34:40 +01:00
slawkens
544d006b6f v1.0 - Hello! 2025-01-12 17:44:18 +01:00
slawkens
085ebbcfde All $cache->set calls should have $ttl 2025-01-12 17:13:25 +01:00
slawkens
77a2c1cec3 Support for plugin themes in menus.php 2025-01-12 16:27:20 +01:00
slawkens
e918591666 Ignore PhpStan error 2025-01-09 22:59:02 +01:00
slawkens
175c2a1f89 Fix PhpStan 2025-01-09 22:52:30 +01:00
slawkens
3b5be1a8db Add player->outfit_url attribute 2025-01-09 22:41:34 +01:00
slawkens
c769962e39 Refactor getTopPlayers function
* Option to getTopPlayers by balance
* use Cache::remember
2025-01-09 22:40:57 +01:00
slawkens
35dfaa28ed Update index.php 2025-01-09 20:57:23 +01:00
slawkens
8e501c0e9c Shorten code with Cache::remember 2025-01-09 15:50:33 +01:00
slawkens
c52ca27126 Fix if someone deletes the default kathrine template 2025-01-09 15:41:22 +01:00
slawkens
41a3cb6f42 vendor should be accessible, cause of 2025-01-09 13:39:05 +01:00
slawkens
eb4b3ada49 Adjust post_ip to support ipv6 2025-01-09 13:10:04 +01:00
slawkens
68bdec7c18 Fix ip size 2025-01-09 13:06:33 +01:00
slawkens
8a612429b2 Use $db->insert instead of manual query 2025-01-09 13:03:55 +01:00
slawkens
16671ea40b Fix change sex price deducted 2025-01-09 09:44:12 +01:00
slawkens
8fb643596f Fix more XSS in forum 2025-01-08 23:22:51 +01:00
slawkens
c2b7286d20 Fix XSS in forum new_post 2025-01-08 23:13:40 +01:00
slawkens
d6c40c836a Fix move_thread by unauthorized user 2025-01-08 22:36:49 +01:00
slawkens
99262c3ebd Fix DataLoader Towns cache 2025-01-07 15:03:39 +01:00
slawkens
b8396d4c84 Fix for TFS 1.4.2 where conditions is NULL 2024-12-29 15:46:02 +01:00
slawkens
b0c8cf2ecd Add $whoopsHandler as variable, can be used by other scripts 2024-12-29 15:45:33 +01:00
slawkens
da1816cc13 use https 2024-12-20 22:42:46 +01:00
slawkens
783d96fc65 Set default_socket_timeout for ipinfo.io checkup 2024-12-20 22:42:35 +01:00
slawkens
988a3f2dbe Display created by id 2024-12-19 22:32:28 +01:00
slawkens
8e0978c1ed Adjustments regarding accounts.id in admin panel -> Accounts editor
getAccountIdentityColumn() function
2024-12-19 22:32:05 +01:00
slawkens
023f1dc598 Support for accounts.id when there is no accounts.name and accounts.number 2024-12-19 21:52:05 +01:00
slawkens
ea5e1d4192 Fix IDE warning about form 2024-12-07 18:53:09 +01:00
slawkens
06188be6e1 Fix $vocs not found 2024-12-07 13:52:52 +01:00
slawkens
2c42de688a Fixes to tibiacom menus ActiveSubmenuItem 2024-12-07 10:28:01 +01:00
slawkens
4ac56e6b15 tabs 2024-12-05 21:49:02 +01:00
slawkens
5e60249603 Update buttons.create_character.html.twig 2024-12-05 21:44:48 +01:00
slawkens
d8b6b749ee Support for button_color (green, red, blue) 2024-12-05 21:44:06 +01:00
slawkens
c5e114d550 Update dependencies 2024-12-04 16:00:30 +01:00
slawkens
706fca8868 update phpneon 2024-12-04 15:46:07 +01:00
slawkens
65adf9ccdd Load deprecated classes + add Cache class 2024-12-03 20:12:03 +01:00
slawkens
bc6663dc44 Fix online vocations numbers, thanks Marko999x 2024-11-25 20:28:00 +01:00
slawkens
e3ffe5d9e1 Display warning if zip extension is not installed 2024-11-23 14:29:16 +01:00
slawkens
c0a66037e0 Fix column not found - hidden/hide 2024-11-22 16:04:48 +01:00
slawkens
17210b717f Execute updated migrations with $up() function 2024-11-22 16:04:19 +01:00
slawkens
5782772b90 Remove bugtracker SQL table as the page has been removed 2024-11-22 15:53:57 +01:00
slawkens
27c44f1bdf schema: Change character set to utf8mb4 (support for Emojis in Menus/Pages/News/Forum etc.) 2024-11-22 15:52:54 +01:00
Slawomir Boczek
3f6ff3a332 Feature migrations up/down (#270)
* Migrations up down

* Add forum model

* Syntactic sugar for db structure changes

* Refactor migrations with $up & $down

* Fix migrations upgrade and downgrade

+ Add option to disable auto migrate

* Add migrate:to command

Usage: php aac migrate:to x (x - database version)

* Show error when mail is not enabled

* Fixes regarding to init.php

* Add migrate command to manually upgrade db, incase auto migrate is disabled

* Fixed rest of the migrations

* Limit max version of database

* Don't allow minus number

* Option to clear specified plugin settings by name

* Version is required

* Fix PHPStan errors

* Unset $up after migration, to prevent executing same migration twice

* Add database version to output

* This is not needed

* Update 5.php

* Set database_auto_migrate on install

* Set blank & color only if current db version supports it

* Fix duplicate function declaration
2024-11-22 15:29:23 +01:00
slawkens
79636280a7 Move current password input to the top, makes more sense 2024-11-19 20:55:53 +01:00
slawkens
38e699ba4b PHP 8.1 is required 2024-11-19 14:21:31 +01:00
slawkens
afb055f2dc More obvious name for parameter in -> installMenus 2024-11-19 14:21:15 +01:00
slawkens
6f58df0467 Update twig.php 2024-11-19 14:08:27 +01:00
slawkens
95343cec02 Change to str_contains 2024-11-19 14:08:24 +01:00
slawkens
8055785c81 Fix installMenus function 2024-11-19 07:48:52 +01:00
slawkens
64e4c08950 MyAAC\Cache 2024-11-19 07:19:43 +01:00
slawkens
12d8faa3ed Do not clear menus by default 2024-11-19 07:05:27 +01:00
slawkens
1e6892971b Change spaces to tabs 2024-11-19 07:03:06 +01:00
slawkens
8ae22accc9 Fix for console displaying REQUEST_URI 2024-11-18 23:49:26 +01:00
slawkens
a2fadc5945 Fixes to installMenus function 2024-11-18 23:48:03 +01:00
slawkens
d0b4065ccf Optimise news management 2024-11-18 15:04:53 +01:00
slawkens
84d37c5a8f Allow OTS_Player to be passed as object to getPlayerLink 2024-11-17 18:07:10 +01:00
slawkens
28a2b34cc1 Update account.management.html.twig 2024-11-12 22:19:21 +01:00
slawkens
bab565fbd0 Update init.php 2024-11-12 22:01:15 +01:00
slawkens
36bd3eb846 New hooks for news management
Can be used for example as discord hooks
2024-11-12 22:01:00 +01:00
slawkens
85bc2342cf Fix missing bracket opening 2024-11-12 21:03:43 +01:00
slawkens
507402171b Patching from master some small adjustments (Account Logs typo + forum new thread show button by @anyeor) 2024-11-12 21:01:14 +01:00
slawkens
941846605c Prefer get_browser_real_ip() over REMOTE_ADDR 2024-11-12 20:59:51 +01:00
slawkens
a4a2480995 Add None vocation to highscores (can be changed to RookStayer in Admin Panel) 2024-11-12 20:51:45 +01:00
slawkens
ddced132cf Fix if highscores_vocation box is disabled causing Choose a vocation dropdown to fail 2024-11-12 20:42:06 +01:00
slawkens
749e8e6f02 Fix choose a skill dropdown 2024-11-11 22:04:06 +01:00
slawkens
7d787b4566 Update database.php 2024-11-10 20:25:46 +01:00
slawkens
7e67e11e16 More understandable argument name 2024-11-10 20:25:42 +01:00
slawkens
011a85d8ae new hook: HOOK_ADMIN_NEWS_ADD 2024-11-10 20:25:17 +01:00
slawkens
382f897322 Update settings.php 2024-11-07 19:07:46 +01:00
slawkens
c980a09146 Rewrite towns loading code, removed OTBM loader (was too slow)
By default load from towns table in db
2024-11-07 19:07:15 +01:00
slawkens
18bd325a44 fix label 2024-11-07 14:44:46 +01:00
slawkens
078e20a9a4 cleanup 2024-11-07 14:44:18 +01:00
slawkens
e96227fbe4 Automatically set selected current one on highscores filters 2024-11-07 14:44:08 +01:00
slawkens
c49c9d99a9 Fix PHP Fatal error 2024-10-27 20:40:48 +01:00
slawkens
a0f1971583 Fix login if limiter is disabled 2024-10-25 19:01:28 +02:00
slawkens
cb5fc84e2e Release v1.0-RC.2 2024-10-25 10:54:03 +02:00
slawkens
29b77035be Update CHANGELOG.md 2024-10-25 10:53:50 +02:00
slawkens
b8c0215720 Fix if loot is empty 2024-10-24 15:55:32 +02:00
slawkens
3100faa645 Fix highscores skills for servers that use player_skills table 2024-10-11 20:35:12 +02:00
slawkens
f7c9a67a96 More fixes to displaying online record 2024-10-04 21:36:13 +02:00
slawkens
e8fedb8d16 One bracket to much.. 2024-10-04 21:26:28 +02:00
slawkens
4e4739e8ab Fix displaying players online record 2024-10-04 21:23:41 +02:00
slawkens
c6cc84a668 Fix RateLimit when cache is disabled 2024-09-19 21:25:54 +02:00
slawkens
95a7c23a70 Use PHP 8 functions 2024-09-14 11:48:56 +02:00
slawkens
a7fe400614 Use Validator::characterName 2024-09-14 11:48:43 +02:00
slawkens
2568046a4d nothing important: brackets 2024-09-14 11:16:47 +02:00
slawkens
7161678c4b Add missing Validator::characterName check 2024-09-12 09:40:01 +02:00
slawkens
93641fc68a New hooks in account manage + create 2024-09-08 15:03:18 +02:00
slawkens
ea7e808508 Add more clients (13.22+) 2024-09-08 14:48:59 +02:00
slawkens
da3fc1fc8c Interesting update from opentibiabr (Uptime readable) 2024-09-08 14:48:42 +02:00
slawkens
201f95caa8 Do not create player if there is no players table in db 2024-09-05 15:36:19 +02:00
slawkens
779aa152fa Do not require players & guilds tables 2024-09-05 15:35:55 +02:00
slawkens
d99b22f98b Fix attempts counting 2024-08-26 15:19:37 +02:00
slawkens
35e28350bd Change spaces to tabs 2024-08-26 15:19:17 +02:00
Gabriel Pedro
327dcb5f87 feat: ratelimit (#267)
* feat: rate limit settings

* fix: section label

* fix: real ip

* fix: real ip
2024-08-26 14:53:09 +02:00
Gabriel Pedro
bc8ada6fe2 fix: verified email for login.php (#265)
* fix: required email login verify

* fix: add missing select column

* Revert "fix: add missing select column"

This reverts commit db79e3118a.
2024-08-25 13:40:32 +02:00
Gabriel Pedro
6183b7ee52 chore: drop raw queries (#266)
* chore: eloquent migrate

* fix: typos
2024-08-25 13:38:58 +02:00
Jonatas
760c3ab017 Highscore frags fixed for TFS 0.3 (#263) 2024-08-16 18:19:44 +02:00
slawkens
ab73d60c61 Fix warning if core.account_country is disabled 2024-08-12 23:01:45 +02:00
slawkens
8d8bdb6dac Fix missing groups variable #262. thanks @Scrollog for reporting 2024-08-12 22:54:23 +02:00
slawkens
71c00aa5e0 Use https for outfit & item images 2024-08-01 23:17:07 +02:00
slawkens
1fcdd54c94 Patching from master
OTS_House refactor code + $db->update with nulls
2024-07-25 15:43:42 +02:00
slawkens
c2ec468246 feat: search by email in accounts editor 2024-07-23 22:56:31 +02:00
slawkens
68118fb7c2 Update phpstan.neon 2024-07-23 08:47:22 +02:00
slawkens
5a69b9a802 Update composer.lock 2024-07-23 08:45:55 +02:00
slawkens
45e63b13c3 Update version to 1.0-RC 2024-07-23 08:35:08 +02:00
slawkens
758a8b3330 Prepare changelog for 1.0-RC
Release Candidate.
2024-07-23 08:30:53 +02:00
slawkens
1843728930 Rename to playerSample 2024-07-23 08:07:59 +02:00
slawkens
cff62ccba4 Another try 2024-07-12 20:54:12 +02:00
slawkens
28f98db9de Fix PHPStan errors in monsters.php 2024-07-12 20:48:27 +02:00
slawkens
da14e125e9 Fix highscores skill links (Thanks @vyroq) 2024-07-12 20:01:12 +02:00
slawkens
cd49dfc799 Set Admin Account verified by default 2024-07-10 18:12:05 +02:00
slawkens
ef79b99b8a Fix monster not found exception 2024-07-10 09:54:54 +02:00
slawkens
9a27403e7d Fixes to account_mail_verify 2024-07-09 23:35:39 +02:00
slawkens
5f63c3b227 Invalidate cached setting 2024-07-09 23:33:00 +02:00
slawkens
203e411b62 Allow account_create_character_create even if account_mail_verify is activated 2024-07-09 23:06:12 +02:00
slawkens
fcb13f3c0f Fixes to account verify - do not allow login without verified email (Thanks @anyeor) 2024-07-09 23:05:36 +02:00
slawkens
d94828772c Rework 5th step of installation, to fix some pointless message about Cache 2024-07-09 22:04:47 +02:00
slawkens
10a739773c Detect tools/ext exists on install to prevent broken installs 2024-07-09 21:29:42 +02:00
slawkens
83b3dc803a Fix 5th step of installer 2024-07-08 19:50:05 +02:00
slawkens
33a47137c9 Fix hooks priority default 2024-06-29 15:09:44 +02:00
slawkens
dc17b701da feat: Hooks priority 2024-06-29 14:05:06 +02:00
slawkens
d30811404b Update players.php 2024-06-28 19:03:06 +02:00
slawkens
a631760dbf Order fraggers by time 2024-06-23 16:10:50 +02:00
slawkens
bc3dcab462 deny all is enough 2024-06-23 09:55:15 +02:00
slawkens
a8d255c04b feat: Plugins pages: subSubFolders 2024-06-14 08:07:52 +02:00
slawkens
813786c768 Update cleanup_players.php 2024-06-14 06:42:45 +02:00
slawkens
0db0ec1aa4 Fix useGuildNick displaying 2024-06-14 06:42:42 +02:00
slawkens
bdc0c43d3f Refactor account routes into sub folders 2024-06-13 22:23:43 +02:00
slawkens
c7a6a539a9 Another approach to fix duplicates - priorities
Priority description: (lower number - higher priority)
1-99 Highest priority - overrides everything, even pages from database, use with caption
100 - default for pages in database
101-999 - recommended range for plugins
1000 - default value for plugins if no other specified
1001 - 9999 - no usage currently
10000 - default myaac routes
2024-06-13 21:35:47 +02:00
slawkens
c1d4b4f80c Make autoload of pages, commands and themes configurable
Not everyone might want them to autoload
2024-06-13 14:36:18 +02:00
slawkens
47a19e85dd Reposition code for setting ranks (addition to previous commit) 2024-06-13 13:07:03 +02:00
slawkens
d9c1b2507c Create guild_rank entries, in case MySQL trigger not loaded 2024-06-13 12:51:29 +02:00
slawkens
4c0739d3e9 Fixed fastRoute duplicate errors 2024-06-13 11:29:06 +02:00
slawkens
afe70a03c5 Fix email_change status 2024-06-11 13:32:22 +02:00
slawkens
3fadf87a7a Fix title on login page 2024-06-11 13:14:15 +02:00
slawkens
c24576165c login.php early exit + fix title 2024-06-11 12:55:02 +02:00
slawkens
1e5c9dcd9b Nothing important, just a space for better look! 2024-06-10 19:43:08 +02:00
slawkens
a04d186c22 Fix highscores frags for TFS 1.x and canary 2024-06-10 18:53:17 +02:00
slawkens
42f99c3edc Fraggers in characters page for TFS 1.x and canary 2024-06-08 23:27:19 +02:00
slawkens
4f4965369d spaces -> tabs 2024-06-05 21:53:58 +02:00
slawkens
57b47ab798 Fix if <flags> are not present in monster.xml 2024-06-05 21:51:50 +02:00
slawkens
9ea2a5067f Order towns by id 2024-06-05 15:10:55 +02:00
slawkens
ec96985872 Revert some breaking change 2024-06-01 18:44:06 +02:00
slawkens
9f2a51b351 Spaces and remove useless function 2024-06-01 15:53:34 +02:00
slawkens
a1d7c94166 Closing tag 2024-06-01 15:51:28 +02:00
slawkens
0c3e3e16dd Set default group_id 2024-06-01 15:51:21 +02:00
slawkens
45dda5e834 Add HOOK_ACCOUNT_CREATE_CHARACTER_* hooks 2024-05-31 22:59:52 +02:00
slawkens
32ae4dde20 Fix closing table elements 2024-05-31 22:57:44 +02:00
slawkens
d3f03fa735 Better place for INSTALL_FINISH hook 2024-05-31 19:21:37 +02:00
slawkens
44eff8092c Fix settings title 2024-05-31 18:30:01 +02:00
slawkens
8ef3d06f1e Fix duplicated routes 2024-05-31 17:22:39 +02:00
slawkens
60bd64a639 Update router.php 2024-05-30 20:40:15 +02:00
slawkens
a1bcb217ec Fixes regarding not working google recaptcha (+few previous commits) 2024-05-30 17:36:07 +02:00
slawkens
933b681a9f Fixed if account_country is disabled 2024-05-30 14:25:31 +02:00
slawkens
e9aea17e1b Close form in proper place 2024-05-30 14:21:52 +02:00
slawkens
060400b074 Revert "Use tables headline for account.create.html.twig"
This reverts commit 64387e085b.
2024-05-30 13:48:59 +02:00
slawkens
6be4a42c5a Revert "Fix form id"
This reverts commit d225c2da26.
2024-05-30 13:48:53 +02:00
slawkens
1e8198635e Enable dev mode on install, prevent noobs asking white page questions 2024-05-30 12:00:26 +02:00
slawkens
be78a0fc45 Do adjustments only if table exist 2024-05-30 11:32:03 +02:00
slawkens
08ac8ebade Add HOOK_INSTALL_FINISH 2024-05-30 11:31:41 +02:00
slawkens
66ecc487a1 One more early exit 2024-05-30 11:18:06 +02:00
slawkens
9e23ec6745 Early exit in 7-finish install 2024-05-30 11:14:16 +02:00
slawkens
968899ef77 Pass $playerSample as parameter to hook 2024-05-30 10:09:31 +02:00
slawkens
3844ad0d71 Fix warnings in basic.js 2024-05-30 09:49:02 +02:00
slawkens
c93bf5a984 create_character_name_min_length => 3 2024-05-30 09:02:19 +02:00
slawkens
50336a810b Fix blessings longer than 3 characters 2024-05-30 08:23:31 +02:00
slawkens
48f6ca0eba Tabs + spaces 2024-05-30 08:20:59 +02:00
slawkens
30107222d4 Add getLongLong function to OTS_Buffer 2024-05-30 08:20:33 +02:00
slawkens
f92b275f70 Update version to beta.2 2024-05-23 23:44:29 +02:00
slawkens
504242fb84 Do not create news about myaac, if any news already exist (on installation) 2024-05-23 23:40:27 +02:00
slawkens
e2bab4220b Fix composer install 2024-05-18 22:31:59 +02:00
slawkens
0b4c34a823 Update phpstan.yml 2024-05-18 22:20:00 +02:00
slawkens
c5aa9a4684 Do not include phpstan into release 2024-05-18 22:19:23 +02:00
slawkens
301afe190b Remove node_modules in release script 2024-05-18 22:01:41 +02:00
slawkens
c35cc83e4f They say composer.lock should be commited - let it be! 2024-05-18 22:01:30 +02:00
slawkens
3ba9d8f780 Fix date 2024-05-18 21:56:01 +02:00
slawkens
06f228509b Update release.sh 2024-05-18 21:53:41 +02:00
slawkens
39e682dfd2 htmlspecialchars seems to be better here (?) 2024-05-16 18:58:54 +02:00
slawkens
6f209440e0 Fix XSS in monsters.php, thanks to @gesior 2024-05-15 22:18:39 +02:00
slawkens
b2a1675de3 Fix if account_country is disabled 2024-04-16 13:32:34 +02:00
slawkens
163877d303 Update account.generate_recovery_key.html.twig 2024-04-16 11:38:10 +02:00
slawkens
a4d11c1a12 Rename variables 2024-04-16 10:45:34 +02:00
slawkens
8cf4e3da02 Fix change_info if account_country is disabled 2024-04-15 21:54:18 +02:00
slawkens
e0230c5237 Adjustments in success.html.twig 2024-04-15 21:47:21 +02:00
slawkens
127e03081c Support for subfolders in plugins/pages 2024-04-15 21:21:16 +02:00
slawkens
e9c6017e60 Fix forum table header text color 2024-04-15 20:35:53 +02:00
slawkens
d5915df37e Fix redirects in forum + polls 2024-04-14 16:06:57 +02:00
slawkens
eb0c2a7674 Post-fix redirect 2024-04-14 16:02:55 +02:00
slawkens
d225c2da26 Fix form id 2024-04-14 15:59:23 +02:00
slawkens
d95e280b9a Use tables headline for account.redirect.html.twig 2024-04-14 15:25:13 +02:00
slawkens
64387e085b Use tables headline for account.create.html.twig 2024-04-14 15:06:43 +02:00
slawkens
e1f507cf2d Extend timeout to fix broken workflow-runs 2024-04-12 15:15:23 +02:00
slawkens
c92a410209 Don't allow redirect to external website 2024-04-08 19:08:21 +02:00
slawkens
1186f94e21 Add Twig TypeCastingExtension 2024-04-08 10:08:48 +02:00
slawkens
f837b3133d deny vendor, composer.json, changelog.md etc. in nginx config sample 2024-04-06 19:51:34 +02:00
slawkens
9106f1e4ce Update CHANGELOG.md 2024-04-06 19:16:22 +02:00
slawkens
a62cfc5272 Update CHANGELOG.md 2024-04-06 15:08:39 +02:00
slawkens
6229736d07 getPlayerLink -> colored 2024-04-01 23:40:53 +02:00
slawkens
6807339056 Colored (online/offline) player links 2024-04-01 23:33:00 +02:00
slawkens
ffaa0729ac Add player->getOutfit function 2024-04-01 23:19:12 +02:00
slawkens
03cc09b8c7 Adjust submit button 2024-04-01 23:10:00 +02:00
slawkens
6d4724f4f4 Squashed commit of the following:
commit da18629d16
Author: slawkens <slawkens@gmail.com>
Date:   Mon Apr 1 21:53:53 2024 +0200

    Fixes to tables headline

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

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

* Fix intend

* More fixes

* Update phpstan.neon

* phpstan level 2

* Move errors ignoring into phpstan.neon

* phpstan level 3

* Don't ignore templates folder

* Something from level 4

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

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

Also: custom commands can be added via Plugins: just need to return new class instance that extends \MyAAC\Commands\Command in plugins/*/commands folder
2024-01-26 23:19:39 +01:00
slawkens
c59bacea93 Fix page title if the index.php is present 2024-01-25 23:11:13 +01:00
slawkens
f719c02050 Feature: auto-load themes (previously templates) from plugins/*/themes/* 2024-01-25 23:06:10 +01:00
slawkens
0698e7b5f5 Typo 2024-01-25 22:29:28 +01:00
slawkens
c594dfd14b Feature: auto-load pages in plugins/*/pages/*.php 2024-01-25 22:29:19 +01:00
slawkens
514c4a037a admin.links style 2024-01-25 22:02:08 +01:00
slawkens
b894f75e74 Put admin.links in <table> to fix position + remove bootstrap classes (didnt worked anyway) 2024-01-25 22:01:35 +01:00
slawkens
d2a3a9a8da System-solution for styled tables, that works with every template 2024-01-25 21:57:20 +01:00
slawkens
3f4c02a327 bugtracker has been removed 2024-01-13 10:18:24 +01:00
slawkens
199672e0c8 Fix donate_column 2024-01-13 10:12:08 +01:00
Danilo Pucci
02adb87fac - adding check before flush buffer (#245) 2024-01-01 23:32:26 +01:00
slawkens
b4448f7279 Silently ignore if the hook does not exist 2023-12-28 19:13:14 +01:00
slawkens
687c9a6690 feature: color-styled tables in tinymce editor 2023-12-12 17:58:17 +01:00
slawkens
2b86ba94fe Cleanup tabs 2023-12-12 14:37:12 +01:00
slawkens
a9fb5dffa3 Fix account manage redirect 2023-12-09 09:26:33 +01:00
slawkens
da77ec20ef Delete bugtracker, it will be included as plugin 2023-12-08 23:56:29 +01:00
slawkens
6fd141eca6 composer --prefer-dist --optimize-autoloader 2023-11-29 22:34:26 +01:00
slawkens
e17dde0dca Fix session fixation 2023-11-27 23:52:36 +01:00
slawkens
d1046ba21d Fix forum XSS 2023-11-27 22:56:38 +01:00
slawkens
98332f1483 Fix XSS in bugtracker.php 2023-11-27 22:29:24 +01:00
slawkens
1423046039 Sort changelogs by date + make sortable in admin panel 2023-11-25 20:09:42 +01:00
slawkens
9c60beeed0 I like this color better - teams page adjustment 2023-11-25 16:56:45 +01:00
slawkens
336b6ac530 Fix mango signature warnings 2023-11-25 16:33:48 +01:00
slawkens
c71722fc52 Fix warning 2023-11-25 16:24:18 +01:00
slawkens
4d8d574089 Fix missing query_string in nginx sample config
Causes missing parameters in $_GET query
2023-11-25 16:24:08 +01:00
slawkens
e74fbe5bfd Update account.lost.form.html.twig 2023-11-25 15:47:53 +01:00
slawkens
48e9a1ed51 Fix account lost interface links 2023-11-25 15:44:34 +01:00
slawkens
56631bdf27 New hook: HOOK_ACCOUNT_CREATE_CHARACTER_AFTER
Possibility to change character after create
2023-11-25 13:53:50 +01:00
slawkens
b1224d9d1a clearRouteCache on database pages change 2023-11-25 13:37:24 +01:00
slawkens
e18ada3d9d Fix default access for database pages 2023-11-25 13:30:48 +01:00
slawkens
c8218f69a5 Fix undefined variable 2023-11-25 13:08:56 +01:00
slawkens
f991a8c817 clearCache after install plugin 2023-11-25 11:09:45 +01:00
slawkens
36ec2e1e56 Add option to execute "install" part of the plugin 2023-11-25 10:10:15 +01:00
slawkens
19c06df300 Insert new setting if it doesn't exist yet 2023-11-24 21:03:31 +01:00
slawkens
b2d5d6f115 Fix backward support, needs to be before router.php 2023-11-23 20:03:15 +01:00
slawkens
5769ac8bb4 Fix onlineTable relation, fixed online status in highscores 2023-11-23 20:02:18 +01:00
slawkens
41c9f54e4b Fix the fix 2023-11-11 21:32:00 +01:00
slawkens
8ef238c96c Fix default option for options 2023-11-11 21:30:10 +01:00
slawkens
9ffb7f5fa9 Move monsters page settings to other tab + some small adjustments 2023-11-11 21:18:00 +01:00
slawkens
8b5464f8f8 Update init.php 2023-11-11 21:16:45 +01:00
slawkens
f008591580 Make links in settings desc clickable 2023-11-11 21:16:34 +01:00
slawkens
1d5b751fe1 Fix Settings:save for other plugins 2023-11-11 18:44:48 +01:00
slawkens
37bde7df22 Use str_contains + str_starts_with 2023-11-11 16:09:44 +01:00
slawkens
89deca1adb Fix empty PAGE 2023-11-11 16:09:31 +01:00
slawkens
c996f25d8d Fix guild leave 2023-11-11 15:28:41 +01:00
slawkens
d291f694d2 Update .gitignore 2023-11-11 15:24:49 +01:00
slawkens
cee1e67d3d Fix highscores_ids_hidden 2023-11-11 15:02:38 +01:00
483 changed files with 17133 additions and 13795 deletions

View File

@@ -1,9 +1,9 @@
name: Cypress name: Cypress
on: on:
pull_request: pull_request:
branches: [develop] branches: [main]
push: push:
branches: [develop] branches: [main]
jobs: jobs:
cypress: cypress:
@@ -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', '8.4' ]
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: main
- 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,30 @@ 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
if-no-files-found: ignore
- 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
if-no-files-found: ignore
- name: Upload PHP Logs
uses: actions/upload-artifact@v4
if: always()
with:
name: php-log-${{ matrix.php-versions }}-${{ matrix.ots }}
path: php.log

View File

@@ -1,9 +1,9 @@
name: PHP Linting name: PHP Linting
on: on:
pull_request: pull_request:
branches: [develop] branches: [main]
push: push:
branches: [develop] branches: [main]
jobs: jobs:
phplint: phplint:

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

@@ -0,0 +1,46 @@
name: "PHPStan"
on:
pull_request:
branches: [main]
push:
branches: [main]
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', '8.4' ]
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
extensions: "intl, zip"
ini-values: "memory_limit=-1"
php-version: "${{ matrix.php-version }}"
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
# Use composer.json for key, if composer.lock is not committed.
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
- name: "Install composer dependencies"
run: "composer install"
- name: "Run PHPStan"
run: "/usr/bin/php vendor/bin/phpstan analyse"

8
.gitignore vendored
View File

@@ -4,17 +4,20 @@ Thumbs.db
# #
/.htaccess /.htaccess
lua
# composer # composer
composer.lock composer.phar
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
@@ -73,6 +76,3 @@ landing
# system # system
system/functions_custom.php system/functions_custom.php
# others/rest
system/pages/downloads.php

View File

@@ -6,7 +6,7 @@
Options -MultiViews Options -MultiViews
</IfModule> </IfModule>
<FilesMatch "^(CHANGELOG\.md|README\.md|composer\.json|composer\.lock|package\.json|package-lock\.json|cypress\.env\.json)$"> <FilesMatch "^(.*\.md|.*\.json|.*\.dist|.*\.sql|CHANGELOG|README|composer\.lock)$">
Require all denied Require all denied
</FilesMatch> </FilesMatch>

344
CHANGELOG-1.x.md Normal file
View File

@@ -0,0 +1,344 @@
# Changelog
## [1.7 - 22.06.2025]
### Added
* Feature: plugins versions check (#310)
* New hooks: HOOK_ACCOUNT_MANAGE_AFTER_CHARACTERS, HOOK_GUILDS_AFTER_MANAGE_BUTTON (https://github.com/slawkens/myaac/commit/c074a48f245df55646b6705737f667b6a84149b2, https://github.com/slawkens/myaac/commit/e6100a1b72de8695bba1dae9ba4e28bfdce47b10)
* Add OTS_Toolbox::getVocationName(id, promotion) + OTS_Player->isNameLocked() (https://github.com/slawkens/myaac/commit/e222957893c4a1de0dc8dbba55bce1a43418d275, https://github.com/slawkens/myaac/commit/522f6c11d835afd36fd07a07074d96d7e219b488)
* Add missing csrf in more places, causing white page with error about Request (https://github.com/slawkens/myaac/commit/dca904e61d21d856bf809070e7652803a2df0f58, https://github.com/slawkens/myaac/commit/c720ccc451ff90ef40b2a1595468d061ffd7e1e4)
### Changed
* Revamped online page (https://github.com/slawkens/myaac/commit/9a90e4aae280e607430511c6727d9a714b11f4c5, https://github.com/slawkens/myaac/commit/4767120043b09141870383e249f3729638d53dc2)
* Better $title inventing (https://github.com/slawkens/myaac/commit/0c95bcfd06b68b21512e477646ef7bd3a0d4912b)
### Fixed
* Use apcu cache clear (https://github.com/slawkens/myaac/commit/b329da52aae9d0e21120a6444d3caf442420ce50, https://github.com/slawkens/myaac/commit/566c2a9151ab6392286f74e26853faa19a1b4f24)
* fix: boostedcreatures for 13.40 (by @GooseWithAKnife) (#307)
## [1.6.1 - 11.06.2025]
### Fixed
* Fixed "Request has been cancelled due to security reasons", cause of missing csrf() in twig files (https://github.com/slawkens/myaac/commit/10cd71a6630ffec91b43a26a6d685b66c5836a6a)
* Fix: Ignore duplicated route exception (https://github.com/slawkens/myaac/commit/9d8e9d27bd87167d8d4005942a6af62bfe4c0892)
### Changed
* Move counter & visitors code before router (In case someone wants to include that info on page) (https://github.com/slawkens/myaac/commit/f78285030708ad3c74ab048711f73bbf3ee5281e)
* Set TinyMCE license key to gpl (Avoid warning message in browser console) (https://github.com/slawkens/myaac/commit/8d29fdb98b92dbc3d2853ef88a185c67036b4a77)
### Removed
* Remove deprecated TinyMCE plugin - template (https://github.com/slawkens/myaac/commit/309c1fb715b882e67cb673b1544a03befbf64a22)
## [1.6 - 03.06.2025]
### Added
* Add new setting/configurable: site_url, prevents domain spoofing (https://github.com/slawkens/myaac/commit/d8a6090be382c35c19117cfef964b594ed02b8d4)
* Add new account coins setting (https://github.com/slawkens/myaac/commit/28886551e86fe562172c4c7f2afb89a2e7672c2e)
* autoload: settings/install/init.php (https://github.com/slawkens/myaac/commit/e5749437074c3b3556628a2aeb5bad2edf97bde0, https://github.com/slawkens/myaac/commit/7d213f479a7e40c6254069b5fc4e578dc32bf8d9, https://github.com/slawkens/myaac/commit/207d6bc69120aba1af2b51808f17e0059b571fed)
* Protect against csrf in more places (accounts & guilds & forums pages) (https://github.com/slawkens/myaac/commit/6eda38603c8ed7e99b92a78a4600b1245377f74d, https://github.com/slawkens/myaac/commit/e776bd52beb3064a9e694efd1b9021ec972ee2f6, https://github.com/slawkens/myaac/commit/84d502bf105f2a789481fba1acc820d236b4de66)
* Added two new hooks for pages loaded from database (custom pages): HOOK_BEFORE_PAGE_CUSTOM, HOOK_AFTER_PAGE_CUSTOM (https://github.com/slawkens/myaac/commit/c961a1ebf837f2ab1734a825ff2c57b4937610c9)
* Add global variables into $hooks->executeFilter (https://github.com/slawkens/myaac/commit/8fdea943768b20193eede99d60313ee84511a0be)
* Add getNPCsCount() to OTS_InfoRespond (https://github.com/slawkens/myaac/commit/7d435ff6433ef1fb2295ee79ed043ee10dc725e9)
### Fixed
* Allow [] in character name (https://github.com/slawkens/myaac/commit/de6603a51347b9e656c58637ed9971fffdd7cedd)
* Do not allow access to tools/ folder after install (https://github.com/slawkens/myaac/commit/6e0f5913831f8dba69fd2d1505be3e2a303c6324)
* Fix CHANGELOG-1.x.md loading in admin panel (https://github.com/slawkens/myaac/commit/4a30fb495dbfbe1d434e8d52419eaf44fe517aee)
* Fix links not working in admin dashboard modules (https://github.com/slawkens/myaac/commit/be7b27c31aa3bbd6c0289c34d1e61139a3fe015c)
* Fix twig variables: logged + account_logged being not set directly after login (https://github.com/slawkens/myaac/commit/1e9b10d6489c488cadf7f6ed17b42f1ea6c767a8)
### Changed
* OTS_ServerInfo -> move setTimeout out of class - Possibility to use the class without MyAAC (https://github.com/slawkens/myaac/commit/40d65a6613149fda51bdceb82c807e5301a3388b)
## [1.5 - 14.05.2025]
### Added
* Feature/twig hooks filters (#258)
* Add latest client versions (14.00 - 15.01) (https://github.com/slawkens/myaac/commit/5367df23812c6182863353c9a39fd7fb0b743f4b)
* db variable to twig (https://github.com/slawkens/myaac/commit/5ed1aec28e146b871a75597411d12e42a067f4e6)
* New filter: HOOK_FILTER_ROUTES (https://github.com/slawkens/myaac/commit/9b75011224f385db8b27e109bfeb28e75b9d779c)
* Allow optionally separate folder for views (thanks @Scrollog for idea) (https://github.com/slawkens/myaac/commit/03e275213901a89edb0ebb8974b776a992ab391f)
* Add float & double types to the Settings (https://github.com/slawkens/myaac/commit/67ab425bb9796d9d123296e3fda542fa8f7f05ee)
* Add optional param _page_only for single-page apps etc. (https://github.com/slawkens/myaac/commit/113473f2560aab6d364c301cc14a8b5ba8f309f4)
### Changed
* Change OTS_Account->getPremDays to not return -1 in case of freePremium (https://github.com/slawkens/myaac/commit/3befde2a1e4d24a011311e785f15185db57e19b8)
* Add note about highscores being updated x minutes + allow ttl 0 to disable cache (https://github.com/slawkens/myaac/commit/a161cff00329da6f970f3a70967fe8346fe92bbc)
* Better monster images (no image not found anymore) + use cache (https://github.com/slawkens/myaac/commit/73a5829974ceca3f02d7925d5cfbd5fa50b1bbd2)
* Rename server-info -> ots-info, changelog -> change-log (Due to conflict with apache2 server-info mod) (https://github.com/slawkens/myaac/commit/3949d84e5d7631f332111b6d00278bddbd0ad10a)
* Move rules page to admin panel (https://github.com/slawkens/myaac/commit/3949d84e5d7631f332111b6d00278bddbd0ad10a)
### Fixed
* php 8.4 warnings
* Visitors counter not working properly on dev mode (https://github.com/slawkens/myaac/commit/da151051186c913dd0dd091aabe893649c2b9ee7)
* Fix login.php boosted creature & boss (not sure exact version, but should be 14.12 or around) (https://github.com/slawkens/myaac/commit/c48b8006319f6c3b5f082befd16785420bb98110)
* Fix installMenus when theme/template was removed from disc (https://github.com/slawkens/myaac/commit/c24c580796bccd54bf9e95b864763f4642684d55)
* Fix if user removes the menu category (https://github.com/slawkens/myaac/commit/dbea69f31478391dacfbbc02c8353c39b4245daf)
### Updated:
* Update cypress from version ^13.17.0 to ^14.3.3 (https://github.com/slawkens/myaac/commit/629fd18ea166860d5898a822f44f9277da6ce43d)
## [1.4 - 22.04.2025]
### Added
* feat: admin-pages (can add admin pages through plugins) (https://github.com/slawkens/myaac/commit/ceaa0639e66d31e8177ff90791463470367aa45d)
* just place the page in admin-pages folder in the plugin
* Also, possibility to overwrite default myaac admin pages
* Add db->hasTableAndColumns(table, columns), credits to @opentibiabr Team (https://github.com/slawkens/myaac/commit/82a533d88c8a342076891d132b4b409ed9a1fe72)
* Add noSubmit option to buttons.base (https://github.com/slawkens/myaac/commit/64f6d3abcada3bf9fd7599f50d2fac0a1367f383)
### Fixed
* Fix: display 404 error instead of 500 when page has been removed from filesystem (https://github.com/slawkens/myaac/commit/c2bf94fb2370d2009a2eb907f818955132cf8611)
* Fix headline.php: change image format to .png cause of black background (https://github.com/slawkens/myaac/commit/b618084d50918539d9a70abd97e764137b966067)
* Clear cache on plugin enable/disable, fixes some issues with plugin pages being cached (https://github.com/slawkens/myaac/commit/1d0c173e7d000aecbd432800941fc3e38a0e50f2)
* Do not autoload sub-folders if autoload pages is disabled (https://github.com/slawkens/myaac/commit/d47195a7878095336f9c9edc6f96244257f67eec)
### Changed
* SQL Syntax Standardization (by @JoaozinhoBrasil, #298)
* Pages in theme/template folder will now have precedence over normal pages (https://github.com/slawkens/myaac/commit/6d8f4718a1d349fba8f0ebc39cfd3a1a84d104b0)
* Small changes in account.login.html.twig (https://github.com/slawkens/myaac/commit/f40b986b59d4c8fa89ab4745731bf366f8619976)
* Plugin name is required, version is optional (https://github.com/slawkens/myaac/commit/e6f05a2731c61d931be49e121c068e49c0ad5e01)
## [1.3.3 - 04.04.2025]
### Fixed
* Fix uninstall plugin when plugin is disabled (https://github.com/slawkens/myaac/commit/6c568fd36a271270684fc412ccd556b230273a6d)
### Changed
* Display more useful info when error parsing config.lua (https://github.com/slawkens/myaac/commit/fa6b6aa153ffc131e0d1631a4dcd9012a5850c2e)
### Other
* Small adjustments (https://github.com/slawkens/myaac/commit/35e2483de86e295bdf089cceffa25842eeb2e34c, https://github.com/slawkens/myaac/commit/ae639d65b0bfa491e747e907e2ebc77f83f47981)
## [1.3.2 - 01.04.2025]
### Fixed
* Fix debugBar/admin panel menu when using custom base_dir (https://github.com/slawkens/myaac/commit/65696f63e3aac02ff952ea81279e7cb2fa7570fb)
### Changed
* Settings: Show/hide IP Ban Protection options depending on the value (enabled/disabled) (https://github.com/slawkens/myaac/commit/dbf73d0b61b45601ae95e51b23c051c2704169c5)
* Do not require init.php in cache:clear command (https://github.com/slawkens/myaac/commit/d25c71857f767834239bbffacd00fdc671adb157)
## [1.3.1 - 19.03.2025]
### Fixed
* Fixed migrate:run command (https://github.com/slawkens/myaac/commit/1a5771ad51e595fe13368a0721b059c4ecefb17d)
### Changed
* Small adjustments (https://github.com/slawkens/myaac/commit/6fac883659f581baac1361826d046410156f1e58, https://github.com/slawkens/myaac/commit/4a6896b4469968b9904292734cf6c14ba5eeef14)
## [1.3 - 10.03.2025]
### Changed
* Use latest outfit-images host from @gesior (https://github.com/slawkens/myaac/commit/529bdcf016dd0f9dffbc34d81f99a046a9ddb70d)
* Change monster link to $_GET ?name= (https://github.com/slawkens/myaac/commit/4c5cc8b573b2b3e7ec00a22b7ede30a68083a924)
### Fixed
* Fixed house links (https://github.com/slawkens/myaac/commit/887b5068ad11c4cdab614afd34525caba785ce13)
* Fixed long title on headline.php (https://github.com/slawkens/myaac/commit/3e3f4bb5a514158ec8777684ca6c7f1c2a37bed5)
* Fixed menu colors once again, plus add !important tag (https://github.com/slawkens/myaac/commit/aa52df6e2ec92cafc25b655ae907bf2e1746d9cc)
* Fix: add possibility to remove all menu items in admin panel (https://github.com/slawkens/myaac/commit/00fe1adc15ea7646596d755f6e6e1f7854ffc1d5, https://github.com/slawkens/myaac/commit/9239a4f4198c3ad260802ac3b47e9c41b80b754e)
## [1.2 - 09.02.2025]
### Added
* Twig session(key) function + reworked session functions to accept multi-array like in Laravel (https://github.com/slawkens/myaac/commit/b46ddb43d03ef7e5fc34e555e92e856bdc905691)
* add template_name to twig variables (https://github.com/slawkens/myaac/commit/ae1161d77050bda181802b4496c9de920a7bb1bc)
* add HOOK_INIT, executed just after $hooks are loaded (https://github.com/slawkens/myaac/commit/19686725dc810f63a07f049f82c66cf336d90ca6)
### Changed
* settings: password input hide/show, enable Save button only if changes has been made, save settings in transaction (https://github.com/slawkens/myaac/commit/4fda4f643b60a151179e5dd4f04912fb2618d98f, https://github.com/slawkens/myaac/commit/28fef952f857b79d64bc7495ffa5e1999e68e192, https://github.com/slawkens/myaac/commit/4b6024dc451accadb6c469fa282a9a764c1c0a81)
* rework menus: Different categories can have different colors + Option to reset menus (https://github.com/slawkens/myaac/commit/73de93a561f6b13111e019075724357d8a617249, https://github.com/slawkens/myaac/commit/3da3e62c5b12390d75de9b3320729bcca6e0b458)
### Fixed
* highscores: Fix online status + vocation for TFS 0.x (https://github.com/slawkens/myaac/commit/ea51ad27c38be88d86514cb979bb394fcfbef1f0)
* clear cache button in admin bar needed to be clicked twice until it worked (https://github.com/slawkens/myaac/commit/ea51ad27c38be88d86514cb979bb394fcfbef1f0)
* HOOK_STARTUP location (https://github.com/slawkens/myaac/commit/a73fb1003ee3f812cf182d1834d65f08e6f60d1f)
* if vocation name has more words (https://github.com/slawkens/myaac/commit/9d7fc98e1e0a96b59ecc1a7c39800a64445db364)
### Updated
* Bump twig/twig from 3.18.0 to 3.19.0 (#284)
## [1.1 - 27.01.2025]
### Changed
* adjust mailer settings descriptions to latest gmail (https://github.com/slawkens/myaac/commit/c5d5bb80671db135e6b503f53684771c7272e05d)
* optimize $player->isOnline() function, thanks @gesior (https://github.com/slawkens/myaac/commit/10dd818b139d5e1bb1ca9ec81edfb083ba9316b4)
* make players.comment and guilds.description VARCHAR (https://github.com/slawkens/myaac/commit/a45ceab83a74bee2b89cdb72baceda75e577e3cf)
* add lua/ folder to .gitignore (https://github.com/slawkens/myaac/commit/07012f786b1114cb6ab2f064f82c645b136a375a)
### Fixed
* general fixes in the tibiacom template menus, better support for custom menus
* make functions_custom.php optional (https://github.com/slawkens/myaac/commit/dc2b5afd9980984e2b259c9fc99f2ade46f70a5a)
* error in CLI, where BASE_URL is not defined (https://github.com/slawkens/myaac/commit/4d749b881582f64b5a46196dbbb5ee8097127f03)
* hook ACCOUNT_LOGIN_BEFORE_ACCOUNT location (https://github.com/slawkens/myaac/commit/669c447fca8643ce56d9ef8c1374ec647c780998)
## [1.0.1 - 14.01.2025]
### Fixed
* tibiacom account & news menu links not auto expanding
### Updated (Thanks dependabot)
* twig from ^2.0 to ^3.11
* tinymce from ^6.8.3 to ^7.2.0
* cypress from ^12.12.0 to ^13.17.0
* nesbot/carbon from 2.72.5 to 2.72.6
## [1.0 - 12.01.2025]
First stable release in the v1.0 series.
Minimum PHP 8.1 is required.
Changes since RC.2:
### Added
* feature: migrations up/down. Allows to downgrade/upgrade database to specified version (https://github.com/slawkens/myaac/commit/3f6ff3a3326b0475d28d11ffd7fff51f362d799f)
* new hooks for news management (https://github.com/slawkens/myaac/commit/011a85d8ae34283ded6999882833f9d4797028ec, https://github.com/slawkens/myaac/commit/36bd3eb846e829b45313e10f7568dc4e95841143)
* None Vocation to highscores (can be changed to RookStayer in Admin Panel) (https://github.com/slawkens/myaac/commit/a4a248099521bb5b8b2aa5bd592138debd2f19d5)
* support for button_color (green, red, blue) (https://github.com/slawkens/myaac/commit/d8b6b749ee62e88b6af4a05d3d7557f90b94d94e)
* add $whoopsHandler as variable, can be used by plugins (https://github.com/slawkens/myaac/commit/b0c8cf2ecda23045d725aaf43cfb3852ed766a4b)
* PlayerModel->outfit_url attribute (https://github.com/slawkens/myaac/commit/3b5be1a8db5dceecaa388e2925a5536d13b38881)
* support for selecting plugin themes in Admin menus.php (https://github.com/slawkens/myaac/commit/77a2c1cec343ffe4be5c2c2503ee81bc32a14ca1)
### Changed
* schema: Change character set to utf8mb4 (support for Emojis in Menus/Pages/News/Forum etc.) (https://github.com/slawkens/myaac/commit/27c44f1bdfb6234cf0c9d5b4b491123bb205b08f)
* prefer get_browser_real_ip() over REMOTE_ADDR (https://github.com/slawkens/myaac/commit/941846605c00cee83168d2f916410b8ba8d4b7b9)
* automatically set selected current one on highscores filters (https://github.com/slawkens/myaac/commit/e96227fbe41ae281783b2d49edb169a603601813)
* rewrite towns loading code, removed OTBM loader (was too slow) (https://github.com/slawkens/myaac/commit/c980a0914632e7b27f718464f669a200707d217e)
* allow OTS_Player to be passed as object to getPlayerLink (https://github.com/slawkens/myaac/commit/84d37c5a8f2c4535a41c8aa8264752969d3f3a3d)
* do not clear menus by default on install (https://github.com/slawkens/myaac/commit/12d8faa3eda5e798f97b71e941c035187daad96e)
* display warning in admin panel - plugins - if zip extension is not installed (https://github.com/slawkens/myaac/commit/e3ffe5d9e11d78ab064a370d8541bac351c9bcd9)
* set default_socket_timeout for ipinfo.io checkup to 5 seconds (https://github.com/slawkens/myaac/commit/783d96fc6568a607d3198b832fed3a0dd06c4ebb)
* refactor getTopPlayers function (support for balance) (https://github.com/slawkens/myaac/commit/c769962e39fe8dfb72ecd5be1864e145696be794)
### Fixed
* XSS in forum (https://github.com/slawkens/myaac/commit/c2b7286d20d4b579171540f7a774e8a0995d5e8f, https://github.com/slawkens/myaac/commit/8fb643596f9586005976e7bdb484a541a9d8715e)
* price deducted when changing sex (https://github.com/slawkens/myaac/commit/16671ea40b72dcf74037c359ad572f9eb825edf9)
* move_thread by unauthorized user (https://github.com/slawkens/myaac/commit/d6c40c836a53cb1710f911f77f45f28b54ea1b54, thanks @anyeor)
* TFS 1.4.2 where conditions is NULL (https://github.com/slawkens/myaac/commit/b8396d4c8482e951da538b13f2296123732c4545)
* do not show forum new thread show button if not logged in (https://github.com/slawkens/myaac/commit/507402171ba3b6e7ee184bd7fa73e0d55e0cad7a, @anyeor)
* login if limiter is disabled (https://github.com/slawkens/myaac/commit/a0f1971583f0f790013e2145fb5ac573c59fbdef)
* fixes to installMenus function (https://github.com/slawkens/myaac/commit/a2fadc5945fe0a5e39f740827f6ffbda1bb501e2)
* many PHP exceptions in different places
* fixes to tibiacom menus ActiveSubmenuItem
### Removed
* bugtracker SQL table code as the page has been removed/moved to plugins (https://github.com/slawkens/myaac/commit/5782772b901b05fb814bc718d062f6e2cd71df8c)
## [1.0-RC.2 - 25.10.2024]
Still waiting for your reports about bugs found in this release. We are very close to stable release.
### Added
* feat: rate limit settings for blocking accounts login attempts (@gpedro, #266)
* search by email in accounts editor (https://github.com/slawkens/myaac/commit/c2ec46824621468f2a1cb4046805c485ed13fea5)
* New hooks in account manage + create (https://github.com/slawkens/myaac/commit/93641fc68ac9a5f1479329e2bd41380c19534d5d)
### Changed
* chore: drop raw queries + accounts - search by email + accounts - required min size for search by account number (@gpedro, #266)
* Use https for outfit & item images (https://github.com/slawkens/myaac/commit/71c00aa5e01fbdfd88802912e200dd1025976231)
* Do not require players & guilds tables on install (https://github.com/slawkens/myaac/commit/779aa152fa940261c9b161533946f44e288597a2)
* Do not create player if there is no players table in db (https://github.com/slawkens/myaac/commit/201f95caa8b70e88fa651eac8c3c3aa7cd765bd0)
### Fixed
* Highscore frags fixed for TFS 0.3 (@Scrollog, #263)
* Missing groups variable #262. thanks, @Scrollog for reporting (https://github.com/slawkens/myaac/commit/8d8bdb6dac6df21672ac77288fff2f2f8d6eb665)
* Verified email for login.php (@gpedro, #265)
* Warning if core.account_country is disabled (https://github.com/slawkens/myaac/commit/ab73d60c61e14a1cacdb6cfbf7f89f4bf3be0833)
## [1.0-RC.1 - 23.07.2024]
Changes since 1.0-beta:
### Added
* Feat: Hooks priority (https://github.com/slawkens/myaac/commit/dc17b701da053e04bfa64e21be9247a4f07505e1)
* Make autoload of pages, commands and themes configurable (https://github.com/slawkens/myaac/commit/c1d4b4f80cd6bb85507ee9471e47013955a26a91)
* Fraggers in characters page for TFS 1.x and canary (https://github.com/slawkens/myaac/commit/42f99c3edc8de39cccc5632cb42e88b24579c5a6)
* New hooks: HOOK_INSTALL_FINISH, HOOK_ACCOUNT_CREATE_CHARACTER_* (https://github.com/slawkens/myaac/commit/08ac8ebade106521a5c7396faa5ce7006e629f7c, https://github.com/slawkens/myaac/commit/45dda5e834ff2059faea6ef9be2efa76f1723cbd)
### Changed
* Allow account_create_character_create even if account_mail_verify is activated (https://github.com/slawkens/myaac/commit/203e411b626fe62401a4b74a48420769e512aa39)
* Create guild_rank entries, in case MySQL trigger not loaded (https://github.com/slawkens/myaac/commit/d9c1b2507c81f306970642b35e4bf5f7cc04a6f2, https://github.com/slawkens/myaac/commit/47a19e85dd84e9f3b39a1b29cfc2c04b004832b9)
* Set Admin Account verified by default (https://github.com/slawkens/myaac/commit/cd49dfc79942f3301ce9c0b8d899b9f39bda9a41)
* Refactor account routes into sub folders (https://github.com/slawkens/myaac/commit/bdc0c43d3fd3a51030c3e916bdb9f008468f5ecd)
* Order towns by id (https://github.com/slawkens/myaac/commit/9ea2a5067fc4b75de395f381577b18914132ad84)
* Do not create news about myaac, if any news already exist (on installation (https://github.com/slawkens/myaac/commit/504242fb846b73b56b87bc1e39d070687ad7f5b4)
### Fixed
* Not working google recaptcha plugin (https://github.com/slawkens/myaac/commit/a1bcb217ecf4e21fd58da4ba491da1852029898a)
* Not working account create if account_country is disabled (https://github.com/slawkens/myaac/commit/933b681a9fcdbb6283e0469b3806d2ded492d232)
* Account verify - do not allow login without verified email (Thanks @anyeor, https://github.com/slawkens/myaac/commit/fcb13f3c0fb8ceafda0bd614a229a26a269432bd)
* Detect tools/ext exists on install to prevent broken installs (https://github.com/slawkens/myaac/commit/10a739773c4f2911876bc802a0ee0537c3e00a92)
* Cache reloading each time page refreshes (https://github.com/slawkens/myaac/commit/ec96985872057340112f65073efc0c4bf86dddb0)
* Highscores frags for TFS 1.x and canary (https://github.com/slawkens/myaac/commit/a04d186c22912915f0a7873dfe677ef3b5a23c79)
* Monsters page: monster not found exception (https://github.com/slawkens/myaac/commit/ef79b99b8acc179f14b8475547347d9daca27512)
* Fixed bug if \<flags\> are not present in monster.xml (https://github.com/slawkens/myaac/commit/57b47ab7983f625c7c0ef4f5303a4d07ef172786)
* fastRoute duplicate errors (https://github.com/slawkens/myaac/commit/4c0739d3e93812dff0c33849ea3f38e4e49113ac)
* useGuildNick displaying (https://github.com/slawkens/myaac/commit/0db0ec1aa47e044c26bc403ff5078a2115d086f8)
## [1.0-beta - 18.05.2024]
Minimum PHP version for this release is 8.1.
### Added
* reworked Admin Panel (@Leesneaks, @gpedro, @slawkens)
* updated to Bootstrap v4
* new Menu
* new Dashboard: statistics, server status
* new Admin Bar showed on top when admin logged in
* new page: Server Data, to reload server data
* Towns, NPCs & Items are stored in permanent cache
* new pages: mass account & teleport tools
* changelogs editor
* revised Accounts & Players editors
* option to add/modify admin menus with plugins
* option to enable/disable plugins
* better, updated TinyMCE editor (v6.x)
* with option to upload images
* list of open source libraries used in project page
* auto-loading of themes, commands & pages from plugins/ folder. You need just to place them in correct folder and they will be loaded automatically - this allows better customization, without interfering with core AAC folders. This will allow in the future automatic updates for plugins as well the AAC as whole.
* config.php moved to Admin Panel -> Settings page
* new console script: aac - using symfony/console
* usage: `php aac` (will list all commands by default)
* example: `php aac cache:clear`
* example: `php aac plugin:install theme-example.zip`
* replace POT Query Builder to Eloquent ORM. Not 100% yet - in some places there is still old $db approach used (@gpedro) (https://github.com/slawkens/myaac/pull/230)
* brand new charming installation page (by @fernandomatos)
* using Bootstrap
* new pages router: nikic/fast-route, allowing for better customisation
* Plugin cronjobs: central control of the cronjobs
* Guild Wars support (available as plugin)
* support for login and create account only by email (configurable)
* with no need for account name
* Google ReCAPTCHA v3 support (available as plugin)
* support for Account Number
* suggest account number option
* many new functions, hooks and configurables
* better Exception Handler (Whoops - https://github.com/filp/whoops)
* automated website tests (using Cypress)
* csrf protection (https://github.com/slawkens/myaac/pull/235)
* option to restrict Page view to specified group of users (Not-Logged in, logged-in players, tutors, gamemasters etc.)
* phpdebug bar (http://phpdebugbar.com/). Activated if env == 'dev', can be also activated in production by enabling "enable_debugbar" in local config
### Changed
* Composer and NPM is now used for external libraries like: Twig, PHPMailer, fast-route, jQuery, Bootstrap etc.
* mail support is disabled on fresh install, can be manually enabled by user
* disable add php pages in admin panel for security. Option to disable plugins upload
* visitors counter shows now user browser, and also if its bot
* changes in required and optional PHP extensions
* reworked Pages:
* Bans
* works now for TFS 1.x
* Highscores
* frags works for TFS 1.x
* cached
* Monsters
* moved pages to Twig:
* experience stages
* update player_deaths entries on name change
* change_password email to be more informal
### Fixed
* hundreds of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here

View File

@@ -1,55 +0,0 @@
# Changelog
## [0.9.0-alpha - 02.06.2023]
Minimum PHP version for this release is 7.2.5.
### Added
* reworked Admin Panel (@Leesneaks, @gpedro, @slawkens)
* updated to Bootstrap v4
* new Menu
* new Dashboard: statistics, server status
* new Admin Bar showed on top when admin logged in
* new page: Server Data, to reload server data
* new pages: mass account & teleport tools
* changelogs editor
* revised Accounts & Players editors
* option to add/modify menus with plugins
* option to enable/disable plugins
* better, updated TinyMCE editor (v6.x)
* with option to upload images
* list of open source libraries used in project
* brand new charming installation page (by @fernandomatos)
* using Bootstrap
* new pages router: nikic/fast-route, allowing for better customisation
* Guild Wars support (available as plugin)
* support for login and create account only by email (configurable)
* with no need for account name
* Google ReCAPTCHA v3 support (available as plugin)
* automatically load towns names from .OTBM file
* support for Account Number
* suggest account number option
* many new functions, hooks and configurables
* better Exception Handler (Whoops - https://github.com/filp/whoops)
* add Cypress testing
### Changed
* Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc.
* mail support is disabled on fresh install, can be manually enabled by user
* disable add php pages in admin panel for security. Option to disable plugins upload
* visitors counter shows now user browser, and also if its bot
* changes in required and optional PHP extensions
* reworked Pages:
* Bans
* works now for TFS 1.x
* Highscores
* frags works for TFS 1.x
* cached
* creatures
* moved pages to Twig:
* experience stages
* update player_deaths entries on name change
* change_password email to be more informal
### Fixed
* hundrets of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
# [MyAAC](https://my-aac.org) # [MyAAC](https://my-aac.org)
MyAAC is a free and open-source Automatic Account Creator (AAC) written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases. MyAAC is a free and open-source Automatic Account Creator (AAC) for Open Tibia Servers written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases.
Official website: https://my-aac.org Official website: https://my-aac.org
@@ -11,20 +11,26 @@ Official website: https://my-aac.org
[![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** | | 2.x | Experimental features | develop | PHP >= 8.1 |
| 0.9.x | Active support | 0.9 | PHP >= 7.2.5 | | **1.x** | **Active development** | main | **PHP >= 8.1** |
| 0.8.x | Active support | master | PHP >= 7.2.5 | | 0.9.x | Not developed anymore | 0.9 | PHP >= 7.2.5 |
| 0.8.x | Active support | 0.8 | 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 |
The recommended version to install is 1.x, which can be found at releases page - [https://github.com/slawkens/myaac/releases](https://github.com/slawkens/myaac/releases).
### Documentation
* [docs.my-aac.org](https://docs.my-aac.org)
* [my-aac.org - FAQ](https://my-aac.org/faqs/)
### 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,22 +54,23 @@ Official website: https://my-aac.org
### Configuration ### Configuration
Check *config.php* to get more informations. Check *config.php* to get more information. (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
This repository follows the Git Flow Workflow. This repository follows the Git Flow Workflow.
Cheatsheet: [Git-Flow-Cheetsheet](https://danielkummer.github.io/git-flow-cheatsheet) Cheatsheet: [Git-Flow-Cheatsheet](https://danielkummer.github.io/git-flow-cheatsheet)
That means, we use: That means, we use:
* master branch, for current stable release * main branch, for current stable release
* develop branch, for development version (next release) * develop branch, for development version (next release)
* feature branches, for features etc. * feature branches, for features etc.
### Known Problems ### Known Problems
- Some compatibility issues with some exotical distibutions. - Some compatibility issues with some exotic distributions.
### Contributing ### Contributing
@@ -73,11 +80,11 @@ Pull requests should be made to the *develop* branch as that is the working bran
Bug fixes to current release should be done to master branch. Bug fixes to current release should be done to master branch.
Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our wiki. Look: [Contributing](https://docs.my-aac.org/misc/contributing) in our wiki.
### Other Notes ### Other Notes
If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org If you have a great idea or want to contribute to the project - visit our website at https://www.my-aac.org
## Project supported by JetBrains ## Project supported by JetBrains
@@ -88,4 +95,4 @@ Many thanks to Jetbrains for kindly providing a license for me to work on this a
### License ### License
This program and all associated files are released under the GNU Public License. This program and all associated files are released under the GNU Public License.
See [LICENSE](https://github.com/slawkens/myaac/blob/master/LICENSE) for details. See [LICENSE](https://github.com/slawkens/myaac/blob/main/LICENSE) for details.

36
aac Normal file
View File

@@ -0,0 +1,36 @@
#!/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';
define('SELF_NAME', basename(__FILE__));
use MyAAC\Plugins;
use Symfony\Component\Console\Application;
$application = new Application('MyAAC', MYAAC_VERSION);
$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->run();

View File

@@ -7,7 +7,7 @@ $hooks->register('debugbar_admin_head_end', HOOK_ADMIN_HEAD_END, function ($para
return; return;
} }
$debugBarRenderer = $debugBar->getJavascriptRenderer(); $debugBarRenderer = $debugBar->getJavascriptRenderer(BASE_URL . 'vendor/maximebf/debugbar/src/DebugBar/Resources/');
echo $debugBarRenderer->renderHead(); echo $debugBarRenderer->renderHead();
}); });
$hooks->register('debugbar_admin_body_end', HOOK_ADMIN_BODY_END, function ($params) { $hooks->register('debugbar_admin_body_end', HOOK_ADMIN_BODY_END, function ($params) {
@@ -17,6 +17,6 @@ $hooks->register('debugbar_admin_body_end', HOOK_ADMIN_BODY_END, function ($para
return; return;
} }
$debugBarRenderer = $debugBar->getJavascriptRenderer(); $debugBarRenderer = $debugBar->getJavascriptRenderer(BASE_URL . 'vendor/maximebf/debugbar/src/DebugBar/Resources/');
echo $debugBarRenderer->render(); echo $debugBarRenderer->render();
}); });

View File

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

View File

@@ -1,6 +1,8 @@
<?php <?php
// few things we'll need // few things we'll need
use MyAAC\Plugins;
require '../common.php'; require '../common.php';
const ADMIN_PANEL = true; const ADMIN_PANEL = true;
@@ -25,11 +27,6 @@ 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
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.');
}
require __DIR__ . '/includes/debugbar.php'; require __DIR__ . '/includes/debugbar.php';
require SYSTEM . 'status.php'; require SYSTEM . 'status.php';
require SYSTEM . 'login.php'; require SYSTEM . 'login.php';
@@ -47,16 +44,22 @@ if(!$logged || !admin()) {
$page = 'login'; $page = 'login';
} }
// include our page $pluginsAdminPages = Plugins::getAdminPages();
$file = __DIR__ . '/pages/' . $page . '.php'; if(isset($pluginsAdminPages[$page]) && file_exists(BASE . $pluginsAdminPages[$page])) {
if(!@file_exists($file)) { $file = BASE . $pluginsAdminPages[$page];
if (strpos($page, 'plugins/') !== false) { }
else {
// include our page
$file = __DIR__ . '/pages/' . $page . '.php';
if(!@file_exists($file)) {
if (str_contains($page, 'plugins/')) {
$file = BASE . $page; $file = BASE . $page;
} }
else { else {
$page = '404'; $page = '404';
$file = SYSTEM . 'pages/404.php'; $file = SYSTEM . 'pages/404.php';
} }
}
} }
ob_start(); ob_start();

View File

@@ -8,6 +8,7 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Models\Account as AccountModel;
use MyAAC\Models\Player; use MyAAC\Models\Player;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
@@ -22,10 +23,7 @@ $use_datatable = true;
if (setting('core.account_country')) if (setting('core.account_country'))
require SYSTEM . 'countries.conf.php'; require SYSTEM . 'countries.conf.php';
$nameOrNumberColumn = 'name'; $nameOrNumberColumn = getAccountIdentityColumn();
if (USE_ACCOUNT_NUMBER) {
$nameOrNumberColumn = 'number';
}
$hasSecretColumn = $db->hasColumn('accounts', 'secret'); $hasSecretColumn = $db->hasColumn('accounts', 'secret');
$hasCoinsColumn = $db->hasColumn('accounts', 'coins'); $hasCoinsColumn = $db->hasColumn('accounts', 'coins');
@@ -51,36 +49,51 @@ $acc_type = setting('core.account_types');
<?php <?php
$id = 0; $id = 0;
$search_account = ''; $search_account = $search_account_email = '';
if (isset($_REQUEST['id'])) if (isset($_REQUEST['id']))
$id = (int)$_REQUEST['id']; $id = (int)$_REQUEST['id'];
else if (isset($_REQUEST['search_email'])) {
$search_account_email = $_REQUEST['search_email'];
$accountModel = AccountModel::where('email', $search_account_email)->limit(11)->get(['email', 'id']);
if (count($accountModel) == 0) {
echo_error('No entries found.');
} else if (count($accountModel) == 1) {
$id = $accountModel->first()->getKey();
} else if (count($accountModel) > 10) {
echo_error('Specified e-mail resulted with too many accounts.');
}
}
else if (isset($_REQUEST['search'])) { else if (isset($_REQUEST['search'])) {
$search_account = $_REQUEST['search']; $search_account = $_REQUEST['search'];
if (strlen($search_account) < 3 && !Validator::number($search_account)) { $min_size = 3;
echo_error('Player name is too short.'); if (in_array($nameOrNumberColumn, ['id', 'number'])) {
$min_size = 1;
}
if (strlen($search_account) < $min_size && !Validator::number($search_account)) {
echo_error('Account ' . $nameOrNumberColumn . ' is too short.');
} else { } else {
$query = $db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $db->quote($search_account)); $query = AccountModel::where($nameOrNumberColumn, '=', $search_account)->limit(11)->get(['id', $nameOrNumberColumn]);
if ($query->rowCount() == 1) { if (count($query) == 0) {
$query = $query->fetch(); echo_error('No entries found.');
$id = (int)$query['id']; } else if (count($query) == 1) {
$id = $query->first()->getKey();
} else if (count($query) > 10) {
echo_error('Specified name resulted with too many accounts.');
} else { } else {
$query = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` LIKE ' . $db->quote('%' . $search_account . '%'));
if ($query->rowCount() > 0 && $query->rowCount() <= 10) {
$str_construct = 'Do you mean?<ul class="mb-0">'; $str_construct = 'Do you mean?<ul class="mb-0">';
foreach ($query as $row) foreach ($query as $row) {
$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row[$nameOrNumberColumn] . '</a></li>'; $str_construct .= '<li><a href="' . $admin_base . '&id=' . $row->getKey() . '">' . $row->attributes[$nameOrNumberColumn] . '</a></li>';
}
$str_construct .= '</ul>'; $str_construct .= '</ul>';
echo_error($str_construct); echo_error($str_construct);
} else if ($query->rowCount() > 10)
echo_error('Specified name resulted with too many accounts.');
else
echo_error('No entries found.');
} }
} }
} }
?> ?>
<div class="row"> <div class="row">
<?php <?php
$groups = new OTS_Groups_List();
if ($id > 0) { if ($id > 0) {
$account = new OTS_Account(); $account = new OTS_Account();
$account->load($id); $account->load($id);
@@ -143,7 +156,9 @@ else if (isset($_REQUEST['search'])) {
$rl_loca = $_POST['rl_loca']; $rl_loca = $_POST['rl_loca'];
//country //country
if(setting('core.account_country')) {
$rl_country = $_POST['rl_country']; $rl_country = $_POST['rl_country'];
}
$web_flags = $_POST['web_flags']; $web_flags = $_POST['web_flags'];
verify_number($web_flags, 'Web Flags', 1); verify_number($web_flags, 'Web Flags', 1);
@@ -190,7 +205,11 @@ else if (isset($_REQUEST['search'])) {
} }
$account->setRLName($rl_name); $account->setRLName($rl_name);
$account->setLocation($rl_loca); $account->setLocation($rl_loca);
if(setting('core.account_country')) {
$account->setCountry($rl_country); $account->setCountry($rl_country);
}
$account->setCustomField('created', $created); $account->setCustomField('created', $created);
$account->setWebFlags($web_flags); $account->setWebFlags($web_flags);
$account->setCustomField('web_lastlogin', $web_lastlogin); $account->setCustomField('web_lastlogin', $web_lastlogin);
@@ -214,7 +233,7 @@ else if (isset($_REQUEST['search'])) {
} }
} }
} else if ($id == 0) { } else if ($id == 0) {
$accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC'); $accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ', email FROM `accounts` ORDER BY `id` ASC');
?> ?>
<div class="col-12 col-sm-12 col-lg-10"> <div class="col-12 col-sm-12 col-lg-10">
<div class="card card-info card-outline"> <div class="card card-info card-outline">
@@ -226,8 +245,9 @@ else if (isset($_REQUEST['search'])) {
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th><?= ($nameOrNumberColumn == 'number' ? 'Number' : 'Name'); ?></th> <th><?= ($nameOrNumberColumn == 'name' ? 'Name' : 'Number'); ?></th>
<?php if($hasTypeColumn || $hasGroupColumn): ?> <?php if($hasTypeColumn || $hasGroupColumn): ?>
<th>E-Mail</th>
<th>Position</th> <th>Position</th>
<?php endif; ?> <?php endif; ?>
<th style="width: 40px">Edit</th> <th style="width: 40px">Edit</th>
@@ -238,6 +258,7 @@ else if (isset($_REQUEST['search'])) {
<tr> <tr>
<th><?php echo $account_lst['id']; ?></th> <th><?php echo $account_lst['id']; ?></th>
<td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td> <td><?php echo $account_lst[$nameOrNumberColumn]; ?></a></td>
<td><?php echo $account_lst['email']; ?></td>
<?php if($hasTypeColumn || $hasGroupColumn): ?> <?php if($hasTypeColumn || $hasGroupColumn): ?>
<td> <td>
<?php if ($hasTypeColumn) { <?php if ($hasTypeColumn) {
@@ -291,7 +312,7 @@ else if (isset($_REQUEST['search'])) {
<div class="card-body"> <div class="card-body">
<div class="tab-content" id="accounts-tabContent"> <div class="tab-content" id="accounts-tabContent">
<div class="tab-pane fade active show" id="accounts-acc"> <div class="tab-pane fade active show" id="accounts-acc">
<form action="<?php echo $admin_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post"> <form action="<?php echo $admin_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post">
<?php csrf(); ?> <?php csrf(); ?>
<div class="form-group row"> <div class="form-group row">
<?php if (USE_ACCOUNT_NAME): ?> <?php if (USE_ACCOUNT_NAME): ?>
@@ -404,6 +425,7 @@ else if (isset($_REQUEST['search'])) {
autocomplete="off" maxlength="20" autocomplete="off" maxlength="20"
value="<?php echo $account->getLocation(); ?>"/> value="<?php echo $account->getLocation(); ?>"/>
</div> </div>
<?php if(setting('core.account_country')): ?>
<div class="col-12 col-sm-12 col-lg-4"> <div class="col-12 col-sm-12 col-lg-4">
<label for="rl_country">Country:</label> <label for="rl_country">Country:</label>
<select name="rl_country" id="rl_country" class="form-control"> <select name="rl_country" id="rl_country" class="form-control">
@@ -412,6 +434,7 @@ else if (isset($_REQUEST['search'])) {
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
<?php endif; ?>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6"> <div class="col-12 col-sm-12 col-lg-6">
@@ -583,6 +606,16 @@ else if (isset($_REQUEST['search'])) {
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post">
<?php csrf(); ?>
<label for="search">Account E-Mail:</label>
<div class="input-group input-group-sm">
<input type="email" class="form-control" id="search_email" name="search_email" value="<?= escapeHtml($search_account_email); ?>" maxlength="255" size="255">
<span class="input-group-append"><button type="submit" class="btn btn-info btn-flat">Search</button></span>
</div>
</form>
</div>
<div class="col-6 col-lg-12"> <div class="col-6 col-lg-12">
<form action="<?php echo $admin_base; ?>" method="post"> <form action="<?php echo $admin_base; ?>" method="post">
<?php csrf(); ?> <?php csrf(); ?>

View File

@@ -9,6 +9,7 @@
* @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!');
@@ -26,9 +27,8 @@ $use_datatable = true;
const CL_LIMIT = 600; // maximum changelog body length const CL_LIMIT = 600; // maximum changelog body length
$id = $_GET['id'] ?? 0; $id = $_GET['id'] ?? 0;
require_once LIBS . 'changelog.php';
if(!empty($action)) if(!empty($action) && isRequestMethod('post'))
{ {
$id = $_POST['id'] ?? null; $id = $_POST['id'] ?? null;
$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null; $body = isset($_POST['body']) ? stripslashes($_POST['body']) : null;
@@ -73,7 +73,7 @@ if(!empty($action))
} }
} }
else if($action == 'hide') { else if($action == 'hide') {
if (Changelog::toggleHidden($id, $errors, $status)) { if (Changelog::toggleHide($id, $errors, $status)) {
success(($status == 1 ? 'Hide' : 'Show') . ' successful.'); success(($status == 1 ? 'Hide' : 'Show') . ' successful.');
} }
} }

View File

@@ -11,12 +11,12 @@
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'MyAAC Changelog'; $title = 'MyAAC Changelog';
if (!file_exists(BASE . 'CHANGELOG.md')) { if (!file_exists(BASE . 'CHANGELOG-1.x.md')) {
echo 'File CHANGELOG.md doesn\'t exist.'; echo 'File CHANGELOG.md doesn\'t exist.';
return; return;
} }
$changelog = file_get_contents(BASE . 'CHANGELOG.md'); $changelog = file_get_contents(BASE . 'CHANGELOG-1.x.md');
$Parsedown = new Parsedown(); $Parsedown = new Parsedown();

View File

@@ -7,6 +7,9 @@
* @copyright 2019 MyAAC * @copyright 2019 MyAAC
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Models\Account;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Mailer'; $title = 'Mailer';
@@ -61,15 +64,15 @@ if (!empty($mail_content) && !empty($mail_subject) && empty($mail_to)) {
$add = ' AND `email_verified` = 1'; $add = ' AND `email_verified` = 1';
} }
$query = $db->query('SELECT `email` FROM `accounts` WHERE `email` != ""' . $add); $query = Account::where('email', '!=', '')->get(['email']);
foreach ($query as $email) { foreach ($query as $email) {
if (_mail($email['email'], $mail_subject, $mail_content)) { if (_mail($email->email, $mail_subject, $mail_content)) {
$success++; $success++;
} }
else { else {
$failed++; $failed++;
echo '<br />'; echo '<br />';
error('An error occorred while sending email to <b>' . $email['email'] . '</b>. For Admin: More info can be found in system/logs/mailer-error.log'); error('An error occorred while sending email to <b>' . $email->email . '</b>. For Admin: More info can be found in system/logs/mailer-error.log');
} }
} }

View File

@@ -24,20 +24,13 @@ $freePremium = $config['lua']['freePremium'];
function admin_give_points($points) function admin_give_points($points)
{ {
global $db, $hasPointsColumn; global $hasPointsColumn;
if (!$hasPointsColumn) { if (!$hasPointsColumn) {
displayMessage('Points not supported.'); displayMessage('Points not supported.');
return; return;
} }
$statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points');
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return;
}
if (!Account::query()->increment('premium_points', $points)) { if (!Account::query()->increment('premium_points', $points)) {
displayMessage('Failed to add points.'); displayMessage('Failed to add points.');
return; return;
@@ -47,7 +40,7 @@ function admin_give_points($points)
function admin_give_coins($coins) function admin_give_coins($coins)
{ {
global $db, $hasCoinsColumn; global $hasCoinsColumn;
if (!$hasCoinsColumn) { if (!$hasCoinsColumn) {
displayMessage('Coins not supported.'); displayMessage('Coins not supported.');
@@ -62,24 +55,6 @@ function admin_give_coins($coins)
displayMessage($coins . ' coins added to all accounts.', true); displayMessage($coins . ' coins added to all accounts.', true);
} }
function query_add_premium($column, $value_query, $condition_query = '1=1', $params = [])
{
global $db;
$statement = $db->prepare("UPDATE `accounts` SET `{$column}` = $value_query WHERE $condition_query");
if (!$statement) {
displayMessage('Failed to prepare query statement.');
return false;
}
if (!$statement->execute($params)) {
displayMessage('Failed to add premium days.');
return false;
}
return true;
}
function admin_give_premdays($days) function admin_give_premdays($days)
{ {
global $db, $freePremium; global $db, $freePremium;
@@ -94,9 +69,9 @@ function admin_give_premdays($days)
// othire // othire
if ($db->hasColumn('accounts', 'premend')) { if ($db->hasColumn('accounts', 'premend')) {
// append premend // append premend
if (query_add_premium('premend', '`premend` + :value', '`premend` > :now', ['value' => $value, 'now' => $now])) { if (Account::where('premend', '>', $now)->increment('premend', $value)) {
// set premend // set premend
if (query_add_premium('premend', ':value', '`premend` <= :now', ['value' => $now + $value, 'now' => $now])) { if (Account::where('premend', '<=', $now)->update(['premend' => $now + $value])) {
displayMessage($days . ' premium days added to all accounts.', true); displayMessage($days . ' premium days added to all accounts.', true);
return; return;
} else { } else {
@@ -114,11 +89,11 @@ function admin_give_premdays($days)
// tfs 0.x // tfs 0.x
if ($db->hasColumn('accounts', 'premdays')) { if ($db->hasColumn('accounts', 'premdays')) {
// append premdays // append premdays
if (query_add_premium('premdays', '`premdays` + :value', '1=1', ['value' => $days])) { if (Account::query()->update(['premdays' => $days])) {
// append lastday // append lastday
if (query_add_premium('lastday', '`lastday` + :value', '`lastday` > :now', ['value' => $value, 'now' => $now])) { if (Account::where('lastday', '>', $now)->increment('lastday', $value)) {
// set lastday // set lastday
if (query_add_premium('lastday', ':value', '`lastday` <= :now', ['value' => $now + $value, 'now' => $now])) { if (Account::where('lastday', '<=', $now)->update(['lastday' => $now + $value])) {
displayMessage($days . ' premium days added to all accounts.', true); displayMessage($days . ' premium days added to all accounts.', true);
return; return;
} else { } else {
@@ -142,9 +117,9 @@ function admin_give_premdays($days)
// tfs 1.x // tfs 1.x
if ($db->hasColumn('accounts', 'premium_ends_at')) { if ($db->hasColumn('accounts', 'premium_ends_at')) {
// append premium_ends_at // append premium_ends_at
if (query_add_premium('premium_ends_at', '`premium_ends_at` + :value', '`premium_ends_at` > :now', ['value' => $value, 'now' => $now])) { if (Account::where('premium_ends_at', '>', $now)->increment('premium_ends_at', $value)) {
// set premium_ends_at // set premium_ends_at
if (query_add_premium('premium_ends_at', ':value', '`premium_ends_at` <= :now', ['value' => $now + $value, 'now' => $now])) { if (Account::where('premium_ends_at', '<=', $now)->update(['premium_ends_at' => $now + $value])) {
displayMessage($days . ' premium days added to all accounts.', true); displayMessage($days . ' premium days added to all accounts.', true);
return; return;
} else { } else {
@@ -162,9 +137,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

@@ -40,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,7 +8,9 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\Cache\Cache;
use MyAAC\Models\Menu; use MyAAC\Models\Menu;
use MyAAC\Plugins;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$title = 'Menus'; $title = 'Menus';
@@ -20,14 +22,16 @@ if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) {
return; return;
} }
$pluginThemes = Plugins::getThemes();
if (isset($_POST['template'])) { if (isset($_POST['template'])) {
$template = $_POST['template']; $template = $_POST['template'];
if (isset($_POST['menu'])) { if (isset($_POST['save'])) {
$post_menu = $_POST['menu']; $post_menu = $_POST['menu'] ?? [];
$post_menu_link = $_POST['menu_link']; $post_menu_link = $_POST['menu_link'] ?? [];
$post_menu_blank = $_POST['menu_blank']; $post_menu_blank = $_POST['menu_blank'] ?? [];
$post_menu_color = $_POST['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;
@@ -55,54 +59,67 @@ if (isset($_POST['template'])) {
} }
} }
$cache = Cache::getInstance(); onTemplateMenusChange();
if ($cache->enabled()) {
$cache->delete('template_menus');
}
success('Saved at ' . date('H:i')); success('Saved at ' . date('H:i'));
} }
$file = TEMPLATES . $template . '/config.php'; $path = TEMPLATES . $template;
if (file_exists($file)) {
require_once $file; if (isset($pluginThemes[$template])) {
$path = BASE . $pluginThemes[$template];
}
$path .= '/config.php';
if (file_exists($path)) {
require_once $path;
} else { } else {
echo 'Cannot find template config.php file.'; echo 'Cannot find template config.php file.';
return; return;
} }
if (isset($_GET['reset_colors'])) {
if (isset($config['menu_default_color'])) {
Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]);
success('Colors has been reset.');
}
else {
warning('There is no default color defined, cannot reset colors.');
}
}
if (!isset($config['menu_categories'])) { if (!isset($config['menu_categories'])) {
echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus."; echo "No menu categories set in template config.php.<br/>This template doesn't support dynamic menus.";
return; return;
} }
if (isset($_GET['reset_colors'])) {
foreach ($config['menu_categories'] as $id => $options) {
$color = $options['default_links_color'] ?? ($config['menu_default_links_color'] ?? ($config['menu_default_color'] ?? '#ffffff'));
Menu::where('template', $template)->where('category', $id)->update(['color' => str_replace('#', '', $color)]);
}
onTemplateMenusChange();
success('Colors has been reset at ' . date('H:i'));
}
if (isset($_GET['reset_menus'])) {
$configMenus = config('menus');
if (isset($configMenus)) {
Plugins::installMenus($template, config('menus'), true);
onTemplateMenusChange();
success('Menus has been reset at ' . date('H:i'));
}
else {
error("This template don't support reinstalling menus.");
}
}
$title = 'Menus - ' . $template; $title = 'Menus - ' . $template;
$canResetColors = isset($config['menu_default_color']) || isset($config['menu_default_links_color']);
foreach ($config['menu_categories'] as $id => $options) {
if (isset($options['default_links_color'])) {
$canResetColors = true;
}
}
$twig->display('admin.menus.header.html.twig', [
'template' => $template,
'canResetColors' => $canResetColors
]);
?> ?>
<div align="center" class="text-center">
<p class="note">You are editing: <?= $template ?><br/><br/>
Hint: You can drag menu items.<br/>
Hint: Add links to external sites using: <b>http://</b> or <b>https://</b> prefix.<br/>
Not all templates support blank and colorful links.
</p>
<?php if (isset($config['menu_default_color'])) {?>
<form method="post" action="?p=menus&reset_colors" onsubmit="return confirm('Do you really want to reset colors?');">
<?php csrf(); ?>
<input type="hidden" name="template" value="<?php echo $template ?>"/>
<button type="submit" class="btn btn-danger">Reset Colors to default</button>
</form>
<br/>
<?php } ?>
</div>
<?php <?php
$menus = Menu::query() $menus = Menu::query()
->select('name', 'link', 'blank', 'color', 'category', 'ordering') ->select('name', 'link', 'blank', 'color', 'category', 'ordering')
@@ -118,7 +135,7 @@ if (isset($_POST['template'])) {
<form method="post" id="menus-form" action="?p=menus"> <form method="post" id="menus-form" action="?p=menus">
<?php csrf(); ?> <?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" name="save" class="btn btn-info">Save</button><br/><br/>
<div class="row"> <div class="row">
<?php foreach ($config['menu_categories'] as $id => $cat): ?> <?php foreach ($config['menu_categories'] as $id => $cat): ?>
<div class="col-md-12 col-lg-6"> <div class="col-md-12 col-lg-6">
@@ -132,12 +149,13 @@ if (isset($_POST['template'])) {
if (isset($menus[$id])) { if (isset($menus[$id])) {
$i = 0; $i = 0;
foreach ($menus[$id] as $menu): foreach ($menus[$id] as $menu):
$color = (empty($menu['color']) ? ($cat['default_links_color'] ?? ($config['menu_default_links_color'] ?? ($config['menu_default_color'] ?? '#ffffff'))) : '#' . $menu['color']);
?> ?>
<li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo escapeHtml($menu['name']); ?>"/> <li class="ui-state-default" id="list-<?php echo $id ?>-<?php echo $i ?>"><label>Name:</label> <input type="text" name="menu[<?php echo $id ?>][]" value="<?php echo escapeHtml($menu['name']); ?>"/>
<label>Link:</label> <input type="text" name="menu_link[<?php echo $id ?>][]" value="<?php echo $menu['link'] ?>"/> <label>Link:</label> <input type="text" name="menu_link[<?php echo $id ?>][]" value="<?php echo $menu['link'] ?>"/>
<input type="hidden" name="menu_blank[<?php echo $id ?>][]" value="0"/> <input type="hidden" name="menu_blank[<?php echo $id ?>][]" value="0"/>
<label><input class="blank-checkbox" type="checkbox" <?php echo($menu['blank'] == 1 ? 'checked' : '') ?>/><span title="Open in New Window">New Window</span></label> <label><input class="blank-checkbox" type="checkbox" <?php echo($menu['blank'] == 1 ? 'checked' : '') ?>/><span title="Open in New Window">New Window</span></label>
<input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo (empty($menu['color']) ? ($config['menu_default_color'] ?? '#ffffff') : $menu['color']); ?>"/> <input class="color-picker" type="text" name="menu_color[<?php echo $id ?>][]" value="<?php echo $color; ?>"/>
<a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li> <a class="remove-button" id="remove-button-<?php echo $id ?>-<?php echo $i ?>"><i class="fas fa-trash"></a></i></li>
<?php $i++; $last_id[$id] = $i; <?php $i++; $last_id[$id] = $i;
endforeach; endforeach;
@@ -150,7 +168,7 @@ if (isset($_POST['template'])) {
</div> </div>
<div class="row pb-2"> <div class="row pb-2">
<div class="col-md-12"> <div class="col-md-12">
<button type="submit" class="btn btn-info">Save</button> <button type="submit" name="save" class="btn btn-info">Save</button>
<?php <?php
echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>'; echo '<button type="button" class="btn btn-danger float-right" value="Cancel" onclick="window.location = \'' . ADMIN_URL . '?p=menus\';"><i class="fas fa-cancel"></i> Cancel</button>';
?> ?>
@@ -161,15 +179,19 @@ if (isset($_POST['template'])) {
$twig->display('admin.menus.js.html.twig', array( $twig->display('admin.menus.js.html.twig', array(
'menus' => $menus, 'menus' => $menus,
'last_id' => $last_id, 'last_id' => $last_id,
'menu_default_color' => $config['menu_default_color'] ?? '#ffffff'
)); ));
?> ?>
<?php <?php
} else { } else {
$templates = Menu::select('template')->distinct()->get()->toArray(); $templates = Menu::select('template')->distinct()->get()->toArray();
foreach ($templates as $key => $value) { foreach ($templates as $key => $value) {
$file = TEMPLATES . $value['template'] . '/config.php'; $path = TEMPLATES . $value['template'];
if (!file_exists($file)) {
if (isset($pluginThemes[$value['template']])) {
$path = BASE . $pluginThemes[$value['template']];
}
if (!file_exists($path . '/config.php')) {
unset($templates[$key]); unset($templates[$key]);
} }
} }
@@ -178,3 +200,11 @@ if (isset($_POST['template'])) {
'templates' => $templates 'templates' => $templates
)); ));
} }
function onTemplateMenusChange(): void
{
$cache = Cache::getInstance();
if ($cache->enabled()) {
$cache->delete('template_menus');
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -19,7 +19,7 @@
{% set i = i + 1 %} {% set i = i + 1 %}
<tr> <tr>
<th>{{ i }}</th> <th>{{ i }}</th>
<td><a href="?p=players&search_name={{ result.name }}">{{ result.name }}</a></td> <td><a href="?p=players&id={{ result.id }}">{{ result.name }}</a></td>
<td>{{ result.balance }}</td> <td>{{ result.balance }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -19,7 +19,7 @@
{% set i = i + 1 %} {% set i = i + 1 %}
<tr> <tr>
<th>{{ i }}</th> <th>{{ i }}</th>
<td><a href="?p=accounts&search_name={{ result.name }}">{{ result.name }}</a></td> <td><a href="?p=accounts&id={{ result.id }}">{{ result.name ?? result.id }}</a></td>
<td>{{ result.coins }}</td> <td>{{ result.coins }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -19,7 +19,7 @@
{% set i = i + 1 %} {% set i = i + 1 %}
<tr> <tr>
<th>{{ i }}</th> <th>{{ i }}</th>
<td><a href="?p=accounts&search_name={{ result.name }}">{{ result.name }}</a></td> <td><a href="?p=accounts&id={{ result.id }}">{{ result.id }}</a></td>
<td>{{ result.created|date("M d Y, H:i:s") }}</td> <td>{{ result.created|date("M d Y, H:i:s") }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -19,7 +19,7 @@
{% set i = i + 1 %} {% set i = i + 1 %}
<tr> <tr>
<th>{{ i }}</th> <th>{{ i }}</th>
<td><a href="?p=players&search_name={{ result.name }}">{{ result.name }}</a></td> <td><a href="?p=players&id={{ result.id }}">{{ result.name }}</a></td>
<td>{{ result.lastlogin|date("M d Y, H:i:s") }}</td> <td>{{ result.lastlogin|date("M d Y, H:i:s") }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -19,7 +19,7 @@
{% set i = i + 1 %} {% set i = i + 1 %}
<tr> <tr>
<th>{{ i }}</th> <th>{{ i }}</th>
<td><a href="?p=accounts&search_name={{ result.name }}">{{ result.name }}</a></td> <td><a href="?p=accounts&id={{ result.id }}">{{ result.name }}</a></td>
<td>{{ result.premium_points }}</td> <td>{{ result.premium_points }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -7,6 +7,10 @@
* @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!');
$title = 'News Panel'; $title = 'News Panel';
@@ -15,9 +19,6 @@ csrfProtect();
$use_datatable = true; $use_datatable = true;
require_once LIBS . 'forum.php';
require_once LIBS . 'news.php';
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.'; echo 'Access denied.';
return; return;
@@ -25,7 +26,7 @@ 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 be modified without schema changes)
const NEWS_TITLE_LIMIT = 100; const NEWS_TITLE_LIMIT = 100;
const NEWS_BODY_LIMIT = 65535; // maximum news body length const NEWS_BODY_LIMIT = 65535; // maximum news body length
const ARTICLE_TEXT_LIMIT = 300; const ARTICLE_TEXT_LIMIT = 300;
@@ -46,26 +47,24 @@ if(!empty($action))
$forum_section = $_POST['forum_section'] ?? null; $forum_section = $_POST['forum_section'] ?? null;
$errors = []; $errors = [];
if($action == 'new') { if (isRequestMethod('post')) {
if(isset($forum_section) && $forum_section != '-1') { if ($action == 'new') {
if (isset($forum_section) && $forum_section != '-1') {
$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors); $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; $type = $category = $player_id = 0;
success('Added successful.'); success('Added successful.');
} }
} } else if ($action == 'delete') {
else if($action == 'delete') {
if (News::delete($id, $errors)) { if (News::delete($id, $errors)) {
success('Deleted successful.'); success('Deleted successful.');
} }
} } else if ($action == 'edit') {
else if($action == 'edit') if (isset($id) && !isset($p_title)) {
{
if(isset($id) && !isset($p_title)) {
$news = News::get($id); $news = News::get($id);
$p_title = $news['title']; $p_title = $news['title'];
$body = $news['body']; $body = $news['body'];
@@ -75,12 +74,11 @@ if(!empty($action))
$player_id = $news['player_id']; $player_id = $news['player_id'];
$article_text = $news['article_text']; $article_text = $news['article_text'];
$article_image = $news['article_image']; $article_image = $news['article_image'];
} } else {
else { if (News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) {
if(News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) {
// update forum thread if exists // update forum thread if exists
if(isset($forum_section) && Validator::number($forum_section)) { 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)); $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 = ''; $action = $p_title = $body = $comments = $article_text = $article_image = '';
@@ -89,19 +87,19 @@ if(!empty($action))
success('Updated successful.'); success('Updated successful.');
} }
} }
} } else if ($action == 'hide') {
else if($action == 'hide') { if (News::toggleHide($id, $errors, $status)) {
if (News::toggleHidden($id, $errors, $status)) {
success(($status == 1 ? 'Hide' : 'Show') . ' successful.'); success(($status == 1 ? 'Hide' : 'Show') . ' 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'],
@@ -138,18 +136,27 @@ if($action == 'edit' || $action == 'new') {
$query = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news')); $query = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news'));
$newses = array(); $newses = array();
$cachePlayers = [];
foreach ($query as $_news) { foreach ($query as $_news) {
$playerId = $_news['player_id'];
if (isset($cachePlayers[$playerId])) {
$_player = $cachePlayers[$playerId];
}
else {
$_player = new OTS_Player(); $_player = new OTS_Player();
$_player->load($_news['player_id']); $_player->load($playerId);
$cachePlayers[$playerId] = $_player;
}
$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, false) : '',
); );
} }

View File

@@ -16,7 +16,7 @@ $title = 'Notepad';
csrfProtect(); 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

@@ -36,7 +36,7 @@ const PAGE_TITLE_LIMIT = 30;
const PAGE_NAME_LIMIT = 30; const PAGE_NAME_LIMIT = 30;
const 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 = $_POST['id']; $id = $_POST['id'];
} }
@@ -97,7 +97,7 @@ if (!empty($action)) {
} }
} }
} else if ($action == 'hide') { } else if ($action == 'hide') {
if (Pages::toggleHidden($id, $errors, $status)) { if (Pages::toggleHide($id, $errors, $status)) {
success(($status == 0 ? 'Show' : 'Hide') . ' successful.'); success(($status == 0 ? 'Show' : 'Hide') . ' successful.');
} }
} }
@@ -112,7 +112,7 @@ $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();

View File

@@ -8,6 +8,7 @@
* @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!');
@@ -19,7 +20,6 @@ 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'),
@@ -51,22 +51,20 @@ else if (isset($_REQUEST['search'])) {
if (strlen($search_player) < 3 && !Validator::number($search_player)) { if (strlen($search_player) < 3 && !Validator::number($search_player)) {
echo_error('Player name is too short.'); echo_error('Player name is too short.');
} else { } else {
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote($search_player)); $query = Player::where('name', 'like', '%' . $search_player . '%')->orderBy('name')->limit(11)->get(['id', 'name']);
if ($query->rowCount() == 1) { if (count($query) == 0) {
$query = $query->fetch(); echo_error('No entries found.');
$id = (int)$query['id']; } else if (count($query) == 1) {
$id = $query->first()->getKey();
} else if (count($query) > 10) {
echo_error('Specified name resulted with too many players.');
} else { } else {
$query = $db->query('SELECT `id`, `name` FROM `players` WHERE `name` LIKE ' . $db->quote('%' . $search_player . '%'));
if ($query->rowCount() > 0 && $query->rowCount() <= 10) {
$str_construct = 'Do you mean?<ul>'; $str_construct = 'Do you mean?<ul>';
foreach ($query as $row) foreach ($query as $row) {
$str_construct .= '<li><a href="' . $player_base . '&id=' . $row['id'] . '">' . $row['name'] . '</a></li>'; $str_construct .= '<li><a href="' . $player_base . '&id=' . $row->getKey() . '">' . $row->name . '</a></li>';
}
$str_construct .= '</ul>'; $str_construct .= '</ul>';
echo_error($str_construct); echo_error($str_construct);
} else if ($query->rowCount() > 10)
echo_error('Specified name resulted with too many players.');
else
echo_error('No entries found.');
} }
} }
} }
@@ -202,7 +200,7 @@ else if (isset($_REQUEST['search'])) {
if ($hasBlessingsColumn) { if ($hasBlessingsColumn) {
$blessings = $_POST['blessings']; $blessings = $_POST['blessings'];
verify_number($blessings, 'Blessings', 2); verify_number($blessings, 'Blessings', 3);
} }
$balance = $_POST['balance']; $balance = $_POST['balance'];
@@ -213,7 +211,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);
@@ -274,7 +272,7 @@ else if (isset($_REQUEST['search'])) {
$player->setLossContainers($loss_containers); $player->setLossContainers($loss_containers);
$player->setLossItems($loss_items); $player->setLossItems($loss_items);
} }
if ($db->hasColumn('players', 'blessings')) if ($hasBlessingsColumn)
$player->setBlessings($blessings); $player->setBlessings($blessings);
if ($hasBlessingColumn) { if ($hasBlessingColumn) {
@@ -290,7 +288,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);
@@ -307,7 +305,7 @@ else if (isset($_REQUEST['search'])) {
} }
} }
} else if ($id == 0) { } else if ($id == 0) {
$players_db = $db->query('SELECT `id`, `name`, `level` FROM `players` ORDER BY `id` asc'); $players_db = Player::orderBy('id')->get(['id','name', 'level']);
?> ?>
<div class="col-12 col-sm-12 col-lg-10"> <div class="col-12 col-sm-12 col-lg-10">
<div class="card card-info card-outline"> <div class="card card-info card-outline">
@@ -327,11 +325,11 @@ else if (isset($_REQUEST['search'])) {
<tbody> <tbody>
<?php foreach ($players_db as $player_db): ?> <?php foreach ($players_db as $player_db): ?>
<tr> <tr>
<th><?php echo $player_db['id']; ?></th> <th><?php echo $player_db->id; ?></th>
<td><?php echo $player_db['name']; ?></a></td> <td><?php echo $player_db->name; ?></a></td>
<td><?php echo $player_db['level']; ?></a></td> <td><?php echo $player_db->level; ?></a></td>
<td><a href="?p=players&id=<?php echo $player_db['id']; ?>" class="btn btn-success btn-sm" title="Edit"> <td><a href="?p=players&id=<?php echo $player_db->id; ?>" class="btn btn-success btn-sm" title="Edit">
<i class="fas fa-pencil-alt"></i> <i class="fas fa-pencil-alt"></i>
</a> </a>
</td> </td>
@@ -375,7 +373,7 @@ 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(); ?> <?php csrf(); ?>
<div class="card-body"> <div class="card-body">
<div class="tab-content" id="tabs-tabContent"> <div class="tab-content" id="tabs-tabContent">
@@ -485,8 +483,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>

View File

@@ -7,6 +7,9 @@
* @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';
@@ -14,13 +17,17 @@ csrfProtect();
$use_datatable = true; $use_datatable = true;
require_once LIBS . 'plugins.php'; if (!setting('core.admin_plugins_manage_enable')) {
if (!getBoolean(setting('core.admin_plugins_manage_enable'))) {
warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.'); warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.');
} }
else { else {
$twig->display('admin.plugins.form.html.twig'); $pluginUploadEnabled = true;
if(!\class_exists('\ZipArchive')) {
error('Please install PHP zip extension. Plugins upload disabled until then.');
$pluginUploadEnabled = false;
}
$twig->display('admin.plugins.form.html.twig', ['pluginUploadEnabled' => $pluginUploadEnabled]);
if (isset($_POST['uninstall'])) { if (isset($_POST['uninstall'])) {
$uninstall = $_POST['uninstall']; $uninstall = $_POST['uninstall'];
@@ -44,6 +51,56 @@ else {
} else { } else {
error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError()); error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError());
} }
}
else if (isset($_GET['check-updates'])) {
$repoUri = $config['admin_plugins_api_uri'] ?? 'https://plugins.my-aac.org/api/';
success("Fetching latest info from $repoUri..");
$adminPlugins = new \MyAAC\Admin\Plugins();
$adminPlugins->setApiBaseUri($repoUri);
try {
$plugins = $adminPlugins->getLatestVersions();
}
catch (Exception $e) {
error($e->getMessage());
}
if (isset($plugins) && count($plugins) > 0) {
$outdated = [];
foreach (get_plugins(true) as $plugin) {
$string = file_get_contents(BASE . 'plugins/' . $plugin . '.json');
$plugin_info = json_decode($string, true);
if (!$plugin_info) {
continue;
}
$disabled = (str_contains($plugin, 'disabled.'));
$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin);
$info = $plugins[$pluginOriginal] ?? false;
if ($info && version_compare($info['version'], $plugin_info['version'], '>')) {
$outdated[] = [
'name' => $pluginOriginal,
'yourVersion' => $plugin_info['version'],
'latestVersion' => $info['version'],
'link' => $info['link'] ?? 'Unknown',
'download_link' => $info['download_link'] ?? 'Unknown',
];
}
}
if (count($outdated) > 0) {
info('Following updates have been found for your plugins:');
$twig->display('admin.plugins.outdated.html.twig', ['plugins' => $outdated]);
}
else {
success('All plugins up to date!');
}
}
} else if (isset($_FILES['plugin']['name'])) { } else if (isset($_FILES['plugin']['name'])) {
$file = $_FILES['plugin']; $file = $_FILES['plugin'];
$filename = $file['name']; $filename = $file['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';
@@ -44,7 +48,7 @@ if (!is_array($settingsFile)) {
$settingsKeyName = ($plugin == 'core' ? $plugin : $settingsFile['key']); $settingsKeyName = ($plugin == 'core' ? $plugin : $settingsFile['key']);
$title = ($plugin == 'core' ? 'Settings' : 'Plugin Settings - ' . $plugin); $title = ($plugin == 'core' ? 'Settings' : 'Plugin Settings - ' . $settingsFile['name']);
$settingsParsed = Settings::display($settingsKeyName, $settingsFile['settings']); $settingsParsed = Settings::display($settingsKeyName, $settingsFile['settings']);

View File

@@ -12,19 +12,18 @@ 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;
if (!setting('core.visitors_counter')): ?> if (!setting('core.visitors_counter')): ?>
Visitors counter is disabled.<br/> Visitors counter is disabled.<br/>
You can enable it by editing this configurable in <b>config.local.php</b> file:<br/> You can enable it in Settings -> General -> Visitors Counter.<br/>
<p style="margin-left: 3em;"><b>$config['visitors_counter'] = true;</b></p>
<?php <?php
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 {
@@ -46,7 +45,7 @@ foreach ($tmp as &$visitor) {
if ($dd->isBot()) { if ($dd->isBot()) {
$bot = $dd->getBot(); $bot = $dd->getBot();
$message = '(Bot) %s, <a href="%s" target="_blank">%s</a>'; $message = '(Bot) %s, <a href="%s" target="_blank">%s</a>';
$browser = sprintf($message, $bot['category'], $bot['url'], $bot['name']); $browser = sprintf($message, $bot['category'] ?? 'Unknown', $bot['url'] ?? '', $bot['name'] ?? 'Unknown name');
} }
else { else {
$osFamily = OperatingSystem::getOsFamily($dd->getOs('name')); $osFamily = OperatingSystem::getOsFamily($dd->getOs('name'));

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

@@ -191,8 +191,8 @@ 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>

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,7 @@
<?php <?php
use MyAAC\Settings;
const MYAAC_ADMIN = true; const MYAAC_ADMIN = true;
require '../../common.php'; require '../../common.php';
@@ -6,11 +9,6 @@ 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.');

View File

@@ -20,14 +20,14 @@
* *
* @package MyAAC * @package MyAAC
* @author Slawkens <slawkens@gmail.com> * @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC * @copyright 2024 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 = '1.0-dev'; const MYAAC_VERSION = '1.7';
const DATABASE_VERSION = 38; const DATABASE_VERSION = 45;
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'));
@@ -122,41 +122,33 @@ if (!IS_CLI) {
session_start(); session_start();
} }
// basedir if (file_exists(BASE . 'config.local.php')) {
$basedir = ''; require BASE . 'config.local.php';
$tmp = explode('/', $_SERVER['SCRIPT_NAME']); }
$size = count($tmp) - 1;
for($i = 1; $i < $size; $i++)
$basedir .= '/' . $tmp[$i];
$basedir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $basedir); require SYSTEM . 'base.php';
define('BASE_DIR', $basedir); define('BASE_DIR', $baseDir);
if(!IS_CLI) { if(!IS_CLI) {
if (isset($_SERVER['HTTP_HOST'][0])) { if (isset($config['site_url'])) {
$baseHost = $_SERVER['HTTP_HOST']; $hasSlashAtEnd = ($config['site_url'][strlen($config['site_url']) - 1] == '/');
} else {
if (isset($_SERVER['SERVER_NAME'][0])) {
$baseHost = $_SERVER['SERVER_NAME'];
} else {
$baseHost = $_SERVER['SERVER_ADDR'];
}
}
define('SERVER_URL', $config['site_url']);
define('BASE_URL', SERVER_URL . ($hasSlashAtEnd ? '' : '/'));
define('ADMIN_URL', SERVER_URL . ($hasSlashAtEnd ? '' : '/') . ADMIN_PANEL_FOLDER . '/');
}
else {
define('SERVER_URL', 'http' . (isHttps() ? '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 . '/');
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); //define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
} }
if (file_exists(BASE . 'config.local.php')) {
require BASE . 'config.local.php';
} }
/** @var array $config */ /** @var array $config */
ini_set('log_errors', 1); ini_set('log_errors', 1);
if(@$config['env'] === 'dev') { if(@$config['env'] === 'dev' || defined('MYAAC_INSTALL')) {
ini_set('display_errors', 1); ini_set('display_errors', 1);
ini_set('display_startup_errors', 1); ini_set('display_startup_errors', 1);
error_reporting(E_ALL); error_reporting(E_ALL);

View File

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

3455
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

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
@@ -68,7 +67,9 @@ describe('Install MyAAC', () => {
cy.get('form').submit() cy.get('form').submit()
cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 30000 }).should('be.visible') cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 60000 }).should('be.visible')
cy.wait(2000);
cy.screenshot('install-finish') cy.screenshot('install-finish')
}) })

View File

@@ -17,7 +17,7 @@ describe('Check Public Pages', () => {
it('Go to changelog page', () => { it('Go to changelog page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/changelog', url: Cypress.env('URL') + '/change-log',
method: 'GET', method: 'GET',
}) })
}) })
@@ -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',
}) })
}) })
@@ -116,9 +116,9 @@ describe('Check Public Pages', () => {
}) })
// library // library
it('Go to creatures page', () => { it('Go to monsters page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/creatures', url: Cypress.env('URL') + '/monsters',
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') + '/ots-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',
}) })
}) })

View File

@@ -4,7 +4,7 @@ const YOU_ARE_NOT_LOGGEDIN = 'You are not logged in.';
describe('Check Protected Pages', () => { describe('Check Protected Pages', () => {
// character actions // character actions
it('Go to accouht character creation page', () => { it('Go to account character creation page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/account/character/create', url: Cypress.env('URL') + '/account/character/create',
method: 'GET', method: 'GET',
@@ -12,7 +12,7 @@ describe('Check Protected Pages', () => {
cy.contains(REQUIRED_LOGIN_MESSAGE) cy.contains(REQUIRED_LOGIN_MESSAGE)
}) })
it('Go to accouht character deletion page', () => { it('Go to account character deletion page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/account/character/delete', url: Cypress.env('URL') + '/account/character/delete',
method: 'GET', method: 'GET',
@@ -21,7 +21,7 @@ describe('Check Protected Pages', () => {
}) })
// account actions // account actions
it('Go to accouht email change page', () => { it('Go to account email change page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/account/email', url: Cypress.env('URL') + '/account/email',
method: 'GET', method: 'GET',
@@ -29,7 +29,7 @@ describe('Check Protected Pages', () => {
cy.contains(REQUIRED_LOGIN_MESSAGE) cy.contains(REQUIRED_LOGIN_MESSAGE)
}) })
it('Go to accouht password change page', () => { it('Go to account password change page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/account/password', url: Cypress.env('URL') + '/account/password',
method: 'GET', method: 'GET',
@@ -37,7 +37,7 @@ describe('Check Protected Pages', () => {
cy.contains(REQUIRED_LOGIN_MESSAGE) cy.contains(REQUIRED_LOGIN_MESSAGE)
}) })
it('Go to accouht info change page', () => { it('Go to account info change page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/account/info', url: Cypress.env('URL') + '/account/info',
method: 'GET', method: 'GET',
@@ -45,7 +45,7 @@ describe('Check Protected Pages', () => {
cy.contains(REQUIRED_LOGIN_MESSAGE) cy.contains(REQUIRED_LOGIN_MESSAGE)
}) })
it('Go to accouht logout change page', () => { it('Go to account logout change page', () => {
cy.visit({ cy.visit({
url: Cypress.env('URL') + '/account/logout', url: Cypress.env('URL') + '/account/logout',
method: 'GET', method: 'GET',

BIN
images/order_asc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 B

BIN
images/order_desc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 B

105
index.php
View File

@@ -24,15 +24,18 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use MyAAC\UsageStatistics;
use MyAAC\Visitors;
require_once 'common.php'; require_once 'common.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';
$uri = $_SERVER['REQUEST_URI']; $uri = $_SERVER['REQUEST_URI'];
if(false !== strpos($uri, 'index.php')) { if(str_contains($uri, 'index.php')) {
$uri = str_replace_first('/index.php', '', $uri); $uri = str_replace_first('/index.php', '', $uri);
} }
if(0 === strpos($uri, '/')) { if(str_starts_with($uri, '/')) {
$uri = str_replace_first('/', '', $uri); $uri = str_replace_first('/', '', $uri);
} }
@@ -59,18 +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.');
}
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';
@@ -78,53 +76,8 @@ 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); $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);
@@ -140,6 +93,7 @@ if(setting('core.backward_support')) {
if($logged && $account_logged) if($logged && $account_logged)
$group_id_of_acc_logged = $account_logged->getGroupId(); $group_id_of_acc_logged = $account_logged->getGroupId();
$config['serverPath'] = $config['server_path'];
$config['site'] = &$config; $config['site'] = &$config;
$config['server'] = &$config['lua']; $config['server'] = &$config['lua'];
$config['site']['shop_system'] = setting('core.gifts_system'); $config['site']['shop_system'] = setting('core.gifts_system');
@@ -164,6 +118,50 @@ if(setting('core.backward_support')) {
$config['status']['serverStatus_' . $key] = $value; $config['status']['serverStatus_' . $key] = $value;
} }
if(setting('core.views_counter')) {
require_once SYSTEM . 'counter.php';
}
if(setting('core.visitors_counter')) {
$visitors = new Visitors(setting('core.visitors_counter_ttl'));
}
require_once SYSTEM . 'router.php';
// 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, 60 * 60);
}
}
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(), 60 * 60);
}
}
}
/** /**
* @var OTS_Account $account_logged * @var OTS_Account $account_logged
*/ */
@@ -172,6 +170,7 @@ if ($logged && admin()) {
'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId() 'username' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId()
]); ]);
} }
$title_full = (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName']; $title_full = (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName'];
require $template_path . '/' . $template_index; require $template_path . '/' . $template_index;

View File

@@ -26,6 +26,9 @@ if(!isset($error) || !$error) {
$config['database_type'] = $config['lua']['database_type']; $config['database_type'] = $config['lua']['database_type'];
else if(isset($config['lua']['sql_type'])) // otserv else if(isset($config['lua']['sql_type'])) // otserv
$config['database_type'] = $config['lua']['sql_type']; $config['database_type'] = $config['lua']['sql_type'];
else {
$config['database_type'] = '';
}
$config['database_type'] = strtolower($config['database_type']); $config['database_type'] = strtolower($config['database_type']);
if(empty($config['database_type'])) { if(empty($config['database_type'])) {

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,88 +1,73 @@
SET @myaac_database_version = 36; SET @myaac_database_version = 45;
CREATE TABLE `myaac_account_actions` CREATE TABLE `myaac_account_actions`
( (
`account_id` INT(11) NOT NULL, `account_id` int NOT NULL,
`ip` INT(10) UNSIGNED NOT NULL DEFAULT 0, `ip` int unsigned NOT NULL DEFAULT 0,
`ipv6` BINARY(16) NOT NULL DEFAULT 0, `ipv6` binary(16) NOT NULL DEFAULT 0,
`date` INT(11) NOT NULL DEFAULT 0, `date` int NOT NULL DEFAULT 0,
`action` VARCHAR(255) NOT NULL DEFAULT '', `action` varchar(255) NOT NULL DEFAULT '',
KEY (`account_id`) KEY (`account_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_admin_menu` CREATE TABLE `myaac_admin_menu`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT '', `name` varchar(255) NOT NULL DEFAULT '',
`page` VARCHAR(255) NOT NULL DEFAULT '', `page` varchar(255) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` int NOT NULL DEFAULT 0,
`flags` INT(11) NOT NULL DEFAULT 0, `flags` int NOT NULL DEFAULT 0,
`enabled` INT(1) NOT NULL DEFAULT 1, `enabled` int NOT NULL DEFAULT 1,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_bugtracker`
(
`account` VARCHAR(255) NOT NULL,
`type` INT(11) NOT NULL DEFAULT 0,
`status` INT(11) NOT NULL DEFAULT 0,
`text` text NOT NULL,
`id` INT(11) NOT NULL DEFAULT 0,
`subject` VARCHAR(255) NOT NULL DEFAULT '',
`reply` INT(11) NOT NULL DEFAULT 0,
`who` INT(11) NOT NULL DEFAULT 0,
`uid` INT(11) NOT NULL AUTO_INCREMENT,
`tag` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;
CREATE TABLE `myaac_changelog` CREATE TABLE `myaac_changelog`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`body` VARCHAR(500) NOT NULL DEFAULT '', `body` varchar(500) NOT NULL DEFAULT '',
`type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - added, 2 - removed, 3 - changed, 4 - fixed', `type` tinyint NOT NULL DEFAULT 0 COMMENT '1 - added, 2 - removed, 3 - changed, 4 - fixed',
`where` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - server, 2 - site', `where` tinyint NOT NULL DEFAULT 0 COMMENT '1 - server, 2 - site',
`date` INT(11) NOT NULL DEFAULT 0, `date` int NOT NULL DEFAULT 0,
`player_id` INT(11) NOT NULL DEFAULT 0, `player_id` int NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
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`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) NOT NULL, `name` varchar(30) NOT NULL,
`value` VARCHAR(1000) NOT NULL, `value` varchar(1000) NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE (`name`) UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
INSERT INTO `myaac_config` (`name`, `value`) VALUES ('database_version', @myaac_database_version); INSERT INTO `myaac_config` (`name`, `value`) VALUES ('database_version', @myaac_database_version);
CREATE TABLE `myaac_faq` CREATE TABLE `myaac_faq`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`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 NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_forum_boards` CREATE TABLE `myaac_forum_boards`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL, `name` varchar(32) NOT NULL,
`description` VARCHAR(255) NOT NULL DEFAULT '', `description` varchar(255) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` int NOT NULL DEFAULT 0,
`guild` INT(11) NOT NULL DEFAULT 0, `guild` int NOT NULL DEFAULT 0,
`access` INT(11) NOT NULL DEFAULT 0, `access` int NOT NULL DEFAULT 0,
`closed` TINYINT(1) NOT NULL DEFAULT 0, `closed` tinyint NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
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);
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUES (NULL, 'Trade', 'Trade offers.', 1); INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUES (NULL, 'Trade', 'Trade offers.', 1);
INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUES (NULL, 'Quests', 'Quest making.', 2); INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUES (NULL, 'Quests', 'Quest making.', 2);
@@ -91,102 +76,102 @@ INSERT INTO `myaac_forum_boards` (`id`, `name`, `description`, `ordering`) VALUE
CREATE TABLE `myaac_forum` CREATE TABLE `myaac_forum`
( (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`first_post` int(11) NOT NULL default '0', `first_post` int NOT NULL DEFAULT 0,
`last_post` int(11) NOT NULL default '0', `last_post` int NOT NULL DEFAULT 0,
`section` int(3) NOT NULL default '0', `section` int NOT NULL DEFAULT 0,
`replies` int(20) NOT NULL default '0', `replies` int NOT NULL DEFAULT 0,
`views` int(20) NOT NULL default '0', `views` int NOT NULL DEFAULT 0,
`author_aid` int(20) NOT NULL default '0', `author_aid` int NOT NULL DEFAULT 0,
`author_guid` int(20) NOT NULL default '0', `author_guid` int NOT NULL DEFAULT 0,
`post_text` text NOT NULL, `post_text` text NOT NULL,
`post_topic` varchar(255) NOT NULL DEFAULT '', `post_topic` varchar(255) NOT NULL DEFAULT '',
`post_smile` tinyint(1) NOT NULL default '0', `post_smile` tinyint NOT NULL DEFAULT 0,
`post_html` tinyint(1) NOT NULL default '0', `post_html` tinyint NOT NULL DEFAULT 0,
`post_date` int(20) NOT NULL default '0', `post_date` int NOT NULL DEFAULT 0,
`last_edit_aid` int(20) NOT NULL default '0', `last_edit_aid` int NOT NULL DEFAULT 0,
`edit_date` int(20) NOT NULL default '0', `edit_date` int NOT NULL DEFAULT 0,
`post_ip` varchar(32) NOT NULL default '0.0.0.0', `post_ip` varchar(45) NOT NULL DEFAULT '0.0.0.0',
`sticked` tinyint(1) NOT NULL DEFAULT '0', `sticked` tinyint NOT NULL DEFAULT 0,
`closed` tinyint(1) NOT NULL DEFAULT '0', `closed` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `section` (`section`) KEY `section` (`section`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_menu` CREATE TABLE `myaac_menu`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`template` VARCHAR(255) NOT NULL, `template` varchar(255) NOT NULL,
`name` VARCHAR(255) NOT NULL, `name` varchar(255) NOT NULL,
`link` VARCHAR(255) NOT NULL, `link` varchar(255) NOT NULL,
`blank` TINYINT(1) NOT NULL DEFAULT 0, `blank` tinyint NOT NULL DEFAULT 0,
`color` VARCHAR(6) NOT NULL DEFAULT '', `color` varchar(6) NOT NULL DEFAULT '',
`category` INT(11) NOT NULL DEFAULT 1, `category` int NOT NULL DEFAULT 1,
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` int NOT NULL DEFAULT 0,
`enabled` INT(1) NOT NULL DEFAULT 1, `enabled` int NOT NULL DEFAULT 1,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_monsters` ( CREATE TABLE `myaac_monsters` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`hidden` tinyint(1) NOT NULL default 0, `hide` tinyint NOT NULL DEFAULT 0,
`name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL,
`mana` int(11) NOT NULL DEFAULT 0, `mana` int NOT NULL DEFAULT 0,
`exp` int(11) NOT NULL, `exp` int NOT NULL,
`health` int(11) NOT NULL, `health` int NOT NULL,
`look` VARCHAR(255) NOT NULL DEFAULT '', `look` varchar(255) NOT NULL DEFAULT '',
`speed_lvl` int(11) NOT NULL default 1, `speed_lvl` int NOT NULL DEFAULT 1,
`use_haste` tinyint(1) NOT NULL, `use_haste` tinyint NOT NULL,
`voices` text NOT NULL, `voices` text NOT NULL,
`immunities` varchar(255) NOT NULL, `immunities` varchar(255) NOT NULL,
`elements` TEXT NOT NULL, `elements` text NOT NULL,
`summonable` tinyint(1) NOT NULL, `summonable` tinyint NOT NULL,
`convinceable` tinyint(1) NOT NULL, `convinceable` tinyint NOT NULL,
`pushable` TINYINT(1) NOT NULL DEFAULT '0', `pushable` tinyint NOT NULL DEFAULT 0,
`canpushitems` TINYINT(1) NOT NULL DEFAULT '0', `canpushitems` tinyint NOT NULL DEFAULT 0,
`canwalkonenergy` TINYINT(1) NOT NULL DEFAULT '0', `canwalkonenergy` tinyint NOT NULL DEFAULT 0,
`canwalkonpoison` TINYINT(1) NOT NULL DEFAULT '0', `canwalkonpoison` tinyint NOT NULL DEFAULT 0,
`canwalkonfire` TINYINT(1) NOT NULL DEFAULT '0', `canwalkonfire` tinyint NOT NULL DEFAULT 0,
`runonhealth` TINYINT(1) NOT NULL DEFAULT '0', `runonhealth` tinyint NOT NULL DEFAULT 0,
`hostile` TINYINT(1) NOT NULL DEFAULT '0', `hostile` tinyint NOT NULL DEFAULT 0,
`attackable` TINYINT(1) NOT NULL DEFAULT '0', `attackable` tinyint NOT NULL DEFAULT 0,
`rewardboss` TINYINT(1) NOT NULL DEFAULT '0', `rewardboss` tinyint NOT NULL DEFAULT 0,
`defense` INT(11) NOT NULL DEFAULT '0', `defense` int NOT NULL DEFAULT 0,
`armor` INT(11) NOT NULL DEFAULT '0', `armor` int NOT NULL DEFAULT 0,
`canpushcreatures` TINYINT(1) NOT NULL DEFAULT '0', `canpushcreatures` tinyint NOT NULL DEFAULT 0,
`race` varchar(255) NOT NULL, `race` varchar(255) NOT NULL,
`loot` text NOT NULL, `loot` text NOT NULL,
`summons` TEXT NOT NULL, `summons` text NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_news` CREATE TABLE `myaac_news`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL, `title` varchar(100) NOT NULL,
`body` TEXT NOT NULL, `body` text NOT NULL,
`type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - news, 2 - ticker, 3 - article', `type` tinyint NOT NULL DEFAULT 0 COMMENT '1 - news, 2 - ticker, 3 - article',
`date` INT(11) NOT NULL DEFAULT 0, `date` int NOT NULL DEFAULT 0,
`category` TINYINT(1) NOT NULL DEFAULT 0, `category` tinyint NOT NULL DEFAULT 0,
`player_id` INT(11) NOT NULL DEFAULT 0, `player_id` int NOT NULL DEFAULT 0,
`last_modified_by` INT(11) NOT NULL DEFAULT 0, `last_modified_by` int NOT NULL DEFAULT 0,
`last_modified_date` INT(11) NOT NULL DEFAULT 0, `last_modified_date` int NOT NULL DEFAULT 0,
`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 NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_news_categories` CREATE TABLE `myaac_news_categories`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`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 NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 0); INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 0);
INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 1); INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 1);
@@ -196,91 +181,91 @@ INSERT INTO `myaac_news_categories` (`id`, `icon_id`) VALUES (NULL, 4);
CREATE TABLE `myaac_notepad` CREATE TABLE `myaac_notepad`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`account_id` INT(11) NOT NULL, `account_id` int NOT NULL,
/*`name` VARCHAR(30) NOT NULL,*/ /*`name` varchar(30) NOT NULL,*/
`content` TEXT NOT NULL, `content` text NOT NULL,
/*`public` TINYINT(1) NOT NULL DEFAULT 0*/ /*`public` tinyint NOT NULL DEFAULT 0*/
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_pages` CREATE TABLE `myaac_pages`
( (
`id` INT NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) NOT NULL, `name` varchar(30) NOT NULL,
`title` VARCHAR(30) NOT NULL, `title` varchar(30) NOT NULL,
`body` TEXT NOT NULL, `body` text NOT NULL,
`date` INT(11) NOT NULL DEFAULT 0, `date` int NOT NULL DEFAULT 0,
`player_id` INT(11) NOT NULL DEFAULT 0, `player_id` int NOT NULL DEFAULT 0,
`php` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 - plain html, 1 - php', `php` tinyint 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 NOT NULL DEFAULT 1 COMMENT '1 - enabled, 0 - disabled',
`access` TINYINT(2) NOT NULL DEFAULT 0, `access` tinyint NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` tinyint 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=utf8mb4;
CREATE TABLE `myaac_gallery` CREATE TABLE `myaac_gallery`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`comment` VARCHAR(255) NOT NULL DEFAULT '', `comment` varchar(255) NOT NULL DEFAULT '',
`image` VARCHAR(255) NOT NULL, `image` varchar(255) NOT NULL,
`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 NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0, `hide` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
INSERT INTO `myaac_gallery` (`id`, `ordering`, `comment`, `image`, `thumb`, `author`) VALUES (NULL, 1, 'Demon', 'images/gallery/demon.jpg', 'images/gallery/demon_thumb.gif', 'MyAAC'); INSERT INTO `myaac_gallery` (`id`, `ordering`, `comment`, `image`, `thumb`, `author`) VALUES (NULL, 1, 'Demon', 'images/gallery/demon.jpg', 'images/gallery/demon_thumb.gif', 'MyAAC');
CREATE TABLE `myaac_settings` CREATE TABLE `myaac_settings`
( (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT '', `name` varchar(255) NOT NULL DEFAULT '',
`key` VARCHAR(255) NOT NULL DEFAULT '', `key` varchar(255) NOT NULL DEFAULT '',
`value` TEXT NOT NULL, `value` text NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `key` (`key`) KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_spells` CREATE TABLE `myaac_spells`
( (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`spell` VARCHAR(255) NOT NULL DEFAULT '', `spell` varchar(255) NOT NULL DEFAULT '',
`name` VARCHAR(255) NOT NULL, `name` varchar(255) NOT NULL,
`words` VARCHAR(255) NOT NULL DEFAULT '', `words` varchar(255) NOT NULL DEFAULT '',
`category` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - attack, 2 - healing, 3 - summon, 4 - supply, 5 - support', `category` tinyint NOT NULL DEFAULT 0 COMMENT '1 - attack, 2 - healing, 3 - summon, 4 - supply, 5 - support',
`type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - instant, 2 - conjure, 3 - rune', `type` tinyint NOT NULL DEFAULT 0 COMMENT '1 - instant, 2 - conjure, 3 - rune',
`level` INT(11) NOT NULL DEFAULT 0, `level` int NOT NULL DEFAULT 0,
`maglevel` INT(11) NOT NULL DEFAULT 0, `maglevel` int NOT NULL DEFAULT 0,
`mana` INT(11) NOT NULL DEFAULT 0, `mana` int NOT NULL DEFAULT 0,
`soul` TINYINT(3) NOT NULL DEFAULT 0, `soul` tinyint NOT NULL DEFAULT 0,
`conjure_id` INT(11) NOT NULL DEFAULT 0, `conjure_id` int NOT NULL DEFAULT 0,
`conjure_count` TINYINT(3) NOT NULL DEFAULT 0, `conjure_count` tinyint NOT NULL DEFAULT 0,
`reagent` INT(11) NOT NULL DEFAULT 0, `reagent` int NOT NULL DEFAULT 0,
`item_id` INT(11) NOT NULL DEFAULT 0, `item_id` int NOT NULL DEFAULT 0,
`premium` TINYINT(1) NOT NULL DEFAULT 0, `premium` tinyint 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 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=utf8mb4;
CREATE TABLE `myaac_visitors` CREATE TABLE `myaac_visitors`
( (
`ip` VARCHAR(45) NOT NULL, `ip` varchar(45) NOT NULL,
`lastvisit` INT(11) NOT NULL DEFAULT 0, `lastvisit` int NOT NULL DEFAULT 0,
`page` VARCHAR(2048) NOT NULL, `page` varchar(2048) NOT NULL,
`user_agent` VARCHAR(255) NOT NULL DEFAULT '', `user_agent` varchar(255) NOT NULL DEFAULT '',
UNIQUE (`ip`) UNIQUE (`ip`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;
CREATE TABLE `myaac_weapons` CREATE TABLE `myaac_weapons`
( (
`id` INT(11) NOT NULL, `id` int NOT NULL,
`level` INT(11) NOT NULL DEFAULT 0, `level` int NOT NULL DEFAULT 0,
`maglevel` INT(11) NOT NULL DEFAULT 0, `maglevel` int NOT NULL DEFAULT 0,
`vocations` VARCHAR(100) NOT NULL DEFAULT '', `vocations` varchar(100) NOT NULL DEFAULT '',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;

View File

@@ -3,16 +3,15 @@
use Twig\Environment as Twig_Environment; use Twig\Environment as Twig_Environment;
use Twig\Loader\FilesystemLoader as Twig_FilesystemLoader; use Twig\Loader\FilesystemLoader as Twig_FilesystemLoader;
require '../common.php'; const MYAAC_INSTALL = true;
define('MYAAC_INSTALL', true); require '../common.php';
// includes // includes
require SYSTEM . 'functions.php'; 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';
@@ -115,7 +114,7 @@ else if($step == 'finish') {
$email = $_SESSION['var_email']; $email = $_SESSION['var_email'];
$password = $_SESSION['var_password']; $password = $_SESSION['var_password'];
$password_confirm = $_SESSION['var_password_confirm']; $password_confirm = $_SESSION['var_password_confirm'];
$player_name = $_SESSION['var_player_name']; $player_name = $_SESSION['var_player_name'] ?? null;
// email check // email check
if(empty($email)) { if(empty($email)) {
@@ -126,18 +125,7 @@ else if($step == 'finish') {
} }
// account check // account check
if(isset($_SESSION['var_account'])) { if(isset($_SESSION['var_account_id'])) {
if(empty($_SESSION['var_account'])) {
$errors[] = $locale['step_admin_account_error_empty'];
}
else if(!Validator::accountName($_SESSION['var_account'])) {
$errors[] = $locale['step_admin_account_error_format'];
}
else if(strtoupper($_SESSION['var_account']) == strtoupper($password)) {
$errors[] = $locale['step_admin_account_error_same'];
}
}
else if(isset($_SESSION['var_account_id'])) {
if(empty($_SESSION['var_account_id'])) { if(empty($_SESSION['var_account_id'])) {
$errors[] = $locale['step_admin_account_id_error_empty']; $errors[] = $locale['step_admin_account_id_error_empty'];
} }
@@ -148,6 +136,17 @@ else if($step == 'finish') {
$errors[] = $locale['step_admin_account_id_error_same']; $errors[] = $locale['step_admin_account_id_error_same'];
} }
} }
else if(isset($_SESSION['var_account'])) {
if(empty($_SESSION['var_account'])) {
$errors[] = $locale['step_admin_account_error_empty'];
}
else if(!Validator::accountName($_SESSION['var_account'])) {
$errors[] = $locale['step_admin_account_error_format'];
}
else if(strtoupper($_SESSION['var_account']) == strtoupper($password)) {
$errors[] = $locale['step_admin_account_error_same'];
}
}
// password check // password check
if(empty($password)) { if(empty($password)) {
@@ -160,13 +159,14 @@ else if($step == 'finish') {
$errors[] = $locale['step_admin_password_confirm_error_not_same']; $errors[] = $locale['step_admin_password_confirm_error_not_same'];
} }
if (isset($player_name)) {
// player name check // player name check
if(empty($player_name)) { if (empty($player_name)) {
$errors[] = $locale['step_admin_player_name_error_empty']; $errors[] = $locale['step_admin_player_name_error_empty'];
} } else if (!Validator::characterName($player_name)) {
else if(!Validator::characterName($player_name)) {
$errors[] = $locale['step_admin_player_name_error_format']; $errors[] = $locale['step_admin_player_name_error_format'];
} }
}
if(!empty($errors)) { if(!empty($errors)) {
$step = 'admin'; $step = 'admin';
@@ -183,14 +183,14 @@ clearstatcache();
if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) { if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) {
if(!file_exists(BASE . 'install/ip.txt')) { if(!file_exists(BASE . 'install/ip.txt')) {
$content = warning('AAC installation is disabled. To enable it make file <b>ip.txt</b> in install/ directory and put there your IP.<br/> $content = warning('AAC installation is disabled. To enable it make file <b>ip.txt</b> in install/ directory and put there your IP.<br/>
Your IP is:<br /><b>' . $_SERVER['REMOTE_ADDR'] . '</b>', true); Your IP is:<br /><b>' . get_browser_real_ip() . '</b>', true);
} }
else { else {
$file_content = trim(file_get_contents(BASE . 'install/ip.txt')); $file_content = trim(file_get_contents(BASE . 'install/ip.txt'));
$allow = false; $allow = false;
$listIP = preg_split('/\s+/', $file_content); $listIP = preg_split('/\s+/', $file_content);
foreach($listIP as $ip) { foreach($listIP as $ip) {
if($_SERVER['REMOTE_ADDR'] == $ip) { if(get_browser_real_ip() == $ip) {
$allow = true; $allow = true;
} }
} }
@@ -199,7 +199,7 @@ if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) {
{ {
$content = warning('In file <b>install/ip.txt</b> must be your IP!<br/> $content = warning('In file <b>install/ip.txt</b> must be your IP!<br/>
In file is:<br /><b>' . nl2br($file_content) . '</b><br/> In file is:<br /><b>' . nl2br($file_content) . '</b><br/>
Your IP is:<br /><b>' . $_SERVER['REMOTE_ADDR'] . '</b>', true); Your IP is:<br /><b>' . get_browser_real_ip() . '</b>', true);
} }
else { else {
ob_start(); ob_start();

View File

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

View File

@@ -10,6 +10,14 @@ foreach($config['clients'] as $client) {
$clients[$client] = $client_version; $clients[$client] = $client_version;
} }
if (empty($_SESSION['var_site_url'])) {
//require SYSTEM . 'base.php';
$serverUrl = 'http' . (isHttps() ? 's' : '') . '://' . $baseHost;
$siteURL = $serverUrl . $baseDir;
$_SESSION['var_site_url'] = $siteURL;
}
$twig->display('install.config.html.twig', array( $twig->display('install.config.html.twig', array(
'clients' => $clients, 'clients' => $clients,
'timezones' => DateTimeZone::listIdentifiers(), 'timezones' => DateTimeZone::listIdentifiers(),

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);
@@ -37,50 +40,40 @@ if(!$error) {
$configToSave['gzip_output'] = false; $configToSave['gzip_output'] = false;
$configToSave['cache_engine'] = 'auto'; $configToSave['cache_engine'] = 'auto';
$configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true); $configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true);
$configToSave['database_auto_migrate'] = true;
require BASE . 'install/includes/config.php';
if(!$error) { if(!$error) {
$content = '';
$saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content);
if ($saved) {
success($locale['step_database_config_saved']);
$_SESSION['saved'] = true;
require BASE . 'config.local.php';
require BASE . 'install/includes/config.php';
if (!$error) {
require BASE . 'install/includes/database.php'; require BASE . 'install/includes/database.php';
$locale['step_database_importing'] = str_replace('$DATABASE_NAME$', config('database_name'), $locale['step_database_importing']); if (isset($database_error)) { // we failed connect to the database
success($locale['step_database_importing']);
if(isset($database_error)) { // we failed connect to the database
error($database_error); error($database_error);
} }
else { else {
if(!$db->hasTable('accounts')) { if (!$db->hasTable('accounts')) {
$tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']); $tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
error($tmp); error($tmp);
$error = true; $error = true;
} }
if(!$db->hasTable('players')) { if (!$error) {
$tmp = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
error($tmp);
$error = true;
}
if(!$db->hasTable('guilds')) {
$tmp = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
error($tmp);
$error = true;
}
if(!$error) {
$twig->display('install.installer.html.twig', array( $twig->display('install.installer.html.twig', array(
'url' => 'tools/5-database.php', 'url' => 'tools/5-database.php',
'message' => $locale['loading_spinner'] 'message' => $locale['loading_spinner']
)); ));
$content = '';
$saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content);
if($saved) {
success($locale['step_database_config_saved']);
$_SESSION['saved'] = true;
} }
else { }
}
} else {
$_SESSION['config_content'] = $content; $_SESSION['config_content'] = $content;
unset($_SESSION['saved']); unset($_SESSION['saved']);
@@ -89,8 +82,6 @@ if(!$error) {
<textarea cols="70" rows="10">' . $content . '</textarea>'); <textarea cols="70" rows="10">' . $content . '</textarea>');
} }
} }
}
}
} }
?> ?>

View File

@@ -18,6 +18,7 @@ if(!$error) {
'locale' => $locale, 'locale' => $locale,
'session' => $_SESSION, 'session' => $_SESSION,
'account' => $account, 'account' => $account,
'hasTablePlayers' => $db->hasTable('players'),
'errors' => isset($errors) ? $errors : null, 'errors' => isset($errors) ? $errors : null,
'buttons' => next_buttons(true, $error ? false : true) 'buttons' => next_buttons(true, $error ? false : true)
)); ));

View File

@@ -1,32 +1,48 @@
<?php <?php
use MyAAC\Cache\Cache;
use MyAAC\Models\News;
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);
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) { if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']); warning($locale['already_installed']);
return;
} }
else {
require SYSTEM . 'init.php';
if(!$error) {
if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER)
$account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null;
else
$account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null;
$password = $_SESSION['var_password']; $cache = Cache::getInstance();
if ($cache->enabled()) {
// clear plugin_hooks to have fresh hooks
$cache->delete('plugins_hooks');
}
if(USE_ACCOUNT_SALT) require SYSTEM . 'init.php';
{ if($error) {
return;
}
if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER)
$account = $_SESSION['var_account'] ?? null;
else
$account_id = $_SESSION['var_account_id'] ?? null;
$password = $_SESSION['var_password'];
if(USE_ACCOUNT_SALT)
{
$salt = generateRandomString(10, false, true, true); $salt = generateRandomString(10, false, true, true);
$password = $salt . $password; $password = $salt . $password;
} }
$account_db = new OTS_Account(); $account_db = new OTS_Account();
if(isset($account)) if(isset($account))
$account_db->find($account); $account_db->find($account);
else else
$account_db->load($account_id); $account_db->load($account_id);
if ($db->hasTable('players')) {
$player_name = $_SESSION['var_player_name']; $player_name = $_SESSION['var_player_name'];
$player_db = new OTS_Player(); $player_db = new OTS_Player();
$player_db->find($player_name); $player_db->find($player_name);
@@ -44,16 +60,17 @@ else {
$groups = new OTS_Groups_List(); $groups = new OTS_Groups_List();
$player_used->setGroupId($groups->getHighestId()); $player_used->setGroupId($groups->getHighestId());
}
$email = $_SESSION['var_email']; $email = $_SESSION['var_email'];
if($account_db->isLoaded()) { if($account_db->isLoaded()) {
$account_db->setPassword(encrypt($password)); $account_db->setPassword(encrypt($password));
$account_db->setEMail($email); $account_db->setEMail($email);
$account_db->save(); $account_db->save();
$account_used = &$account_db; $account_used = &$account_db;
} }
else { else {
$new_account = new OTS_Account(); $new_account = new OTS_Account();
if(USE_ACCOUNT_NAME) { if(USE_ACCOUNT_NAME) {
$new_account->create($account); $new_account->create($account);
@@ -71,53 +88,74 @@ else {
$new_account->logAction('Account created.'); $new_account->logAction('Account created.');
$account_used = &$new_account; $account_used = &$new_account;
} }
if(USE_ACCOUNT_SALT) if(USE_ACCOUNT_SALT)
$account_used->setCustomField('salt', $salt); $account_used->setCustomField('salt', $salt);
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN); $account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us'); $account_used->setCustomField('country', 'us');
if($db->hasColumn('accounts', 'group_id')) $account_used->setCustomField('email_verified', 1);
if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId()); $account_used->setCustomField('group_id', $groups->getHighestId());
if($db->hasColumn('accounts', 'type')) if($db->hasColumn('accounts', 'type'))
$account_used->setCustomField('type', 6); $account_used->setCustomField('type', 6);
if(!$player_db->isLoaded()) if ($db->hasTable('players')) {
if(!$player_db->isLoaded()) {
$player->setAccountId($account_used->getId()); $player->setAccountId($account_used->getId());
else
$player_db->setAccountId($account_used->getId());
success($locale['step_database_created_account']);
setSession('account', $account_used->getId());
setSession('password', encrypt($password));
setSession('remember_me', true);
if($player_db->isLoaded()) {
$player_db->save();
}
else {
$player->save(); $player->save();
} }
else {
$player_db->setAccountId($account_used->getId());
$player_db->save();
}
}
success($locale['step_database_created_account']);
setSession('account', $account_used->getId());
setSession('password', encrypt($password));
setSession('remember_me', true);
if(!News::all()->count()) {
$player_id = 0; $player_id = 0;
$query = $db->query("SELECT `id` FROM `players` WHERE `name` = " . $db->quote($player_name) . ";");
if($query->rowCount() == 1) { if ($db->hasTable('players')) {
$query = $query->fetch(); $tmpNewsPlayer = \MyAAC\Models\Player::where('name', $player_name)->first();
$player_id = $query['id']; if($tmpNewsPlayer) {
$player_id = $tmpNewsPlayer->id;
}
} }
$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX ."news` WHERE `title` LIKE 'Hello!';"); News::create([
if($query->rowCount() == 0) { 'type' => 1,
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'); 'date' => time(),
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');")) { 'category' => 2,
'title' => 'Hello!',
'body' => 'MyAAC is just READY to use!',
'player_id' => $player_id,
'comments' => 'https://my-aac.org',
'hide' => 0,
]);
News::create([
'type' => 2,
'date' => time(),
'category' => 4,
'title' => 'Hello tickers!',
'body' => 'https://my-aac.org',
'player_id' => $player_id,
'comments' => '',
'hide' => 0,
]);
success($locale['step_database_created_news']); success($locale['step_database_created_news']);
} }
}
$settings = Settings::getInstance(); $settings = Settings::getInstance();
foreach($_SESSION as $key => $value) { foreach($_SESSION as $key => $value) {
if (in_array($key, ['var_usage', 'var_date_timezone', 'var_client'])) { if (in_array($key, ['var_usage', 'var_date_timezone', 'var_client'])) {
if ($key == 'var_usage') { if ($key == 'var_usage') {
$key = 'anonymous_usage_statistics'; $key = 'anonymous_usage_statistics';
@@ -130,15 +168,15 @@ else {
$settings->updateInDatabase('core', $key, $value); $settings->updateInDatabase('core', $key, $value);
} }
} }
success('Settings saved.'); success('Settings saved.');
$twig->display('install.installer.html.twig', array( $twig->display('install.installer.html.twig', array(
'url' => 'tools/7-finish.php', 'url' => 'tools/7-finish.php',
'message' => $locale['importing_spinner'] 'message' => $locale['importing_spinner']
)); ));
if(!isset($_SESSION['installed'])) { if(!isset($_SESSION['installed'])) {
if (!array_key_exists('CI', getenv())) { if (!array_key_exists('CI', getenv())) {
$report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL);
if (function_exists('curl_version')) if (function_exists('curl_version'))
@@ -155,15 +193,6 @@ else {
} }
$_SESSION['installed'] = true; $_SESSION['installed'] = true;
}
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') !== false)
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
}
} }
$hooks->trigger(HOOK_INSTALL_FINISH_END);

View File

@@ -1,3 +1,4 @@
<?php defined('MYAAC') or die('Direct access not allowed!'); ?>
<!DOCTYPE html> <!DOCTYPE html>
<html dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>"> <html dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>">
<head> <head>
@@ -6,7 +7,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

@@ -7,12 +7,19 @@ 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';
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
return;
}
$error = false; $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) {
@@ -30,6 +37,9 @@ if($db->hasTable(TABLE_PREFIX . 'account_actions')) {
else { else {
// import schema // import schema
try { try {
$locale['step_database_importing'] = str_replace('$DATABASE_NAME$', config('database_name'), $locale['step_database_importing']);
success($locale['step_database_importing']);
$db->query(file_get_contents(BASE . 'install/includes/schema.sql')); $db->query(file_get_contents(BASE . 'install/includes/schema.sql'));
$locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']); $locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']);
@@ -136,75 +146,86 @@ if(!$db->hasColumn('accounts', 'premium_points')) {
success($locale['step_database_adding_field'] . ' accounts.premium_points...'); success($locale['step_database_adding_field'] . ' accounts.premium_points...');
} }
if($db->hasColumn('guilds', 'checkdata')) { if ($db->hasTable('guilds')) {
if(query("ALTER TABLE `guilds` MODIFY `checkdata` INT NOT NULL DEFAULT 0;")) if ($db->hasColumn('guilds', 'checkdata')) {
if (query("ALTER TABLE `guilds` MODIFY `checkdata` INT NOT NULL DEFAULT 0;"))
success($locale['step_database_modifying_field'] . ' guilds.checkdata...'); success($locale['step_database_modifying_field'] . ' guilds.checkdata...');
} }
if(!$db->hasColumn('guilds', 'motd')) { if (!$db->hasColumn('guilds', 'motd')) {
if(query("ALTER TABLE `guilds` ADD `motd` VARCHAR(255) NOT NULL DEFAULT '';")) if (query("ALTER TABLE `guilds` ADD `motd` VARCHAR(255) NOT NULL DEFAULT '';"))
success($locale['step_database_adding_field'] . ' guilds.motd...'); success($locale['step_database_adding_field'] . ' guilds.motd...');
} } else {
else { if (query("ALTER TABLE `guilds` MODIFY `motd` VARCHAR(255) NOT NULL DEFAULT '';"))
if(query("ALTER TABLE `guilds` MODIFY `motd` VARCHAR(255) NOT NULL DEFAULT '';"))
success($locale['step_database_modifying_field'] . ' guilds.motd...'); success($locale['step_database_modifying_field'] . ' guilds.motd...');
} }
if(!$db->hasColumn('guilds', 'description')) { if (!$db->hasColumn('guilds', 'description')) {
if(query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;")) if (query("ALTER TABLE `guilds` ADD `description` VARCHAR(5000) NOT NULL DEFAULT '';"))
success($locale['step_database_adding_field'] . ' guilds.description...'); success($locale['step_database_adding_field'] . ' guilds.description...');
} }
else {
if (query("ALTER TABLE `guilds` MODIFY `description` VARCHAR(5000) NOT NULL DEFAULT '';")) {
success($locale['step_database_modifying_field'] . ' guilds.description...');
}
}
if($db->hasColumn('guilds', 'logo_gfx_name')) { if ($db->hasColumn('guilds', 'logo_gfx_name')) {
if(query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) { if (query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) {
$tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']); $tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp); $tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp);
success($tmp); success($tmp);
} }
} } else if (!$db->hasColumn('guilds', 'logo_name')) {
else if(!$db->hasColumn('guilds', 'logo_name')) { if (query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';"))
if(query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';"))
success($locale['step_database_adding_field'] . ' guilds.logo_name...'); success($locale['step_database_adding_field'] . ' guilds.logo_name...');
}
} }
if(!$db->hasColumn('players', 'created')) { if ($db->hasTable('players')) {
if(query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;")) if (!$db->hasColumn('players', 'created')) {
if (query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.created...'); success($locale['step_database_adding_field'] . ' players.created...');
} }
if(!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion')) { if (!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion')) {
if(query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;")) if (query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.deleted...'); success($locale['step_database_adding_field'] . ' players.deleted...');
} }
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', 'hide')) {
else if(!$db->hasColumn('players', 'hidden')) { if (query("ALTER TABLE `players` ADD `hide` TINYINT(1) NOT NULL DEFAULT 0;"))
if(query("ALTER TABLE `players` ADD `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) success($locale['step_database_adding_field'] . ' players.hide...');
success($locale['step_database_adding_field'] . ' players.hidden...'); }
}
if(!$db->hasColumn('players', 'comment')) { if (!$db->hasColumn('players', 'comment')) {
if(query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;")) if (query("ALTER TABLE `players` ADD `comment` VARCHAR(5000) NOT NULL DEFAULT '';"))
success($locale['step_database_adding_field'] . ' players.comment...'); success($locale['step_database_adding_field'] . ' players.comment...');
} }
else {
if (query("ALTER TABLE `players` MODIFY `comment` VARCHAR(5000) NOT NULL DEFAULT '';")) {
success($locale['step_database_modifying_field'] . ' players.comment...');
}
}
if($db->hasColumn('players', 'rank_id')) { if ($db->hasColumn('players', 'rank_id')) {
if(query("ALTER TABLE players MODIFY `rank_id` INT(11) NOT NULL DEFAULT 0;")) if (query("ALTER TABLE players MODIFY `rank_id` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_modifying_field'] . ' players.rank_id...'); success($locale['step_database_modifying_field'] . ' players.rank_id...');
if($db->hasColumn('players', 'guildnick')) { if ($db->hasColumn('players', 'guildnick')) {
if(query("ALTER TABLE players MODIFY `guildnick` VARCHAR(255) NOT NULL DEFAULT '';")) { if (query("ALTER TABLE players MODIFY `guildnick` VARCHAR(255) NOT NULL DEFAULT '';")) {
success($locale['step_database_modifying_field'] . ' players.guildnick...'); success($locale['step_database_modifying_field'] . ' players.guildnick...');
} }
} }
}
} }
if($db->hasTable('z_forum')) { if($db->hasTable('z_forum')) {

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,62 +12,77 @@ require BASE . 'install/includes/functions.php';
require BASE . 'install/includes/locale.php'; require BASE . 'install/includes/locale.php';
ini_set('max_execution_time', 300); ini_set('max_execution_time', 300);
@ob_end_flush();
ob_implicit_flush(); ob_implicit_flush();
ob_end_flush();
header('X-Accel-Buffering: no'); header('X-Accel-Buffering: no');
/*
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) { if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']); warning($locale['already_installed']);
return; return;
}*/ }
require SYSTEM . 'init.php'; require SYSTEM . 'init.php';
$deleted = 'deleted'; if ($db->hasTable('players')) {
if($db->hasColumn('players', 'deletion')) $deleted = 'deleted';
if ($db->hasColumn('players', 'deletion'))
$deleted = 'deletion'; $deleted = 'deletion';
$time = time(); $time = time();
function insert_sample_if_not_exist($p) { function insert_sample_if_not_exist($p)
{
global $db, $success, $deleted, $time; global $db, $success, $deleted, $time;
$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;
} }
}
$success = true;
insert_sample_if_not_exist(array('name' => 'Rook Sample', 'level' => 1, 'vocation_id' => 0, 'health' => 150, 'healthmax' => 150, 'experience' => 0, 'looktype' => 130, 'mana' => 0, 'manamax' => 0, 'soul' => 100, 'cap' => 400));
insert_sample_if_not_exist(array('name' => 'Sorcerer Sample', 'level' => 8, 'vocation_id' => 1, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 130, 'mana' => 90, 'manamax' => 90, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Druid Sample', 'level' => 8, 'vocation_id' => 2, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 130, 'mana' => 90, 'manamax' => 90, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Paladin Sample', 'level' => 8, 'vocation_id' => 3, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 129, 'mana' => 90, 'manamax' => 90, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Knight Sample', 'level' => 8, 'vocation_id' => 4, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 131, 'mana' => 90, 'manamax' => 90, 'soul' => 100, 'cap' => 470));
if ($success) {
success($locale['step_database_imported_players']);
}
} }
$success = true;
insert_sample_if_not_exist(array('name' => 'Rook Sample', 'level' => 1, 'vocation_id' => 0, 'health' => 150, 'healthmax' => 150, 'experience' => 0, 'looktype' => 130, 'mana' => 0, 'manamax' => 0, 'soul' => 100, 'cap' => 400));
insert_sample_if_not_exist(array('name' => 'Sorcerer Sample', 'level' => 8, 'vocation_id' => 1, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 130, 'mana' => 90, 'manamax' => 90, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Druid Sample', 'level' => 8, 'vocation_id' => 2, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 130, 'mana' => 90, 'manamax' => 90, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Paladin Sample', 'level' => 8, 'vocation_id' => 3, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 129, 'mana' => 90, 'manamax' => 90, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Knight Sample', 'level' => 8, 'vocation_id' => 4, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 131, 'mana' => 90, 'manamax' => 90, 'soul' => 100, 'cap' => 470));
if($success) {
success($locale['step_database_imported_players']);
}
require_once LIBS . 'plugins.php';
Plugins::installMenus('kathrine', require TEMPLATES . 'kathrine/menus.php');
Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php');
require LIBS . 'DataLoader.php';
DataLoader::setLocale($locale); DataLoader::setLocale($locale);
DataLoader::load(); DataLoader::load();
// add menus entries
require_once SYSTEM . 'migrations/17.php';
$up();
// update config.highscores_ids_hidden // update config.highscores_ids_hidden
require_once SYSTEM . 'migrations/20.php'; require_once SYSTEM . 'migrations/20.php';
$up();
// add z_polls tables // add z_polls tables
require_once SYSTEM . 'migrations/22.php'; require_once SYSTEM . 'migrations/22.php';
$up();
// add myaac_pages pages // add myaac_pages pages
require_once SYSTEM . 'migrations/27.php'; require_once SYSTEM . 'migrations/27.php';
$up();
require_once SYSTEM . 'migrations/30.php'; require_once SYSTEM . 'migrations/30.php';
$up();
// new monster columns
require_once SYSTEM . 'migrations/31.php';
$up();
// rules page
require_once SYSTEM . 'migrations/45.php';
$up();
use MyAAC\Models\FAQ as ModelsFAQ;
if(ModelsFAQ::count() == 0) { if(ModelsFAQ::count() == 0) {
ModelsFAQ::create([ ModelsFAQ::create([
'question' => 'What is this?', 'question' => 'What is this?',
@@ -71,6 +90,21 @@ if(ModelsFAQ::count() == 0) {
]); ]);
} }
$hooks->trigger(HOOK_INSTALL_FINISH);
$db->setClearCacheAfter(true);
// cleanup
foreach($_SESSION as $key => $value) {
if(str_contains($key, 'var_')) {
unset($_SESSION[$key]);
}
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
$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

@@ -4,6 +4,7 @@ use MyAAC\Models\BoostedCreature;
use MyAAC\Models\PlayerOnline; use MyAAC\Models\PlayerOnline;
use MyAAC\Models\Account; use MyAAC\Models\Account;
use MyAAC\Models\Player; use MyAAC\Models\Player;
use MyAAC\RateLimit;
require_once 'common.php'; require_once 'common.php';
require_once SYSTEM . 'functions.php'; require_once SYSTEM . 'functions.php';
@@ -85,12 +86,25 @@ switch ($action) {
die(json_encode(['eventlist' => $eventlist, 'lastupdatetimestamp' => time()])); die(json_encode(['eventlist' => $eventlist, 'lastupdatetimestamp' => time()]));
case 'boostedcreature': case 'boostedcreature':
$boostedCreature = BoostedCreature::latest(); $clientVersion = (int)setting('core.client');
// 13.40 and up
if ($clientVersion >= 1340) {
$creatureBoost = $db->query("SELECT * FROM " . $db->tableName('boosted_creature'))->fetchAll();
$bossBoost = $db->query("SELECT * FROM " . $db->tableName('boosted_boss'))->fetchAll();
die(json_encode([
'boostedcreature' => true,
'creatureraceid' => intval($creatureBoost[0]['raceid']),
'bossraceid' => intval($bossBoost[0]['raceid'])
]));
}
// lower clients
$boostedCreature = BoostedCreature::first();
die(json_encode([ die(json_encode([
'boostedcreature' => true, 'boostedcreature' => true,
'raceid' => $boostedCreature->raceid 'raceid' => $boostedCreature->raceid
])); ]));
break;
case 'login': case 'login':
@@ -130,12 +144,29 @@ switch ($action) {
} }
$account = $account->first(); $account = $account->first();
$ip = get_browser_real_ip();
$limiter = new RateLimit('failed_logins', setting('core.account_login_attempts_limit'), setting('core.account_login_ban_time'));
$limiter->enabled = setting('core.account_login_ipban_protection');
$limiter->load();
$ban_msg = 'A wrong account, password or secret has been entered ' . setting('core.account_login_attempts_limit') . ' times in a row. You are unable to log into your account for the next ' . setting('core.account_login_ban_time') . ' minutes. Please wait.';
if (!$account) { if (!$account) {
$limiter->increment($ip);
if ($limiter->exceeded($ip)) {
sendError($ban_msg);
}
sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.'); sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.');
} }
$current_password = encrypt((USE_ACCOUNT_SALT ? $account->salt : '') . $request->password); $current_password = encrypt((USE_ACCOUNT_SALT ? $account->salt : '') . $request->password);
if (!$account || $account->password != $current_password) { if (!$account || $account->password != $current_password) {
$limiter->increment($ip);
if ($limiter->exceeded($ip)) {
sendError($ban_msg);
}
sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.'); sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.');
} }
@@ -145,16 +176,30 @@ switch ($action) {
if ($accountSecret != null && $accountSecret != '') { if ($accountSecret != null && $accountSecret != '') {
$accountHasSecret = true; $accountHasSecret = true;
if ($inputToken === false) { if ($inputToken === false) {
$limiter->increment($ip);
if ($limiter->exceeded($ip)) {
sendError($ban_msg);
}
sendError('Submit a valid two-factor authentication token.', 6); sendError('Submit a valid two-factor authentication token.', 6);
} else { } else {
require_once LIBS . 'rfc6238.php'; require_once LIBS . 'rfc6238.php';
if (TokenAuth6238::verify($accountSecret, $inputToken) !== true) { if (TokenAuth6238::verify($accountSecret, $inputToken) !== true) {
$limiter->increment($ip);
if ($limiter->exceeded($ip)) {
sendError($ban_msg);
}
sendError('Two-factor authentication failed, token is wrong.', 6); sendError('Two-factor authentication failed, token is wrong.', 6);
} }
} }
} }
} }
$limiter->reset($ip);
if (setting('core.account_mail_verify') && $account->email_verified !== 1) {
sendError('You need to verify your account, enter in our site and resend verify e-mail!');
}
// common columns // common columns
$columns = 'id, name, level, sex, vocation, looktype, lookhead, lookbody, looklegs, lookfeet, lookaddons'; $columns = 'id, name, level, sex, vocation, looktype, lookhead, lookbody, looklegs, lookfeet, lookaddons';

View File

@@ -1,6 +1,6 @@
server { server {
listen 80; listen 80;
root /home/otserv/www/public; root /var/www/html;
index index.php; index index.php;
server_name your-domain.com; server_name your-domain.com;
@@ -10,22 +10,21 @@ server {
# this is very important, be sure its in your nginx conf - it prevents access to logs etc. # this is very important, be sure its in your nginx conf - it prevents access to logs etc.
location ~ /system { location ~ /system {
deny all; deny all;
return 404;
} }
# block .htaccess # block .htaccess, CHANGELOG.md, composer.json etc.
location ~ /\.ht { # this is to prevent finding software versions
location ~\.(ht|md|json|dist|sql)$ {
deny all; deny all;
} }
# block git files and folders # block git files and folders
location ~ /\.git { location ~ /\.git {
return 404;
deny all; deny all;
} }
location / { location / {
try_files $uri $uri/ /index.php; 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 });

1041
package-lock.json generated

File diff suppressed because it is too large Load Diff

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": "^14.3.3"
},
"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": "^7.2.0"
} }
} }

13
phpstan-bootstrap.php Normal file
View File

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

39
phpstan.neon Normal file
View File

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

View File

@@ -1,6 +1,6 @@
{ {
"name": "create-account-hint", "name": "create-account-hint",
"description": "This plugin display text 'To play on Forgotten you need an account. All you have to do to create your new account is to enter an account name, password, country and your email address. Also you have to agree to the terms presented below. If you have done so, your account name will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.' on the create account page. <strong>Be careful when uninstalling this!</strong>", "description": "This plugin display text 'To play on Forgotten you need an account. All you have to do to create your new account is to enter an account name, password, country and your email address. Also you have to agree to the terms presented below. If you have done so, your account name will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.' on the create account page.",
"version": "1.0", "version": "1.0",
"author": "slawkens", "author": "slawkens",
"contact": "slawkens@gmail.com", "contact": "slawkens@gmail.com",

View File

@@ -9,7 +9,4 @@
*/ */
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
global $twig_loader; $twig->display('account-create-hint/hint.html.twig');
$twig_loader->prependPath(BASE . 'plugins/account-create-hint');
$twig->display('hint.html.twig');

View File

@@ -1,8 +1,6 @@
<?php <?php
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
$reward = setting('core.account_mail_confirmed_reward');
$hasCoinsColumn = $db->hasColumn('accounts', 'coins'); $hasCoinsColumn = $db->hasColumn('accounts', 'coins');
$rewardCoins = setting('core.account_mail_confirmed_reward_coins'); $rewardCoins = setting('core.account_mail_confirmed_reward_coins');
if ($rewardCoins > 0 && !$hasCoinsColumn) { if ($rewardCoins > 0 && !$hasCoinsColumn) {

View File

@@ -25,7 +25,8 @@
"hooks": { "hooks": {
"Example Hook": { "Example Hook": {
"type": "BEFORE_PAGE", "type": "BEFORE_PAGE",
"file": "plugins/example/before.php" "file": "plugins/example/before.php",
"priority": 1000
} }
}, },
"routes": { "routes": {
@@ -33,12 +34,25 @@
"pattern": "/YourAwesomePage/{name:string}/{page:int}", "pattern": "/YourAwesomePage/{name:string}/{page:int}",
"file": "plugins/your-plugin/your-awesome-page.php", "file": "plugins/your-plugin/your-awesome-page.php",
"method": "GET", "method": "GET",
"priority": "130" "priority": 130
}, },
"Redirect Example": { "Redirect Example": {
"redirect_from": "/redirectExample", "redirect_from": "/redirectExample",
"redirect_to": "account/manage" "redirect_to": "account/manage"
} }
}, },
"settings": "plugins/your-plugin-folder/settings.php" "routes-default-priority": 1000,
"pages-default-priority": 1000,
"settings": "plugins/your-plugin-folder/settings.php",
"autoload": {
"pages": true,
"pages-sub-folders": false,
"commands": true,
"themes": true,
"admin-pages": true,
"admin-pages-sub-folders": true,
"settings": true,
"install": true,
"init": false
}
} }

View File

@@ -22,7 +22,7 @@ if [ $1 = "prepare" ]; then
mkdir -p tmp mkdir -p tmp
# get myaac from git archive # get myaac from git archive
git archive --format zip --output tmp/myaac.zip develop git archive --format zip --output tmp/myaac.zip main
cd tmp/ || exit cd tmp/ || exit
@@ -38,7 +38,11 @@ if [ $1 = "prepare" ]; then
cd $dir || exit cd $dir || exit
# dependencies # dependencies
composer install --no-dev composer install --no-dev --prefer-dist --optimize-autoloader
npm install
# node_modules is useless, we already have copy in tools/ext
rm -R node_modules
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

21
system/base.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
$baseDir = '';
$tmp = explode('/', $_SERVER['SCRIPT_NAME']);
$size = count($tmp) - 1;
for($i = 1; $i < $size; $i++)
$baseDir .= '/' . $tmp[$i];
$baseDir = str_replace(['/' . ADMIN_PANEL_FOLDER, '/install', '/tools'], '', $baseDir);
if(!IS_CLI) {
if (isset($_SERVER['HTTP_HOST'][0])) {
$baseHost = $_SERVER['HTTP_HOST'];
} else {
if (isset($_SERVER['SERVER_NAME'][0])) {
$baseHost = $_SERVER['SERVER_NAME'];
} else {
$baseHost = $_SERVER['SERVER_ADDR'];
}
}
}

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

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

@@ -105,4 +105,16 @@ $config['clients'] = [
1316, 1316,
1320, 1320,
1321, 1321,
1322,
1330,
1332,
1340,
1400,
1405,
1410,
1411,
1412,
1500,
1501,
]; ];

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,3 @@ function fieldExist($field, $table)
global $db; global $db;
return $db->hasColumn($table, $field); return $db->hasColumn($table, $field);
} }
?>

View File

@@ -36,3 +36,5 @@ class Guild extends OTS_Guild {
} }
class GuildRank extends OTS_GuildRank {} class GuildRank extends OTS_GuildRank {}
class House extends OTS_House {} class House extends OTS_House {}
class Cache extends \MyAAC\Cache\Cache {}

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

@@ -106,6 +106,7 @@ try {
'persistent' => @$config['database_persistent'] 'persistent' => @$config['database_persistent']
)); ));
global $db;
$db = POT::getInstance()->getDBHandle(); $db = POT::getInstance()->getDBHandle();
$capsule = new Capsule; $capsule = new Capsule;
$capsule->addConnection([ $capsule->addConnection([
@@ -121,12 +122,17 @@ try {
$eloquentConnection = $capsule->getConnection(); $eloquentConnection = $capsule->getConnection();
if (isset($twig)) {
$twig->addGlobal('db', $db);
}
} catch (Exception $e) { } catch (Exception $e) {
if(isset($cache) && $cache->enabled()) { if(isset($cache) && $cache->enabled()) {
$cache->delete('config_lua'); $cache->delete('config_lua');
} }
if(defined('MYAAC_INSTALL')) { if(defined('MYAAC_INSTALL')) {
$error = $e->getMessage();
return; // installer will take care of this return; // installer will take care of this
} }

View File

@@ -8,21 +8,21 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
if (class_exists(\Whoops\Run::class)) { use MyAAC\Exceptions\SensitiveException;
$whoops = new \Whoops\Run; use Whoops\Handler\PlainTextHandler;
if(IS_CLI) { use Whoops\Handler\PrettyPageHandler;
$whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); use Whoops\Run;
}
else {
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
}
if (class_exists(Run::class)) {
$whoops = new Run;
$whoopsHandler = IS_CLI ? (new PlainTextHandler()) : (new PrettyPageHandler());
$whoops->pushHandler($whoopsHandler);
$whoops->register(); $whoops->register();
return; return;
} }
require LIBS . 'SensitiveException.php';
/** /**
* @param Exception $exception * @param Exception $exception
*/ */

View File

@@ -9,12 +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\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;
@@ -44,7 +49,7 @@ function warning($message, $return = false) {
return message($message, 'warning', $return); return message($message, 'warning', $return);
} }
function note($message, $return = false) { function note($message, $return = false) {
return info($message, $return); return message($message, 'note', $return);
} }
function info($message, $return = false) { function info($message, $return = false) {
return message($message, 'info', $return); return message($message, 'info', $return);
@@ -82,25 +87,41 @@ function getForumBoardLink($board_id, $page = NULL): string {
return BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'forum/board/' . (int)$board_id . (isset($page) ? '/' . $page : ''); return BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'forum/board/' . (int)$board_id . (isset($page) ? '/' . $page : '');
} }
function getPlayerLink($name, $generate = true): string function getPlayerLink($name, $generate = true, bool $colored = false): string
{ {
if(is_numeric($name)) if (is_object($name) and $name instanceof OTS_Player) {
{ $player = $name;
}
else {
$player = new OTS_Player(); $player = new OTS_Player();
if(is_numeric($name)) {
$player->load((int)$name); $player->load((int)$name);
if($player->isLoaded()) }
$name = $player->getName(); else {
$player->find($name);
}
} }
if (!$player->isLoaded()) {
return '(error)';
}
$name = $player->getName();
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'characters/' . urlencode($name); $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'characters/' . urlencode($name);
if ($colored) {
$name = '<span style="color: ' . ($player->isOnline() ? 'green' : 'red') . ';">' . $name . '</span>';
}
if(!$generate) return $url; if(!$generate) return $url;
return generateLink($url, $name); return generateLink($url, $name);
} }
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?name=' . urlencode($name);
if(!$generate) return $url; if(!$generate) return $url;
return generateLink($url, $name); return generateLink($url, $name);
@@ -108,16 +129,14 @@ function getMonsterLink($name, $generate = true): string
function getHouseLink($name, $generate = true): string function getHouseLink($name, $generate = true): string
{ {
if(is_numeric($name)) if(is_numeric($name)) {
{
$house = House::find(intval($name), ['name']); $house = House::find(intval($name), ['name']);
if ($house) { if ($house) {
$name = $house->name; $name = $house->name;
} }
} }
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses?name=' . urlencode($name);
$url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses/' . urlencode($name);
if(!$generate) return $url; if(!$generate) return $url;
return generateLink($url, $name); return generateLink($url, $name);
@@ -137,7 +156,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'] : '';
} }
@@ -197,7 +215,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;
@@ -206,6 +224,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';
} }
@@ -253,7 +275,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();
@@ -410,7 +432,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`;');
@@ -520,33 +545,39 @@ function template_header($is_admin = false): string
*/ */
function template_footer(): string function template_footer(): string
{ {
global $views_counter; $footer = [];
$ret = '';
if(admin()) { if(admin()) {
$ret .= generateLink(ADMIN_URL, 'Admin Panel', true); $footer[] = generateLink(ADMIN_URL, 'Admin Panel', true);
} }
if(setting('core.visitors_counter')) { if(setting('core.visitors_counter')) {
global $visitors; global $visitors;
$amount = $visitors->getAmountVisitors(); $amount = $visitors->getAmountVisitors();
$ret .= '<br/>Currently there ' . ($amount > 1 ? 'are' : 'is') . ' ' . $amount . ' visitor' . ($amount > 1 ? 's' : '') . '.'; $footer[] = 'Currently there ' . ($amount > 1 ? 'are' : 'is') . ' ' . $amount . ' visitor' . ($amount > 1 ? 's' : '') . '.';
} }
if(setting('core.views_counter')) { if(setting('core.views_counter')) {
$ret .= '<br/>Page has been viewed ' . $views_counter . ' times.'; global $views_counter;
$footer[] = 'Page has been viewed ' . $views_counter . ' times.';
} }
if(setting('core.footer_load_time')) { if(setting('core.footer_load_time')) {
$ret .= '<br/>Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.'; $footer[] = 'Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.';
} }
$settingFooter = setting('core.footer'); $settingFooter = setting('core.footer');
if(isset($settingFooter[0])) { if(isset($settingFooter[0])) {
$ret .= '<br/>' . $settingFooter; $footer[] = '' . $settingFooter;
} }
// please respect my work and help spreading the word, thanks! // please respect my work and help spreading the word, thanks!
return $ret . '<br/>' . base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); $footer[] = base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=');
global $hooks;
$hooks->triggerFilter(HOOK_FILTER_THEME_FOOTER, $footer);
return implode('<br/>', $footer);
} }
function template_ga_code() function template_ga_code()
@@ -562,24 +593,12 @@ function template_form()
{ {
global $template_name; global $template_name;
$cache = Cache::getInstance(); $templates = Cache::remember('templates', 5 * 60, function() {
if($cache->enabled()) return get_templates();
{ });
$tmp = '';
if($cache->fetch('templates', $tmp)) {
$templates = unserialize($tmp);
}
else
{
$templates = get_templates();
$cache->set('templates', serialize($templates), 30);
}
}
else
$templates = get_templates();
$options = ''; $options = '';
foreach($templates as $key => $value) foreach($templates as $value)
$options .= '<option ' . ($template_name == $value ? 'SELECTED' : '') . '>' . $value . '</option>'; $options .= '<option ' . ($template_name == $value ? 'SELECTED' : '') . '>' . $value . '</option>';
global $twig; global $twig;
@@ -702,11 +721,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);
} }
@@ -779,7 +795,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;
} }
@@ -798,6 +814,10 @@ function get_templates()
$ret[] = $file; $ret[] = $file;
} }
foreach (Plugins::getThemes() as $name => $path) {
$ret[] = $name;
}
return $ret; return $ret;
} }
@@ -968,31 +988,29 @@ function load_config_lua($filename)
continue; continue;
} }
$tmp_exp = explode('=', $line, 2); $tmp_exp = explode('=', $line, 2);
if(strpos($line, 'dofile') !== false) if(str_contains($line, 'dofile')) {
{
$delimiter = '"'; $delimiter = '"';
if(strpos($line, $delimiter) === false) if(!str_contains($line, $delimiter)) {
$delimiter = "'"; $delimiter = "'";
}
$tmp = explode($delimiter, $line); $tmp = explode($delimiter, $line);
$result = array_merge($result, load_config_lua($config['server_path'] . $tmp[1])); $result = array_merge($result, load_config_lua($config['server_path'] . $tmp[1]));
} }
else if(count($tmp_exp) >= 2) else if(count($tmp_exp) >= 2) {
{
$key = trim($tmp_exp[0]); $key = trim($tmp_exp[0]);
if(0 !== strpos($key, '--')) if(!str_starts_with($key, '--')) {
{
$value = trim($tmp_exp[1]); $value = trim($tmp_exp[1]);
if(strpos($value, '--') !== false) {// found some deep comment if(str_contains($value, '--')) {// found some deep comment
$value = preg_replace('/--.*$/i', '', $value); $value = preg_replace('/--.*$/i', '', $value);
} }
if(is_numeric($value)) if(is_numeric($value))
$result[$key] = (float) $value; $result[$key] = (float) $value;
elseif(in_array(@$value[0], array("'", '"')) && in_array(@$value[strlen($value) - 1], array("'", '"'))) elseif(in_array(@$value[0], array("'", '"')) && in_array(@$value[strlen($value) - 1], array("'", '"')))
$result[$key] = (string) substr(substr($value, 1), 0, -1); $result[$key] = substr(substr($value, 1), 0, -1);
elseif(in_array($value, array('true', 'false'))) elseif(in_array($value, array('true', 'false')))
$result[$key] = ($value === 'true') ? true : false; $result[$key] = $value === 'true';
elseif(@$value[0] === '{') { elseif(@$value[0] === '{') {
// arrays are not supported yet // arrays are not supported yet
// just ignore the error // just ignore the error
@@ -1000,12 +1018,19 @@ function load_config_lua($filename)
} }
else else
{ {
foreach($result as $tmp_key => $tmp_value) // load values definied by other keys, like: dailyFragsToBlackSkull = dailyFragsToRedSkull foreach($result as $tmp_key => $tmp_value) { // load values defined by other keys, like: dailyFragsToBlackSkull = dailyFragsToRedSkull
$value = str_replace($tmp_key, $tmp_value, $value); $value = str_replace($tmp_key, $tmp_value, $value);
$ret = @eval("return $value;"); }
if((string) $ret == '' && trim($value) !== '""') // = parser error
{ try {
throw new RuntimeException('ERROR: Loading config.lua file. Line <b>' . ($ln + 1) . '</b> of LUA config file is not valid [key: <b>' . $key . '</b>]'); $ret = eval("return $value;");
}
catch (Throwable $e) {
throw new RuntimeException('ERROR: Loading config.lua file. Line: ' . ($ln + 1) . ' - Unable to parse value "' . $value . '" - ' . $e->getMessage());
}
if((string) $ret == '' && trim($value) !== '""') {
throw new RuntimeException('ERROR: Loading config.lua file. Line ' . ($ln + 1) . ' is not valid [key: ' . $key . ']');
} }
$result[$key] = $ret; $result[$key] = $ret;
} }
@@ -1014,11 +1039,10 @@ function load_config_lua($filename)
} }
} }
$result = array_merge($result, isset($config['lua']) ? $config['lua'] : array()); return array_merge($result, $config['lua'] ?? []);
return $result;
} }
function str_replace_first($search, $replace, $subject) { function str_replace_first($search,$replace, $subject) {
$pos = strpos($subject, $search); $pos = strpos($subject, $search);
if ($pos !== false) { if ($pos !== false) {
return substr_replace($subject, $replace, $pos, strlen($search)); return substr_replace($subject, $replace, $pos, strlen($search));
@@ -1041,19 +1065,38 @@ function get_browser_real_ip() {
return '0'; return '0';
} }
function setSession($key, $data) { function setSession($key, $value = null): void {
$_SESSION[setting('core.session_prefix') . $key] = $data; if (!is_array($key)) {
$key = [$key => $value];
}
foreach ($key as $arrayKey => $arrayValue) {
if (is_null($arrayValue)) {
unsetSession($arrayKey);
}
else {
$_SESSION[setting('core.session_prefix') . $arrayKey] = $arrayValue;
}
}
} }
function getSession($key) { function getSession($key) {
$key = setting('core.session_prefix') . $key; return $_SESSION[setting('core.session_prefix') . $key] ?? null;
return isset($_SESSION[$key]) ? $_SESSION[$key] : false;
} }
function unsetSession($key) { function unsetSession($key): void {
unset($_SESSION[setting('core.session_prefix') . $key]); unset($_SESSION[setting('core.session_prefix') . $key]);
} }
function csrf(): void { function session($key): mixed {
CsrfToken::create(); if (is_array($key)) {
setSession($key);
return null;
}
return getSession($key);
}
function csrf(bool $return = false): string {
return CsrfToken::create($return);
} }
function csrfToken(): string { function csrfToken(): string {
@@ -1062,7 +1105,7 @@ function csrfToken(): string {
function isValidToken(): bool { function isValidToken(): bool {
$token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null; $token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null;
return ($_SERVER['REQUEST_METHOD'] !== 'POST' || (isset($token) && CsrfToken::isValid($token))); return (!isRequestMethod('post') || (isset($token) && CsrfToken::isValid($token)));
} }
function csrfProtect(): void function csrfProtect(): void
@@ -1074,20 +1117,16 @@ function csrfProtect(): void
} }
} }
function getTopPlayers($limit = 5) { function getTopPlayers($limit = 5, $skill = 'level') {
global $db; global $db;
$cache = Cache::getInstance(); if ($skill === 'level') {
if($cache->enabled()) { $skill = 'experience';
$tmp = '';
if($cache->fetch('top_' . $limit . '_level', $tmp)) {
$players = unserialize($tmp);
}
} }
if (!isset($players)) { return Cache::remember("top_{$limit}_{$skill}", 2 * 60, function () use ($db, $limit, $skill) {
$columns = [ $columns = [
'id', 'name', 'level', 'vocation', 'experience', 'id', 'name', 'level', 'vocation', 'experience', 'balance',
'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet' 'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet'
]; ];
@@ -1095,36 +1134,27 @@ function getTopPlayers($limit = 5) {
$columns[] = 'lookaddons'; $columns[] = 'lookaddons';
} }
if ($db->hasColumn('players', 'online')) { return Player::query()
$columns[] = 'online';
}
$players = Player::query()
->select($columns) ->select($columns)
->withOnlineStatus() ->withOnlineStatus()
->notDeleted() ->notDeleted()
->where('group_id', '<', setting('core.highscores_groups_hidden')) ->where('group_id', '<', setting('core.highscores_groups_hidden'))
->whereNotIn('id', setting('core.highscores_ids_hidden')) ->whereNotIn('id', setting('core.highscores_ids_hidden'))
->where('account_id', '!=', 1) ->where('account_id', '!=', 1)
->orderByDesc('experience') ->orderByDesc($skill)
->limit($limit) ->limit($limit)
->get() ->get()
->map(function ($e, $i) { ->map(function ($e, $i) {
$row = $e->toArray(); $row = $e->toArray();
$row['online'] = $e->online_status; $row['online'] = $e->online_status;
$row['rank'] = $i + 1; $row['rank'] = $i + 1;
$row['outfit_url'] = $e->outfit_url;
unset($row['online_table']); unset($row['online_table']);
return $row; return $row;
})->toArray(); })->toArray();
});
if($cache->enabled()) {
$cache->set('top_' . $limit . '_level', serialize($players), 120);
}
}
return $players;
} }
function deleteDirectory($dir, $ignore = array(), $contentOnly = false) { function deleteDirectory($dir, $ignore = array(), $contentOnly = false) {
@@ -1191,72 +1221,52 @@ 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',
if ($cache->fetch('status', $tmp)) 'config_lua',
$cache->delete('status'); 'towns', 'groups', 'vocations',
'visitors', 'views_counter', 'failed_logins',
if ($cache->fetch('templates', $tmp)) 'template_menus',
$cache->delete('templates'); 'last_kills',
'hooks', 'plugins_hooks', 'plugins_routes', 'plugins_settings', 'plugins_themes', 'plugins_commands',
if ($cache->fetch('config_lua', $tmp)) 'settings',
$cache->delete('config_lua'); ];
if ($cache->fetch('vocations', $tmp))
$cache->delete('vocations');
if ($cache->fetch('towns', $tmp))
$cache->delete('towns');
if ($cache->fetch('groups', $tmp))
$cache->delete('groups');
if ($cache->fetch('visitors', $tmp))
$cache->delete('visitors');
if ($cache->fetch('views_counter', $tmp))
$cache->delete('views_counter');
if ($cache->fetch('failed_logins', $tmp))
$cache->delete('failed_logins');
foreach (get_templates() as $template) { foreach (get_templates() as $template) {
if ($cache->fetch('template_ini_' . $template, $tmp)) { $keysToClear[] = 'template_ini_' . $template;
$cache->delete('template_ini_' . $template); }
// highscores cache
$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('template_menus', $tmp)) { foreach ($keysToClear as $item) {
$cache->delete('template_menus'); $tmp = '';
if ($cache->fetch($item, $tmp)) {
$cache->delete($item);
} }
if ($cache->fetch('database_tables', $tmp)) {
$cache->delete('database_tables');
}
if ($cache->fetch('database_columns', $tmp)) {
$cache->delete('database_columns');
}
if ($cache->fetch('database_checksum', $tmp)) {
$cache->delete('database_checksum');
}
if ($cache->fetch('last_kills', $tmp)) {
$cache->delete('last_kills');
} }
if ($cache->fetch('hooks', $tmp)) { global $db;
$cache->delete('hooks'); $db->setClearCacheAfter(true);
}
if ($cache->fetch('plugins_hooks', $tmp)) {
$cache->delete('plugins_hooks');
}
if ($cache->fetch('plugins_routes', $tmp)) {
$cache->delete('plugins_routes');
} }
if (function_exists('apcu_clear_cache')) {
apcu_clear_cache();
} }
deleteDirectory(CACHE . 'signatures', ['index.html'], true); deleteDirectory(CACHE . 'signatures', ['index.html'], true);
@@ -1265,12 +1275,20 @@ function clearCache()
deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html', 'persistent'], 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)
@@ -1312,13 +1330,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;
@@ -1328,11 +1339,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();
@@ -1576,21 +1582,6 @@ function right($str, $length) {
return substr($str, -$length); return substr($str, -$length);
} }
function getCreatureImgPath($creature){
$creature_path = setting('core.monsters_images_url');
$creature_gfx_name = trim(strtolower($creature)) . setting('core.monsters_images_extension');
if (!file_exists($creature_path . $creature_gfx_name)) {
$creature_gfx_name = str_replace(" ", "", $creature_gfx_name);
if (file_exists($creature_path . $creature_gfx_name)) {
return $creature_path . $creature_gfx_name;
} else {
return $creature_path . 'nophoto.png';
}
} else {
return $creature_path . $creature_gfx_name;
}
}
function between($x, $lim1, $lim2) { function between($x, $lim1, $lim2) {
if ($lim1 < $lim2) { if ($lim1 < $lim2) {
$lower = $lim1; $upper = $lim2; $lower = $lim1; $upper = $lim2;
@@ -1638,7 +1629,7 @@ function removeIfFirstSlash(&$text) {
}; };
function escapeHtml($html) { function escapeHtml($html) {
return htmlentities($html, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); return htmlspecialchars($html);
} }
function getGuildNameById($id) function getGuildNameById($id)
@@ -1675,9 +1666,31 @@ 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);
}
function getAccountIdentityColumn(): string
{
if (USE_ACCOUNT_NAME) {
return 'name';
}
elseif (USE_ACCOUNT_NUMBER) {
return 'number';
}
return 'id';
}
// 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
require SYSTEM . 'functions_custom.php'; $customFunctions = SYSTEM . 'functions_custom.php';
if (is_file($customFunctions)) {
require $customFunctions;
}

View File

@@ -8,16 +8,21 @@
* @link https://my-aac.org * @link https://my-aac.org
*/ */
use DebugBar\StandardDebugBar;
use MyAAC\Cache\Cache;
use MyAAC\CsrfToken; use MyAAC\CsrfToken;
use MyAAC\Hooks;
use MyAAC\Plugins;
use MyAAC\Models\Town;
use MyAAC\Settings;
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
global $config;
if(!isset($config['installed']) || !$config['installed']) { if(!isset($config['installed']) || !$config['installed']) {
throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.'); throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.');
} }
use DebugBar\StandardDebugBar;
if(config('env') === 'dev') { if(config('env') === 'dev') {
require SYSTEM . 'exception.php'; require SYSTEM . 'exception.php';
} }
@@ -35,17 +40,23 @@ if($config['server_path'][strlen($config['server_path']) - 1] !== '/')
$config['server_path'] .= '/'; $config['server_path'] .= '/';
// enable gzip compression if supported by the browser // enable gzip compression if supported by the browser
if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && function_exists('ob_gzhandler')) if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && str_contains($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('ob_gzhandler'))
ob_start('ob_gzhandler'); ob_start('ob_gzhandler');
// cache // cache
require_once SYSTEM . 'libs/cache.php'; global $cache;
$cache = Cache::getInstance(); $cache = Cache::getInstance();
// load plugins init.php
foreach (Plugins::getInits() as $init) {
require $init;
}
// event system // event system
require_once SYSTEM . 'hooks.php'; global $hooks;
$hooks = new Hooks(); $hooks = new Hooks();
$hooks->load(); $hooks->load();
$hooks->trigger(HOOK_INIT);
// twig // twig
require_once SYSTEM . 'twig.php'; require_once SYSTEM . 'twig.php';
@@ -54,28 +65,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) {
{
foreach($_POST as $var => $value) {
if(is_string($value)) { if(is_string($value)) {
$_POST[$var] = trim($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
@@ -96,8 +103,8 @@ if($config_lua_reload) {
// cache config // cache config
if($cache->enabled()) { if($cache->enabled()) {
$cache->set('config_lua', serialize($config['lua']), 120); $cache->set('config_lua', serialize($config['lua']), 2 * 60);
$cache->set('server_path', $config['server_path']); $cache->set('server_path', $config['server_path'], 10 * 60);
} }
} }
unset($tmp); unset($tmp);
@@ -131,18 +138,27 @@ 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';
$twig->addGlobal('logged', false);
$twig->addGlobal('account_logged', new \OTS_Account());
// 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 ' . (IS_CLI ? 'http://your-ip.com/' : BASE_URL) . 'install');
}
// execute migrations // execute migrations
require SYSTEM . 'migrate.php'; $configDatabaseAutoMigrate = config('database_auto_migrate');
if (!isset($configDatabaseAutoMigrate) || $configDatabaseAutoMigrate) {
require SYSTEM . 'migrate.php';
}
// settings // settings
require_once LIBS . 'Settings.php';
$settings = Settings::getInstance(); $settings = Settings::getInstance();
$settings->load(); $settings->load();
@@ -155,12 +171,15 @@ if (!isset($token) || !$token) {
// deprecated config values // deprecated config values
require_once SYSTEM . 'compat/config.php'; require_once SYSTEM . 'compat/config.php';
// deprecated classes
require_once SYSTEM . 'compat/classes.php';
date_default_timezone_set(setting('core.date_timezone')); date_default_timezone_set(setting('core.date_timezone'));
setting( setting(
[ [
'core.account_create_character_create', 'core.account_mail_verify',
setting('core.account_create_character_create') && (!setting('core.mail_enabled') || !setting('core.account_mail_verify')) setting('core.account_mail_verify') && setting('core.mail_enabled')
] ]
); );
@@ -173,5 +192,17 @@ 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 = Cache::remember('towns', 10 * 60, function () use ($db) {
Towns::load(); if ($db->hasTable('towns') && Town::count() > 0) {
return Town::orderBy('id', 'ASC')->pluck('name', 'id')->toArray();
}
return [];
});
if (count($towns) <= 0) {
$towns = setting('core.towns');
}
config(['towns', $towns]);
unset($towns);

View File

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

View File

@@ -1,131 +0,0 @@
<?php
/**
* Project: MyAAC
* Automatic Account Creator for Open Tibia Servers
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
use MyAAC\Models\Town;
/**
* Class Towns
*/
class Towns
{
/**
* @var string
*/
private static $filename = CACHE . 'persistent/' . 'towns.php';
/**
* Determine towns
*
* @return array
*/
public static function determine()
{
global $db;
if($db->hasTable('towns')) {
return self::getFromDatabase();
}
return self::getFromOTBM();
}
/**
* Load cached towns file
*/
public static function load()
{
$towns = config('towns');
if (file_exists(self::$filename)) {
$towns = require self::$filename;
}
config(['towns', $towns]);
}
/**
* Save into cache file
*
* @return bool
*/
public static function save()
{
$towns = self::determine();
if (count($towns) > 0) {
file_put_contents(self::$filename, '<?php return ' . var_export($towns, true) . ';', LOCK_EX);
return true;
}
return false;
}
/**
* Load from OTBM map file
*
* @return array
*/
public static function getFromOTBM()
{
$mapName = configLua('mapName');
if (!isset($mapName)) {
$mapName = configLua('map');
$mapFile = config('server_path') . $mapName;
}
if (strpos($mapName, '.otbm') === false) {
$mapName .= '.otbm';
}
if (!isset($mapFile)) {
$mapFile = config('data_path') . 'world/' . $mapName;
}
if (strpos($mapFile, '.gz') !== false) {
$mapFile = str_replace('.gz', '', $mapFile);
}
$towns = [];
if (file_exists($mapFile)) {
ini_set('memory_limit', '-1');
require LIBS . 'TownsReader.php';
$townsReader = new TownsReader($mapFile);
$townsReader->load();
$towns = $townsReader->get();
}
return $towns;
}
/**
* Load from database
*
* @return array
*/
public static function getFromDatabase()
{
return Town::pluck('name', 'id')->toArray();
}
}

View File

@@ -1,82 +0,0 @@
<?php
/*
This file is part of OTSCMS (http://www.otscms.com/) project.
Copyright (C) 2005 - 2007 Wrzasq (wrzasq@gmail.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
This code bases on oryginal OTServ code for .otbm files - file iomapotbm.cpp rev.2141
*/
class TownsReader
{
// node bytes
const ESCAPE_CHAR = 0xFD;
const NODE_START = 0xFE;
// map node types
const OTBM_TOWN = 13;
// file handler
protected $file;
// towns
private $towns = [];
// loads map .otbm file
public function __construct($file)
{
// opens file for reading
$this->file = fopen($file, 'rb');
}
public function load()
{
// checks if file is opened correctly
if ($this->file) {
// skips version
fseek($this->file, 4);
// reads nodes chain
while (!feof($this->file)) {
// reads byte
switch (ord(fgetc($this->file))) {
// maybe a town node
case self::NODE_START:
// reads node type
if (ord(fgetc($this->file)) == self::OTBM_TOWN) {
$id = unpack('L', fread($this->file, 4));
$length = unpack('S', fread($this->file, 2));
// reads town name
$this->towns[$id[1]] = fread($this->file, $length[1]);
}
break;
// escape next character - it might be NODE_START character which is in fact not
case self::ESCAPE_CHAR:
fgetc($this->file);
break;
}
}
}
}
public function get() {
return $this->towns;
}
}

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

@@ -415,9 +415,11 @@ class POT
* @tutorial POT/Server_status.pkg * @tutorial POT/Server_status.pkg
* @deprecated 0.1.4 Use OTS_ServerInfo->status(). * @deprecated 0.1.4 Use OTS_ServerInfo->status().
*/ */
public static function serverStatus($server, $port) public static function serverStatus($server, $port, $timeout = 2.0)
{ {
$status = new OTS_ServerInfo($server, $port); $status = new OTS_ServerInfo($server, $port);
$status->setTimeout($timeout);
return $status->status(); return $status->status();
} }
@@ -1115,7 +1117,7 @@ class POT
* *
* @param IOTS_FileCache $cache Cache handler (skip this parameter to reset cache handler to null). * @param IOTS_FileCache $cache Cache handler (skip this parameter to reset cache handler to null).
*/ */
public function setItemsCache(IOTS_FileCache $cache = null) public function setItemsCache(?IOTS_FileCache $cache = null)
{ {
$this->itemsCache = $cache; $this->itemsCache = $cache;
} }
@@ -1253,7 +1255,7 @@ class POT
* *
* @param IOTS_FileCache $cache Cache handler (skip this parameter to reset cache handler to null). * @param IOTS_FileCache $cache Cache handler (skip this parameter to reset cache handler to null).
*/ */
public function setMapCache(IOTS_FileCache $cache = null) public function setMapCache(?IOTS_FileCache $cache = null)
{ {
$this->mapCache = $cache; $this->mapCache = $cache;
} }

View File

@@ -446,16 +446,13 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
if(isset($this->data['premium_ends_at']) || isset($this->data['premend'])) { if(isset($this->data['premium_ends_at']) || isset($this->data['premend'])) {
$col = isset($this->data['premium_ends_at']) ? 'premium_ends_at' : 'premend'; $col = isset($this->data['premium_ends_at']) ? 'premium_ends_at' : 'premend';
$ret = ceil(($this->data[$col] - time()) / (24 * 60 * 60)); $ret = ceil(($this->data[$col] - time()) / (24 * 60 * 60));
return $ret > 0 ? $ret : 0; return max($ret, 0);
} }
if($this->data['premdays'] == 0) { if($this->data['premdays'] == 0) {
return 0; return 0;
} }
global $config;
if(isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium'])) return -1;
if($this->data['premdays'] == self::GRATIS_PREMIUM_DAYS){ if($this->data['premdays'] == self::GRATIS_PREMIUM_DAYS){
return self::GRATIS_PREMIUM_DAYS; return self::GRATIS_PREMIUM_DAYS;
} }
@@ -1011,7 +1008,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable
public function logAction($action) public function logAction($action)
{ {
$ip = get_browser_real_ip(); $ip = get_browser_real_ip();
if(strpos($ip, ":") === false) { if(!str_contains($ip, ":")) {
$ipv6 = '0'; $ipv6 = '0';
} }
else { else {

View File

@@ -83,38 +83,4 @@ abstract class OTS_Base_DAO implements IOTS_DAO
{ {
unset($this->data['id']); unset($this->data['id']);
} }
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @version 0.1.0
* @param array $properties List of object properties.
*/
public static function __set_state($properties)
{
// deletes database handle
if( isset($properties['db']) )
{
unset($properties['db']);
}
// initializes new object with current database connection
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
} }
/**#@-*/
?>

View File

@@ -184,8 +184,14 @@ abstract class OTS_Base_DB extends PDO implements IOTS_DB
$query = 'UPDATE '.$this->tableName($table).' SET '; $query = 'UPDATE '.$this->tableName($table).' SET ';
$count = count($fields); $count = count($fields);
for ($i = 0; $i < $count; $i++) for ($i = 0; $i < $count; $i++) {
$query.= $this->fieldName($fields[$i]).' = '.$this->quote($values[$i]).', '; $value = 'NULL';
if ($values[$i] !== null) {
$value = $this->quote($values[$i]);
}
$query.= $this->fieldName($fields[$i]).' = '.$value.', ';
}
$query = substr($query, 0, -2); $query = substr($query, 0, -2);
$query.=' WHERE ('; $query.=' WHERE (';
@@ -229,6 +235,30 @@ abstract class OTS_Base_DB extends PDO implements IOTS_DB
$this->exec($query); $this->exec($query);
return true; return true;
} }
public function addColumn($table, $column, $definition): void {
$this->exec('ALTER TABLE ' . $this->tableName($table) . ' ADD ' . $this->fieldName($column) . ' ' . $definition . ';');
}
public function modifyColumn($table, $column, $definition): void {
$this->exec('ALTER TABLE ' . $this->tableName($table) . ' MODIFY ' . $this->fieldName($column) . ' ' . $definition . ';');
}
public function changeColumn($table, $from, $to, $definition): void {
$this->exec('ALTER TABLE ' . $this->tableName($table) . ' CHANGE ' . $this->fieldName($from) . ' ' . $this->fieldName($to) . ' ' . $definition . ';');
}
public function dropColumn($table, $column): void {
$this->exec('ALTER TABLE ' . $this->tableName($table) . ' DROP COLUMN ' . $this->fieldName($column) . ';');
}
public function renameTable($from, $to): void {
$this->exec('RENAME TABLE ' . $this->tableName($from) . ' TO ' . $this->tableName($to) . ';');
}
public function dropTable($table, $ifExists = true): void {
$this->exec('DROP TABLE ' . ($ifExists ? 'IF EXISTS' : '') . ' ' . $this->tableName($table) . ';');
}
/** /**
* LIMIT/OFFSET clause for queries. * LIMIT/OFFSET clause for queries.
* *

View File

@@ -196,6 +196,16 @@ class OTS_Buffer
return $value[1]; return $value[1];
} }
public function getLongLong()
{
// checks buffer size
$this->check(8);
$value = unpack('P', substr($this->buffer, $this->pos, 8) );
$this->pos += 8;
return $value[1];
}
/** /**
* Appends quater byte to buffer. * Appends quater byte to buffer.
* *

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