mirror of
				https://github.com/slawkens/myaac.git
				synced 2025-10-30 15:36:24 +01:00 
			
		
		
		
	Compare commits
	
		
			364 Commits
		
	
	
		
			feature/cs
			...
			feature/do
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 8d76e4e670 | ||
|   | da1816cc13 | ||
|   | 783d96fc65 | ||
|   | 5e14521f08 | ||
|   | 335a0d1cff | ||
|   | 988a3f2dbe | ||
|   | 8e0978c1ed | ||
|   | 023f1dc598 | ||
|   | ea5e1d4192 | ||
|   | 06188be6e1 | ||
|   | 2c42de688a | ||
|   | 4ac56e6b15 | ||
|   | 5e60249603 | ||
|   | d8b6b749ee | ||
|   | c5e114d550 | ||
|   | 706fca8868 | ||
|   | 65adf9ccdd | ||
|   | bc6663dc44 | ||
|   | e3ffe5d9e1 | ||
|   | c0a66037e0 | ||
|   | 17210b717f | ||
|   | 5782772b90 | ||
|   | 27c44f1bdf | ||
|   | 3f6ff3a332 | ||
|   | 79636280a7 | ||
|   | 38e699ba4b | ||
|   | afb055f2dc | ||
|   | 6f58df0467 | ||
|   | 95343cec02 | ||
|   | 8055785c81 | ||
|   | 64e4c08950 | ||
|   | 12d8faa3ed | ||
|   | 1e6892971b | ||
|   | 8ae22accc9 | ||
|   | a2fadc5945 | ||
|   | d0b4065ccf | ||
|   | 84d37c5a8f | ||
|   | 28a2b34cc1 | ||
|   | bab565fbd0 | ||
|   | 36bd3eb846 | ||
|   | 85bc2342cf | ||
|   | 507402171b | ||
|   | 941846605c | ||
|   | a4a2480995 | ||
|   | ddced132cf | ||
|   | 749e8e6f02 | ||
|   | 7d787b4566 | ||
|   | 7e67e11e16 | ||
|   | 011a85d8ae | ||
|   | 382f897322 | ||
|   | c980a09146 | ||
|   | 18bd325a44 | ||
|   | 078e20a9a4 | ||
|   | e96227fbe4 | ||
|   | c49c9d99a9 | ||
|   | a0f1971583 | ||
|   | cb5fc84e2e | ||
|   | 29b77035be | ||
|   | b8c0215720 | ||
|   | 3100faa645 | ||
|   | f7c9a67a96 | ||
|   | e8fedb8d16 | ||
|   | 4e4739e8ab | ||
|   | c6cc84a668 | ||
|   | 95a7c23a70 | ||
|   | a7fe400614 | ||
|   | 2568046a4d | ||
|   | 7161678c4b | ||
|   | 93641fc68a | ||
|   | ea7e808508 | ||
|   | da3fc1fc8c | ||
|   | 201f95caa8 | ||
|   | 779aa152fa | ||
|   | d99b22f98b | ||
|   | 35e28350bd | ||
|   | 327dcb5f87 | ||
|   | bc8ada6fe2 | ||
|   | 6183b7ee52 | ||
|   | 760c3ab017 | ||
|   | ab73d60c61 | ||
|   | 8d8bdb6dac | ||
|   | 71c00aa5e0 | ||
|   | 1fcdd54c94 | ||
|   | c2ec468246 | ||
|   | 68118fb7c2 | ||
|   | 5a69b9a802 | ||
|   | 45e63b13c3 | ||
|   | 758a8b3330 | ||
|   | 1843728930 | ||
|   | 5735d487d9 | ||
|   | cff62ccba4 | ||
|   | 28f98db9de | ||
|   | da14e125e9 | ||
|   | cd49dfc799 | ||
|   | ef79b99b8a | ||
|   | 9a27403e7d | ||
|   | 5f63c3b227 | ||
|   | 203e411b62 | ||
|   | fcb13f3c0f | ||
|   | d94828772c | ||
|   | 10a739773c | ||
|   | 83b3dc803a | ||
|   | 33a47137c9 | ||
|   | dc17b701da | ||
|   | d30811404b | ||
|   | a631760dbf | ||
|   | bc3dcab462 | ||
|   | a8d255c04b | ||
|   | 813786c768 | ||
|   | 0db0ec1aa4 | ||
|   | bdc0c43d3f | ||
|   | c7a6a539a9 | ||
|   | c1d4b4f80c | ||
|   | 47a19e85dd | ||
|   | d9c1b2507c | ||
|   | 4c0739d3e9 | ||
|   | afe70a03c5 | ||
|   | 3fadf87a7a | ||
|   | c24576165c | ||
|   | 1e5c9dcd9b | ||
|   | a04d186c22 | ||
|   | 42f99c3edc | ||
|   | 4f4965369d | ||
|   | 57b47ab798 | ||
|   | 9ea2a5067f | ||
|   | ec96985872 | ||
|   | 9f2a51b351 | ||
|   | a1d7c94166 | ||
|   | 0c3e3e16dd | ||
|   | 45dda5e834 | ||
|   | 32ae4dde20 | ||
|   | d3f03fa735 | ||
|   | 44eff8092c | ||
|   | 8ef3d06f1e | ||
|   | 60bd64a639 | ||
|   | a1bcb217ec | ||
|   | 933b681a9f | ||
|   | e9aea17e1b | ||
|   | 060400b074 | ||
|   | 6be4a42c5a | ||
|   | 1e8198635e | ||
|   | be78a0fc45 | ||
|   | 08ac8ebade | ||
|   | 66ecc487a1 | ||
|   | 9e23ec6745 | ||
|   | 968899ef77 | ||
|   | 3844ad0d71 | ||
|   | c93bf5a984 | ||
|   | 50336a810b | ||
|   | 48f6ca0eba | ||
|   | 30107222d4 | ||
|   | f92b275f70 | ||
|   | 504242fb84 | ||
|   | e2bab4220b | ||
|   | 0b4c34a823 | ||
|   | c5aa9a4684 | ||
|   | 301afe190b | ||
|   | c35cc83e4f | ||
|   | 3ba9d8f780 | ||
|   | 06f228509b | ||
|   | 39e682dfd2 | ||
|   | 6f209440e0 | ||
|   | b2a1675de3 | ||
|   | 163877d303 | ||
|   | a4d11c1a12 | ||
|   | 8cf4e3da02 | ||
|   | e0230c5237 | ||
|   | 127e03081c | ||
|   | e9c6017e60 | ||
|   | d5915df37e | ||
|   | eb0c2a7674 | ||
|   | d225c2da26 | ||
|   | d95e280b9a | ||
|   | 64387e085b | ||
|   | e1f507cf2d | ||
|   | c92a410209 | ||
|   | 1186f94e21 | ||
|   | f837b3133d | ||
|   | 9106f1e4ce | ||
|   | a62cfc5272 | ||
|   | 6229736d07 | ||
|   | 6807339056 | ||
|   | ffaa0729ac | ||
|   | 03cc09b8c7 | ||
|   | 6d4724f4f4 | ||
|   | 2afe0c1185 | ||
|   | d7e1ca747e | ||
|   | 6334f3f4fa | ||
|   | fe7ad61abe | ||
|   | 5a9490138b | ||
|   | e23a749e4c | ||
|   | ab5e4eff76 | ||
|   | fdd3bfd105 | ||
|   | 93ad347571 | ||
|   | 7d4aafda4f | ||
|   | 87e8c9eb4d | ||
|   | d61197b6a1 | ||
|   | dfba8bc60b | ||
|   | d2d497d82c | ||
|   | 4204e0a419 | ||
|   | e8e093cc1f | ||
|   | 2b39a1e406 | ||
|   | cac592e63a | ||
|   | 0255d0bef2 | ||
|   | a59f0e9244 | ||
|   | 9f3231fff6 | ||
|   | 647eae08b4 | ||
|   | e2487f97e3 | ||
|   | 235e69b8da | ||
|   | 649e37ab0f | ||
|   | dff4a98ef5 | ||
|   | b754374585 | ||
|   | ad789c50ff | ||
|   | ccfd2b4f55 | ||
|   | 3f5744964a | ||
|   | b22dc0014a | ||
|   | 00cbce20b0 | ||
|   | bbe922a65d | ||
|   | 8f23c62708 | ||
|   | 58bb6093b0 | ||
|   | 2faaa037ab | ||
|   | cc9057324a | ||
|   | f7971a21d8 | ||
|   | 08e7cf05b5 | ||
|   | 2e482fdc2a | ||
|   | a2c8e2b2ae | ||
|   | cc3e66cacb | ||
|   | bd86454fea | ||
|   | 1bb6e61583 | ||
|   | 13a2570ad0 | ||
|   | e961f2efcf | ||
|   | 54609bf90e | ||
|   | 6494bd2c0c | ||
|   | 670812772d | ||
|   | ae8a9fc44c | ||
|   | f80c5fd8ed | ||
|   | 6bac02bd35 | ||
|   | ac67555f28 | ||
|   | 6c4fd4ed27 | ||
|   | a8a896e0f5 | ||
|   | b517a12f8a | ||
|   | 5d741944f7 | ||
|   | a3056f5f48 | ||
|   | 8518f21987 | ||
|   | a3a2f05783 | ||
|   | 9f3c980ed2 | ||
|   | 31f8c99745 | ||
|   | 25c0bac7a3 | ||
|   | 9a749afc46 | ||
|   | 87df817eae | ||
|   | 3a58c8a6f9 | ||
|   | 2ba03e0c99 | ||
|   | f7f46bae00 | ||
|   | ccc91a473c | ||
|   | 7e347e950f | ||
|   | 535ae2047d | ||
|   | 12bc6a0333 | ||
|   | 3a86738983 | ||
|   | 3b3e9b0e70 | ||
|   | 54b9cc5402 | ||
|   | 6d23b285c1 | ||
|   | 76256a7ee6 | ||
|   | 07dafc5118 | ||
|   | b5c1b431d5 | ||
|   | 3a3e434d4e | ||
|   | d71bab648d | ||
|   | 3554b41172 | ||
|   | 41022727bd | ||
|   | 9b781d09a9 | ||
|   | c8d4e7d186 | ||
|   | 6cd8b7697d | ||
|   | 19c4cb810b | ||
|   | ba6119e6d0 | ||
|   | 1ce816040a | ||
|   | aa8e26f6a3 | ||
|   | f0eb113bc2 | ||
|   | 6ed8f18115 | ||
|   | 2262c4e882 | ||
|   | 69b02fa977 | ||
|   | 6baf49bba8 | ||
|   | bb02328b5a | ||
|   | 5a4854c205 | ||
|   | c661ae36ef | ||
|   | df8fb68d5e | ||
|   | fb0afdcea1 | ||
|   | e3775fed86 | ||
|   | 93b0d3829d | ||
|   | b6f98ffdee | ||
|   | 511e10e78b | ||
|   | cfdbc2a8b2 | ||
|   | 1a6fb8bee2 | ||
|   | 410d75c882 | ||
|   | c59bacea93 | ||
|   | f719c02050 | ||
|   | 0698e7b5f5 | ||
|   | c594dfd14b | ||
|   | 514c4a037a | ||
|   | b894f75e74 | ||
|   | d2a3a9a8da | ||
|   | 3f4c02a327 | ||
|   | 199672e0c8 | ||
|   | 02adb87fac | ||
|   | b4448f7279 | ||
|   | 687c9a6690 | ||
|   | 2b86ba94fe | ||
|   | a9fb5dffa3 | ||
|   | da77ec20ef | ||
|   | 6fd141eca6 | ||
|   | e17dde0dca | ||
|   | d1046ba21d | ||
|   | 98332f1483 | ||
|   | 1423046039 | ||
|   | 9c60beeed0 | ||
|   | 336b6ac530 | ||
|   | c71722fc52 | ||
|   | 4d8d574089 | ||
|   | e74fbe5bfd | ||
|   | 48e9a1ed51 | ||
|   | 56631bdf27 | ||
|   | b1224d9d1a | ||
|   | e18ada3d9d | ||
|   | c8218f69a5 | ||
|   | f991a8c817 | ||
|   | 36ec2e1e56 | ||
|   | 19c06df300 | ||
|   | b2d5d6f115 | ||
|   | 5769ac8bb4 | ||
|   | 41c9f54e4b | ||
|   | 8ef238c96c | ||
|   | 9ffb7f5fa9 | ||
|   | 8b5464f8f8 | ||
|   | f008591580 | ||
|   | 1d5b751fe1 | ||
|   | 37bde7df22 | ||
|   | 89deca1adb | ||
|   | c996f25d8d | ||
|   | d291f694d2 | ||
|   | cee1e67d3d | ||
|   | c81861d8c8 | ||
|   | c3c1a6b2a6 | ||
|   | d0590d2747 | ||
|   | c79a1d5f3a | ||
|   | ada1e391d4 | ||
|   | 193e18523d | ||
|   | 3fb9b1ae2f | ||
|   | 561bdcd766 | ||
|   | 556ef47d59 | ||
|   | 130ad25c4d | ||
|   | 08bea2c541 | ||
|   | 8974830621 | ||
|   | d582120fac | ||
|   | 8227303b89 | ||
|   | 7a402ec0e0 | ||
|   | 790d85a88a | ||
|   | 42e40e5d77 | ||
|   | 80a3a72b36 | ||
|   | a4b1631f6d | ||
|   | 49af260c2e | ||
|   | 72d7ee8bf2 | ||
|   | c503f5e0a5 | ||
|   | 03b2d71572 | ||
|   | 86b94ea5e8 | ||
|   | e9b5617748 | ||
|   | fee9d60da4 | 
							
								
								
									
										65
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | Thumbs.db | ||||||
|  | .DS_Store | ||||||
|  | .idea | ||||||
|  |  | ||||||
|  | # | ||||||
|  | /.htaccess | ||||||
|  |  | ||||||
|  | # composer | ||||||
|  | composer.phar | ||||||
|  | vendor | ||||||
|  |  | ||||||
|  | # npm | ||||||
|  | node_modules | ||||||
|  | tools/ext | ||||||
|  |  | ||||||
|  | # cypress | ||||||
|  | cypress.env.json | ||||||
|  | cypress/e2e/2-advanced-examples | ||||||
|  | cypress/screenshots | ||||||
|  |  | ||||||
|  | # created by release.sh | ||||||
|  | releases | ||||||
|  | tmp | ||||||
|  |  | ||||||
|  | config.local.php | ||||||
|  | !docker/config.local.php | ||||||
|  |  | ||||||
|  | # all custom templates | ||||||
|  | templates/* | ||||||
|  | !templates/tibiacom | ||||||
|  | !templates/kathrine | ||||||
|  |  | ||||||
|  | # guild images | ||||||
|  | images/guilds/* | ||||||
|  | !images/guilds/default.gif | ||||||
|  |  | ||||||
|  | # editor images | ||||||
|  | images/editor/* | ||||||
|  | !images/editor/index.html | ||||||
|  |  | ||||||
|  | # gallery images | ||||||
|  | images/gallery/* | ||||||
|  | !images/gallery/index.html | ||||||
|  | !images/gallery/demon.jpg | ||||||
|  | !images/gallery/demon_thumb.gif | ||||||
|  |  | ||||||
|  | # cache | ||||||
|  | system/cache/* | ||||||
|  | !system/cache/index.html | ||||||
|  | !system/cache/twig/index.html | ||||||
|  | !system/cache/signatures/index.html | ||||||
|  | !system/cache/plugins/index.html | ||||||
|  | !system/cache/persistent/index.html | ||||||
|  |  | ||||||
|  | # logs | ||||||
|  | system/logs/* | ||||||
|  | !system/logs/index.html | ||||||
|  |  | ||||||
|  | # data | ||||||
|  | system/data/* | ||||||
|  | !system/data/index.html | ||||||
|  |  | ||||||
|  | # php sessions | ||||||
|  | system/php_sessions/* | ||||||
|  | !system/php_sessions/index.html | ||||||
							
								
								
									
										98
									
								
								.github/workflows/cypress.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										98
									
								
								.github/workflows/cypress.yml
									
									
									
									
										vendored
									
									
								
							| @@ -22,8 +22,9 @@ jobs: | |||||||
|     strategy: |     strategy: | ||||||
|       fail-fast: false |       fail-fast: false | ||||||
|       matrix: |       matrix: | ||||||
|         php-versions: [ '7.4', '8.0', '8.1' ] |         php-versions: [ '8.1', '8.2', '8.3' ] | ||||||
|     name: MyAAC on PHP ${{ matrix.php-versions }} |         ots: ['tfs-1.4', 'canary-3.1.2'] # TODO: add 'tfs-master' (actually doesn't work cause AAC doesn't support reading .env configuration) | ||||||
|  |     name: Cypress (PHP ${{ matrix.php-versions }}, ${{ matrix.ots }}) | ||||||
|     steps: |     steps: | ||||||
|         - name: 📌 MySQL Start & init & show db |         - name: 📌 MySQL Start & init & show db | ||||||
|           run: | |           run: | | ||||||
| @@ -32,47 +33,81 @@ jobs: | |||||||
|             mysql -e "SHOW DATABASES" -uroot -proot |             mysql -e "SHOW DATABASES" -uroot -proot | ||||||
|  |  | ||||||
|         - name: Checkout MyAAC |         - name: Checkout MyAAC | ||||||
|           uses: actions/checkout@v3 |           uses: actions/checkout@v4 | ||||||
|           with: |           with: | ||||||
|             ref: 0.9 |             ref: develop | ||||||
|  |  | ||||||
|  |         - uses: actions/setup-node@v4 | ||||||
|  |           with: | ||||||
|  |             node-version: 18 | ||||||
|  |         - run: npm ci | ||||||
|  |  | ||||||
|         - name: Checkout TFS |         - name: Checkout TFS | ||||||
|           uses: actions/checkout@v3 |           uses: actions/checkout@v4 | ||||||
|  |           if: matrix.ots == 'tfs-1.4' | ||||||
|           with: |           with: | ||||||
|             repository: otland/forgottenserver |             repository: otland/forgottenserver | ||||||
|             ref: 1.4 |             ref: 1.4 | ||||||
|             path: tfs |             path: ots | ||||||
|  |  | ||||||
|         - name: Import TFS Schema |         - name: Checkout TFS | ||||||
|  |           uses: actions/checkout@v4 | ||||||
|  |           if: matrix.ots == 'tfs-master' | ||||||
|  |           with: | ||||||
|  |             repository: otland/forgottenserver | ||||||
|  |             ref: master | ||||||
|  |             path: ots | ||||||
|  |  | ||||||
|  |         - name: Checkout Canary | ||||||
|  |           uses: actions/checkout@v4 | ||||||
|  |           if: matrix.ots == 'canary-3.1.2' | ||||||
|  |           with: | ||||||
|  |             repository: opentibiabr/canary | ||||||
|  |             ref: v3.1.2 | ||||||
|  |             path: ots | ||||||
|  |  | ||||||
|  |         - name: Import OTS Schema | ||||||
|           run: | |           run: | | ||||||
|               mysql -uroot -proot myaac < tfs/schema.sql |               mysql -uroot -proot myaac < ots/schema.sql | ||||||
|  |  | ||||||
|         - name: Rename config.lua |         - name: Rename config.lua | ||||||
|           run: mv tfs/config.lua.dist tfs/config.lua |           run: mv ots/config.lua.dist ots/config.lua | ||||||
|  |  | ||||||
|         - name: Replace mysqlUser |         - name: Replace mysqlUser (TFS 1.4) | ||||||
|           uses: jacobtomlinson/gha-find-replace@v2 |           uses: jacobtomlinson/gha-find-replace@v3 | ||||||
|  |           if: matrix.ots == 'tfs-1.4' | ||||||
|           with: |           with: | ||||||
|             find: 'mysqlUser = "forgottenserver"' |             find: 'mysqlUser = "forgottenserver"' | ||||||
|             replace: 'mysqlUser = "root"' |             replace: 'mysqlUser = "root"' | ||||||
|             regex: false |             regex: false | ||||||
|             include: 'tfs/config.lua' |             include: 'ots/config.lua' | ||||||
|  |  | ||||||
|         - name: Replace mysqlPass |         - name: Replace mysqlPass (TFS 1.4) | ||||||
|           uses: jacobtomlinson/gha-find-replace@v2 |           uses: jacobtomlinson/gha-find-replace@v3 | ||||||
|  |           if: matrix.ots == 'tfs-1.4' | ||||||
|           with: |           with: | ||||||
|               find: 'mysqlPass = ""' |               find: 'mysqlPass = ""' | ||||||
|               replace: 'mysqlPass = "root"' |               replace: 'mysqlPass = "root"' | ||||||
|               regex: false |               regex: false | ||||||
|               include: 'tfs/config.lua' |               include: 'ots/config.lua' | ||||||
|  |  | ||||||
|         - name: Replace mysqlDatabase |         - name: Replace mysqlDatabase (TFS 1.4) | ||||||
|           uses: jacobtomlinson/gha-find-replace@v2 |           uses: jacobtomlinson/gha-find-replace@v3 | ||||||
|  |           if: matrix.ots == 'tfs-1.4' | ||||||
|           with: |           with: | ||||||
|               find: 'mysqlDatabase = "forgottenserver"' |               find: 'mysqlDatabase = "forgottenserver"' | ||||||
|               replace: 'mysqlDatabase = "myaac"' |               replace: 'mysqlDatabase = "myaac"' | ||||||
|               regex: false |               regex: false | ||||||
|               include: 'tfs/config.lua' |               include: 'ots/config.lua' | ||||||
|  |  | ||||||
|  |         - name: Replace mysqlDatabase (Canary) | ||||||
|  |           uses: jacobtomlinson/gha-find-replace@v3 | ||||||
|  |           if: matrix.ots == 'canary-3.1.2' | ||||||
|  |           with: | ||||||
|  |               find: 'mysqlDatabase = "otservbr-global"' | ||||||
|  |               replace: 'mysqlDatabase = "myaac"' | ||||||
|  |               regex: false | ||||||
|  |               include: 'ots/config.lua' | ||||||
|  |  | ||||||
|         - name: Setup PHP |         - name: Setup PHP | ||||||
|           uses: shivammathur/setup-php@v2 |           uses: shivammathur/setup-php@v2 | ||||||
| @@ -85,13 +120,13 @@ jobs: | |||||||
|           run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT |           run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | ||||||
|  |  | ||||||
|         - name: Cache composer dependencies |         - name: Cache composer dependencies | ||||||
|           uses: actions/cache@v3 |           uses: actions/cache@v4 | ||||||
|           with: |           with: | ||||||
|             path: ${{ steps.composer-cache.outputs.dir }} |             path: ${{ steps.composer-cache.outputs.dir }} | ||||||
|             # Use composer.json for key, if composer.lock is not committed. |             # Use composer.json for key, if composer.lock is not committed. | ||||||
|             # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} |             key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} | ||||||
|             key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} |             #key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | ||||||
|             restore-keys: ${{ runner.os }}-composer- |             restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} | ||||||
|  |  | ||||||
|         - name: Install Composer dependencies |         - name: Install Composer dependencies | ||||||
|           run: composer install --no-progress --prefer-dist --optimize-autoloader |           run: composer install --no-progress --prefer-dist --optimize-autoloader | ||||||
| @@ -100,21 +135,28 @@ jobs: | |||||||
|           run: nohup php -S localhost:8080 > php.log 2>&1 & |           run: nohup php -S localhost:8080 > php.log 2>&1 & | ||||||
|  |  | ||||||
|         - name: Cypress Run |         - name: Cypress Run | ||||||
|           uses: cypress-io/github-action@v5 |           uses: cypress-io/github-action@v6 | ||||||
|           env: |           env: | ||||||
|             CYPRESS_URL: http://localhost:8080 |             CYPRESS_URL: http://localhost:8080 | ||||||
|             CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/tfs |             CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/ots | ||||||
|  |  | ||||||
|         - name: Save screenshots |         - name: Save screenshots | ||||||
|           uses: actions/upload-artifact@v3 |           uses: actions/upload-artifact@v4 | ||||||
|           if: always() |           if: always() | ||||||
|           with: |           with: | ||||||
|             name: cypress-screenshots |             name: cypress-screenshots-${{ matrix.php-versions }}-${{ matrix.ots }} | ||||||
|             path: cypress/screenshots |             path: cypress/screenshots | ||||||
|  |  | ||||||
|         - name: Upload Cypress Videos |         - name: Upload Cypress Videos | ||||||
|           uses: actions/upload-artifact@v3 |           uses: actions/upload-artifact@v4 | ||||||
|           if: always() |           if: always() | ||||||
|           with: |           with: | ||||||
|             name: cypress-videos |             name: cypress-videos-${{ matrix.php-versions }}-${{ matrix.ots }} | ||||||
|             path: cypress/videos |             path: cypress/videos | ||||||
|  |  | ||||||
|  |         - name: Upload PHP Logs | ||||||
|  |           uses: actions/upload-artifact@v4 | ||||||
|  |           if: always() | ||||||
|  |           with: | ||||||
|  |             name: php-log-${{ matrix.php-versions }}-${{ matrix.ots }} | ||||||
|  |             path: php.log | ||||||
|   | |||||||
							
								
								
									
										46
									
								
								.github/workflows/phpstan.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								.github/workflows/phpstan.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | name: "PHPStan" | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   pull_request: | ||||||
|  |     branches: [develop] | ||||||
|  |   push: | ||||||
|  |     branches: [develop] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   tests: | ||||||
|  |     name: PhpStan on PHP ${{ matrix.php-versions }} | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |  | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         php-versions: [ '8.1', '8.2', '8.3' ] | ||||||
|  |     steps: | ||||||
|  |       - name: "Checkout" | ||||||
|  |         uses: "actions/checkout@v4" | ||||||
|  |  | ||||||
|  |       - name: "Install PHP" | ||||||
|  |         uses: "shivammathur/setup-php@v2" | ||||||
|  |         with: | ||||||
|  |           coverage: "none" | ||||||
|  |           extensions: "intl, zip" | ||||||
|  |           ini-values: "memory_limit=-1" | ||||||
|  |           php-version: "${{ matrix.php-version }}" | ||||||
|  |  | ||||||
|  |       - name: Get composer cache directory | ||||||
|  |         id: composer-cache | ||||||
|  |         run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | ||||||
|  |  | ||||||
|  |       - name: Cache composer dependencies | ||||||
|  |         uses: actions/cache@v4 | ||||||
|  |         with: | ||||||
|  |           path: ${{ steps.composer-cache.outputs.dir }} | ||||||
|  |           # Use composer.json for key, if composer.lock is not committed. | ||||||
|  |           key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | ||||||
|  |           restore-keys: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | ||||||
|  |  | ||||||
|  |       - name: "Install composer dependencies" | ||||||
|  |         run: "composer install" | ||||||
|  |  | ||||||
|  |       - name: "Run PHPStan" | ||||||
|  |         run: "/usr/bin/php vendor/bin/phpstan analyse" | ||||||
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -6,21 +6,24 @@ Thumbs.db | |||||||
| /.htaccess | /.htaccess | ||||||
|  |  | ||||||
| # 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 | ||||||
| tmp | tmp | ||||||
|  |  | ||||||
| config.local.php | config.local.php | ||||||
|  | !docker/config.local.php | ||||||
|  |  | ||||||
| # all custom templates | # all custom templates | ||||||
| templates/* | templates/* | ||||||
| @@ -47,6 +50,7 @@ system/cache/* | |||||||
| !system/cache/twig/index.html | !system/cache/twig/index.html | ||||||
| !system/cache/signatures/index.html | !system/cache/signatures/index.html | ||||||
| !system/cache/plugins/index.html | !system/cache/plugins/index.html | ||||||
|  | !system/cache/persistent/index.html | ||||||
|  |  | ||||||
| # logs | # logs | ||||||
| system/logs/* | system/logs/* | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,8 +1,60 @@ | |||||||
| # Changelog | # Changelog | ||||||
|  |  | ||||||
| ## [0.9.0-alpha - 02.06.2023] | ## [1.0-RC.2 - 25.10.2024] | ||||||
|  |  | ||||||
| Minimum PHP version for this release is 7.2.5. | 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 | ### Added | ||||||
| * reworked Admin Panel (@Leesneaks, @gpedro, @slawkens) | * reworked Admin Panel (@Leesneaks, @gpedro, @slawkens) | ||||||
| @@ -11,17 +63,26 @@ Minimum PHP version for this release is 7.2.5. | |||||||
|   * new Dashboard: statistics, server status |   * new Dashboard: statistics, server status | ||||||
|   * new Admin Bar showed on top when admin logged in |   * new Admin Bar showed on top when admin logged in | ||||||
|   * new page: Server Data, to reload server data |   * new page: Server Data, to reload server data | ||||||
|  |     * Towns, NPCs & Items are stored in permanent cache | ||||||
|   * new pages: mass account & teleport tools |   * new pages: mass account & teleport tools | ||||||
|   * changelogs editor |   * changelogs editor | ||||||
|   * revised Accounts & Players editors |   * revised Accounts & Players editors | ||||||
|   * option to add/modify menus with plugins |   * option to add/modify admin menus with plugins | ||||||
|   * option to enable/disable plugins |   * option to enable/disable plugins | ||||||
|   * better, updated TinyMCE editor (v6.x) |   * better, updated TinyMCE editor (v6.x) | ||||||
|     * with option to upload images |     * with option to upload images | ||||||
|   * list of open source libraries used in project |   * list of open source libraries used in project page | ||||||
|  | * auto-loading of themes, commands & pages from plugins/ folder. You need just to place them in correct folder and they will be loaded automatically - this allows better customization, without interfering with core AAC folders. This will allow in the future automatic updates for plugins as well the AAC as whole. | ||||||
|  | * config.php moved to Admin Panel -> Settings page | ||||||
|  | * new console script: aac - using symfony/console | ||||||
|  |   * usage: `php aac` (will list all commands by default) | ||||||
|  |   * example: `php aac cache:clear` | ||||||
|  |   * example: `php aac plugin:install theme-example.zip` | ||||||
|  | * replace POT Query Builder to Eloquent ORM. Not 100% yet - in some places there is still old $db approach used (@gpedro) (https://github.com/slawkens/myaac/pull/230) | ||||||
| * brand new charming installation page (by @fernandomatos) | * brand new charming installation page (by @fernandomatos) | ||||||
|   * using Bootstrap |   * using Bootstrap | ||||||
| * new pages router: nikic/fast-route, allowing for better customisation | * new pages router: nikic/fast-route, allowing for better customisation | ||||||
|  | * Plugin cronjobs: central control of the cronjobs | ||||||
| * Guild Wars support (available as plugin) | * Guild Wars support (available as plugin) | ||||||
| * support for login and create account only by email (configurable) | * support for login and create account only by email (configurable) | ||||||
|   * with no need for account name |   * with no need for account name | ||||||
| @@ -31,10 +92,13 @@ Minimum PHP version for this release is 7.2.5. | |||||||
|   * suggest account number option |   * suggest account number option | ||||||
| * many new functions, hooks and configurables | * many new functions, hooks and configurables | ||||||
| * better Exception Handler (Whoops - https://github.com/filp/whoops) | * better Exception Handler (Whoops - https://github.com/filp/whoops) | ||||||
| * add Cypress testing | * automated website tests (using Cypress) | ||||||
|  | * csrf protection (https://github.com/slawkens/myaac/pull/235) | ||||||
|  | * option to restrict Page view to specified group of users (Not-Logged in, logged-in players, tutors, gamemasters etc.) | ||||||
|  | * phpdebug bar (http://phpdebugbar.com/). Activated if env == 'dev', can be also activated in production by enabling "enable_debugbar" in local config | ||||||
|  |  | ||||||
| ### Changed | ### Changed | ||||||
| * Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc. | * Composer 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 | * 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 | * 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 | * visitors counter shows now user browser, and also if its bot | ||||||
| @@ -45,7 +109,7 @@ Minimum PHP version for this release is 7.2.5. | |||||||
| 	* Highscores | 	* Highscores | ||||||
| 		* frags works for TFS 1.x | 		* frags works for TFS 1.x | ||||||
| 		* cached | 		* cached | ||||||
| 	* creatures | 	* Monsters | ||||||
| * moved pages to Twig: | * moved pages to Twig: | ||||||
|   * experience stages |   * experience stages | ||||||
| * update player_deaths entries on name change | * update player_deaths entries on name change | ||||||
|   | |||||||
| @@ -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> | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								README.md
									
									
									
									
									
								
							| @@ -10,21 +10,20 @@ Official website: https://my-aac.org | |||||||
| [](https://discord.gg/2J39Wus) | [](https://discord.gg/2J39Wus) | ||||||
| [](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed) | [](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed) | ||||||
|  |  | ||||||
| | Version    | Status                                    | Branch  | Requirements   | | | Version | Status                 | Branch  | Requirements   | | ||||||
| |:-----------|:------------------------------------------|:--------|:---------------| | |:--------|:-----------------------|:--------|:---------------| | ||||||
| | **0.10.x** | **Active development**                    | develop | **PHP >= 8.0** | | | **1.x** | **Active development** | develop | **PHP >= 8.1** | | ||||||
| | 0.9.x      | Active support                            | 0.9     | PHP >= 7.2.5   | | | 0.9.x   | Not developed anymore  | 0.9     | PHP >= 7.2.5   | | ||||||
| | 0.8.x      | Active support                            | master  | PHP >= 7.2.5   | | | 0.8.x   | Active support         | master  | PHP >= 7.2.5   | | ||||||
| | 0.7.x      | End Of Life                               | 0.7     | PHP >= 5.3.3   | | | 0.7.x   | End Of Life            | 0.7     | PHP >= 5.3.3   | | ||||||
|  |  | ||||||
| ### Requirements | ### Requirements | ||||||
|  |  | ||||||
| 	- PHP 8.0 or later |  | ||||||
| 	- MySQL database | 	- MySQL database | ||||||
| 	- PDO PHP Extension | 	- PHP Extensions: pdo, xml, json | ||||||
| 	- XML PHP Extension | 	- (optional) apache2 mod_rewrite (to use friendly_urls) | ||||||
| 	- (optional) ZIP PHP Extension | 	- (optional) zip PHP Extension (to install plugins) | ||||||
| 	- (optional) mod_rewrite to use friendly_urls | 	- (optional) gd PHP Extension (for generating signature images) | ||||||
|  |  | ||||||
| ### Installation | ### Installation | ||||||
|  |  | ||||||
| @@ -48,7 +47,8 @@ Official website: https://my-aac.org | |||||||
|  |  | ||||||
| ### Configuration | ### Configuration | ||||||
|  |  | ||||||
| Check *config.php* to get more informations. | Check *config.php* to get more informations. (Notice: MyAAC 1.0+ doesn't use config.php anymore, it has been moved to Admin Panel - Settings page). | ||||||
|  |  | ||||||
| Use *config.local.php* for your local configuration changes. | Use *config.local.php* for your local configuration changes. | ||||||
|  |  | ||||||
| ### Branches | ### Branches | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								aac
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								aac
									
									
									
									
									
										Normal 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(); | ||||||
							
								
								
									
										22
									
								
								admin/includes/debugbar.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								admin/includes/debugbar.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | $hooks->register('debugbar_admin_head_end', HOOK_ADMIN_HEAD_END, function ($params) { | ||||||
|  | 	global $debugBar; | ||||||
|  |  | ||||||
|  | 	if (!isset($debugBar)) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$debugBarRenderer = $debugBar->getJavascriptRenderer(); | ||||||
|  | 	echo $debugBarRenderer->renderHead(); | ||||||
|  | }); | ||||||
|  | $hooks->register('debugbar_admin_body_end', HOOK_ADMIN_BODY_END, function ($params) { | ||||||
|  | 	global $debugBar; | ||||||
|  |  | ||||||
|  | 	if (!isset($debugBar)) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$debugBarRenderer = $debugBar->getJavascriptRenderer(); | ||||||
|  | 	echo $debugBarRenderer->render(); | ||||||
|  | }); | ||||||
| @@ -1,5 +1,7 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
|  | use MyAAC\Plugins; | ||||||
|  |  | ||||||
| $order = 10; | $order = 10; | ||||||
|  |  | ||||||
| $settingsMenu = []; | $settingsMenu = []; | ||||||
|   | |||||||
| @@ -25,11 +25,7 @@ define('PAGE', $page); | |||||||
| require SYSTEM . 'functions.php'; | require SYSTEM . 'functions.php'; | ||||||
| require SYSTEM . 'init.php'; | require SYSTEM . 'init.php'; | ||||||
|  |  | ||||||
| // verify myaac tables exists in database | require __DIR__ . '/includes/debugbar.php'; | ||||||
| if(!$db->hasTable('myaac_account_actions')) { |  | ||||||
| 	throw new RuntimeException('Seems that the table <strong>myaac_account_actions</strong> of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting <a href="' . BASE_URL . 'install">this</a> url.'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| require SYSTEM . 'status.php'; | require SYSTEM . 'status.php'; | ||||||
| require SYSTEM . 'login.php'; | require SYSTEM . 'login.php'; | ||||||
| require __DIR__ . '/includes/functions.php'; | require __DIR__ . '/includes/functions.php'; | ||||||
| @@ -49,7 +45,7 @@ if(!$logged || !admin()) { | |||||||
| // include our page | // include our page | ||||||
| $file = __DIR__ . '/pages/' . $page . '.php'; | $file = __DIR__ . '/pages/' . $page . '.php'; | ||||||
| if(!@file_exists($file)) { | if(!@file_exists($file)) { | ||||||
| 	if (strpos($page, 'plugins/') !== false) { | 	if (str_contains($page, 'plugins/')) { | ||||||
| 		$file = BASE . $page; | 		$file = BASE . $page; | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
|   | |||||||
| @@ -8,21 +8,22 @@ | |||||||
|  * @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!'); | ||||||
|  |  | ||||||
| $title = 'Account editor'; | $title = 'Account editor'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| $admin_base = ADMIN_URL . '?p=accounts'; | $admin_base = ADMIN_URL . '?p=accounts'; | ||||||
| $use_datatable = true; | $use_datatable = true; | ||||||
|  |  | ||||||
| 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'); | ||||||
| @@ -48,41 +49,56 @@ $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 . '%')); | 			$str_construct = 'Do you mean?<ul class="mb-0">'; | ||||||
| 			if ($query->rowCount() > 0 && $query->rowCount() <= 10) { | 			foreach ($query as $row) { | ||||||
| 				$str_construct = 'Do you mean?<ul class="mb-0">'; | 				$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row->getKey() . '">' . $row->attributes[$nameOrNumberColumn] . '</a></li>'; | ||||||
| 				foreach ($query as $row) | 			} | ||||||
| 					$str_construct .= '<li><a href="' . $admin_base . '&id=' . $row['id'] . '">' . $row[$nameOrNumberColumn] . '</a></li>'; | 			$str_construct .= '</ul>'; | ||||||
| 				$str_construct .= '</ul>'; | 			echo_error($str_construct); | ||||||
| 				echo_error($str_construct); |  | ||||||
| 			} else if ($query->rowCount() > 10) |  | ||||||
| 				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); | ||||||
|  |  | ||||||
| 		if (isset($account, $_POST['save']) && $account->isLoaded()) { | 		if (isset($_POST['save']) && $account->isLoaded()) { | ||||||
| 			$error = false; | 			$error = false; | ||||||
|  |  | ||||||
| 			$_error = ''; | 			$_error = ''; | ||||||
| @@ -140,7 +156,9 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 			$rl_loca = $_POST['rl_loca']; | 			$rl_loca = $_POST['rl_loca']; | ||||||
|  |  | ||||||
| 			//country | 			//country | ||||||
| 			$rl_country = $_POST['rl_country']; | 			if(setting('core.account_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); | ||||||
| @@ -187,7 +205,11 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 				} | 				} | ||||||
| 				$account->setRLName($rl_name); | 				$account->setRLName($rl_name); | ||||||
| 				$account->setLocation($rl_loca); | 				$account->setLocation($rl_loca); | ||||||
| 				$account->setCountry($rl_country); |  | ||||||
|  | 				if(setting('core.account_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); | ||||||
| @@ -211,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"> | ||||||
| @@ -223,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> | ||||||
| @@ -235,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) { | ||||||
| @@ -288,7 +312,8 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 				<div class="card-body"> | 				<div class="card-body"> | ||||||
| 					<div class="tab-content" id="accounts-tabContent"> | 					<div class="tab-content" id="accounts-tabContent"> | ||||||
| 						<div class="tab-pane fade active show" id="accounts-acc"> | 						<div class="tab-pane fade active show" id="accounts-acc"> | ||||||
| 							<form action="<?php echo $admin_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post"> | 							<form action="<?php echo $admin_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post"> | ||||||
|  | 								<?php csrf(); ?> | ||||||
| 								<div class="form-group row"> | 								<div class="form-group row"> | ||||||
| 									<?php if (USE_ACCOUNT_NAME): ?> | 									<?php if (USE_ACCOUNT_NAME): ?> | ||||||
| 										<div class="col-12 col-sm-12 col-lg-4"> | 										<div class="col-12 col-sm-12 col-lg-4"> | ||||||
| @@ -400,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"> | ||||||
| @@ -408,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"> | ||||||
| @@ -581,6 +608,17 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 				<div class="row"> | 				<div class="row"> | ||||||
| 					<div class="col-6 col-lg-12"> | 					<div class="col-6 col-lg-12"> | ||||||
| 						<form action="<?php echo $admin_base; ?>" method="post"> | 						<form action="<?php echo $admin_base; ?>" method="post"> | ||||||
|  | 							<?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"> | ||||||
|  | 						<form action="<?php echo $admin_base; ?>" method="post"> | ||||||
|  | 							<?php csrf(); ?> | ||||||
| 							<label for="search">Account Name:</label> | 							<label for="search">Account Name:</label> | ||||||
| 							<div class="input-group input-group-sm"> | 							<div class="input-group input-group-sm"> | ||||||
| 								<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_account); ?>" maxlength="32" size="32"> | 								<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_account); ?>" maxlength="32" size="32"> | ||||||
| @@ -590,6 +628,7 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 					</div> | 					</div> | ||||||
| 					<div class="col-6 col-lg-12"> | 					<div class="col-6 col-lg-12"> | ||||||
| 						<form action="<?php echo $admin_base; ?>" method="post"> | 						<form action="<?php echo $admin_base; ?>" method="post"> | ||||||
|  | 							<?php csrf(); ?> | ||||||
| 							<label for="id">Account ID:</label> | 							<label for="id">Account ID:</label> | ||||||
| 							<div class="input-group input-group-sm"> | 							<div class="input-group input-group-sm"> | ||||||
| 								<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32"> | 								<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32"> | ||||||
|   | |||||||
| @@ -9,34 +9,33 @@ | |||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\Changelog; | ||||||
| use MyAAC\Models\Changelog as ModelsChangelog; | use MyAAC\Models\Changelog as ModelsChangelog; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
|  | $title = 'Changelog'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | ||||||
| 	echo 'Access denied.'; | 	echo 'Access denied.'; | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| $title = 'Changelog'; |  | ||||||
| $use_datatable = true; | $use_datatable = true; | ||||||
| const CL_LIMIT = 600; // maximum changelog body length | const CL_LIMIT = 600; // maximum changelog body length | ||||||
| ?> |  | ||||||
|  |  | ||||||
| <link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ > |  | ||||||
| <script src="<?php echo BASE_URL; ?>tools/js/jquery.datetimepicker.js"></script> |  | ||||||
| <?php |  | ||||||
| $id = $_GET['id'] ?? 0; | $id = $_GET['id'] ?? 0; | ||||||
| require_once LIBS . 'changelog.php'; |  | ||||||
|  |  | ||||||
| if(!empty($action)) | if(!empty($action) && isRequestMethod('post')) | ||||||
| { | { | ||||||
| 	$id = $_REQUEST['id'] ?? null; | 	$id = $_POST['id'] ?? null; | ||||||
| 	$body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null; | 	$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null; | ||||||
| 	$create_date = isset($_REQUEST['createdate']) ? (int)strtotime($_REQUEST['createdate'] ): null; | 	$create_date = isset($_POST['createdate']) ? (int)strtotime($_POST['createdate'] ): null; | ||||||
| 	$player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null; | 	$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null; | ||||||
| 	$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null; | 	$type = isset($_POST['type']) ? (int)$_POST['type'] : null; | ||||||
| 	$where = isset($_REQUEST['where']) ? (int)$_REQUEST['where'] : null; | 	$where = isset($_POST['where']) ? (int)$_POST['where'] : null; | ||||||
|  |  | ||||||
| 	$errors = array(); | 	$errors = array(); | ||||||
|  |  | ||||||
| @@ -46,12 +45,13 @@ if(!empty($action)) | |||||||
| 			$body = ''; | 			$body = ''; | ||||||
| 			$type = $where = $player_id = $create_date = 0; | 			$type = $where = $player_id = $create_date = 0; | ||||||
|  |  | ||||||
| 			success("Added successful."); | 			success('Added successful.'); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else if($action == 'delete') { | 	else if($action == 'delete') { | ||||||
| 		Changelog::delete($id, $errors); | 		if (Changelog::delete($id, $errors)) { | ||||||
| 		success("Deleted successful."); | 			success('Deleted successful.'); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	else if($action == 'edit') | 	else if($action == 'edit') | ||||||
| 	{ | 	{ | ||||||
| @@ -68,13 +68,14 @@ if(!empty($action)) | |||||||
| 				$action = $body = ''; | 				$action = $body = ''; | ||||||
| 				$type = $where = $player_id = $create_date = 0; | 				$type = $where = $player_id = $create_date = 0; | ||||||
|  |  | ||||||
| 				success("Updated successful."); | 				success('Updated successful.'); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else if($action == 'hide') { | 	else if($action == 'hide') { | ||||||
| 		Changelog::toggleHidden($id, $errors, $status); | 		if (Changelog::toggleHide($id, $errors, $status)) { | ||||||
| 		success(($status == 1 ? 'Show' : 'Hide') . " successful."); | 			success(($status == 1 ? 'Hide' : 'Show') . ' successful.'); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if(!empty($errors)) | 	if(!empty($errors)) | ||||||
| @@ -113,7 +114,7 @@ if($action == 'edit' || $action == 'new') { | |||||||
| 	$account_players->orderBy('group_id', POT::ORDER_DESC); | 	$account_players->orderBy('group_id', POT::ORDER_DESC); | ||||||
| 	$twig->display('admin.changelog.form.html.twig', array( | 	$twig->display('admin.changelog.form.html.twig', array( | ||||||
| 		'action' => $action, | 		'action' => $action, | ||||||
| 		'cl_link_form' => constant('ADMIN_URL').'?p=changelog&action=' . ($action == 'edit' ? 'edit' : 'new'), | 		'cl_link_form' => constant('ADMIN_URL').'?p=changelog', | ||||||
| 		'cl_id' => $id ?? null, | 		'cl_id' => $id ?? null, | ||||||
| 		'body' => isset($body) ? escapeHtml($body) : '', | 		'body' => isset($body) ? escapeHtml($body) : '', | ||||||
| 		'create_date' => $create_date ?? '', | 		'create_date' => $create_date ?? '', | ||||||
| @@ -128,15 +129,3 @@ if($action == 'edit' || $action == 'new') { | |||||||
| $twig->display('admin.changelog.html.twig', array( | $twig->display('admin.changelog.html.twig', array( | ||||||
| 	'changelogs' => $changelogs, | 	'changelogs' => $changelogs, | ||||||
| )); | )); | ||||||
|  |  | ||||||
| ?> |  | ||||||
| <script> |  | ||||||
| 	$(document).ready(function () { |  | ||||||
| 		$('#createdate').datetimepicker({format: "M d Y, H:i:s",}); |  | ||||||
|  |  | ||||||
| 		$('.tb_datatable').DataTable({ |  | ||||||
| 			"order": [[0, "desc"]], |  | ||||||
| 			"columnDefs": [{targets: [1, 2,4,5],orderable: false}] |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| </script> |  | ||||||
|   | |||||||
| @@ -10,7 +10,9 @@ | |||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Dashboard'; | $title = 'Dashboard'; | ||||||
|  |  | ||||||
| if (isset($_GET['clear_cache'])) { | csrfProtect(); | ||||||
|  |  | ||||||
|  | if (isset($_POST['clear_cache'])) { | ||||||
| 	if (clearCache()) { | 	if (clearCache()) { | ||||||
| 		success('Cache cleared.'); | 		success('Cache cleared.'); | ||||||
| 	} else { | 	} else { | ||||||
| @@ -18,7 +20,7 @@ if (isset($_GET['clear_cache'])) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| if (isset($_GET['maintenance'])) { | if (isset($_POST['maintenance'])) { | ||||||
| 	$message = (!empty($_POST['message']) ? $_POST['message'] : null); | 	$message = (!empty($_POST['message']) ? $_POST['message'] : null); | ||||||
| 	$_status = (isset($_POST['status']) && $_POST['status'] == 'true'); | 	$_status = (isset($_POST['status']) && $_POST['status'] == 'true'); | ||||||
| 	$_status = ($_status ? '0' : '1'); | 	$_status = ($_status ? '0' : '1'); | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ | |||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Login'; | $title = 'Login'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| require PAGES . 'account/login.php'; | require PAGES . 'account/login.php'; | ||||||
| if ($logged) { | if ($logged) { | ||||||
| 	header('Location: ' . (admin() ? ADMIN_URL : BASE_URL)); | 	header('Location: ' . (admin() ? ADMIN_URL : BASE_URL)); | ||||||
|   | |||||||
| @@ -7,9 +7,14 @@ | |||||||
|  * @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'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) { | ||||||
| 	echo 'Access denied.'; | 	echo 'Access denied.'; | ||||||
| 	return; | 	return; | ||||||
| @@ -20,7 +25,7 @@ if (!setting('core.mail_enabled')) { | |||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| $mail_to = isset($_REQUEST['mail_to']) ? stripslashes(trim($_REQUEST['mail_to'])) : null; | $mail_to = isset($_POST['mail_to']) ? stripslashes(trim($_POST['mail_to'])) : null; | ||||||
| $mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null; | $mail_subject = isset($_POST['mail_subject']) ? stripslashes($_POST['mail_subject']) : null; | ||||||
| $mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null; | $mail_content = isset($_POST['mail_content']) ? stripslashes($_POST['mail_content']) : null; | ||||||
|  |  | ||||||
| @@ -59,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'); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,26 +16,21 @@ defined('MYAAC') or die('Direct access not allowed!'); | |||||||
|  |  | ||||||
| $title = 'Mass Account Actions'; | $title = 'Mass Account Actions'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| $hasCoinsColumn = $db->hasColumn('accounts', 'coins'); | $hasCoinsColumn = $db->hasColumn('accounts', 'coins'); | ||||||
| $hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); | $hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); | ||||||
| $freePremium = $config['lua']['freePremium']; | $freePremium = $config['lua']['freePremium']; | ||||||
|  |  | ||||||
| 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; | ||||||
| @@ -45,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.'); | ||||||
| @@ -60,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; | ||||||
| @@ -92,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 { | ||||||
| @@ -112,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 { | ||||||
| @@ -140,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 { | ||||||
| @@ -160,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.'); | ||||||
|   | |||||||
| @@ -16,6 +16,8 @@ defined('MYAAC') or die('Direct access not allowed!'); | |||||||
|  |  | ||||||
| $title = 'Mass Teleport Actions'; | $title = 'Mass Teleport Actions'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| function admin_teleport_position($x, $y, $z) { | function admin_teleport_position($x, $y, $z) { | ||||||
| 	if (!Player::query()->update([ | 	if (!Player::query()->update([ | ||||||
| 		'posx' => $x, 'posy' => $y, 'posz' => $z | 		'posx' => $x, 'posy' => $y, 'posz' => $z | ||||||
| @@ -38,9 +40,9 @@ function admin_teleport_town($town_id) { | |||||||
| 	displayMessage('Player\'s town updated.', true); | 	displayMessage('Player\'s town updated.', true); | ||||||
| } | } | ||||||
|  |  | ||||||
| if (isset($_POST['action']) && $_POST['action'])    { | if (!empty(ACTION) && isRequestMethod('post'))    { | ||||||
|  |  | ||||||
| 	$action = $_POST['action']; | 	$action = ACTION; | ||||||
|  |  | ||||||
| 	if (preg_match("/[^A-z0-9_\-]/", $action)) { | 	if (preg_match("/[^A-z0-9_\-]/", $action)) { | ||||||
| 		displayMessage('Invalid action.'); | 		displayMessage('Invalid action.'); | ||||||
|   | |||||||
| @@ -8,24 +8,27 @@ | |||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\Cache\Cache; | ||||||
| use MyAAC\Models\Menu; | use MyAAC\Models\Menu; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Menus'; | $title = 'Menus'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) { | ||||||
| 	echo 'Access denied.'; | 	echo 'Access denied.'; | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| if (isset($_REQUEST['template'])) { | if (isset($_POST['template'])) { | ||||||
| 	$template = $_REQUEST['template']; | 	$template = $_POST['template']; | ||||||
|  |  | ||||||
| 	if (isset($_REQUEST['menu'])) { | 	if (isset($_POST['menu'])) { | ||||||
| 		$post_menu = $_REQUEST['menu']; | 		$post_menu = $_POST['menu']; | ||||||
| 		$post_menu_link = $_REQUEST['menu_link']; | 		$post_menu_link = $_POST['menu_link']; | ||||||
| 		$post_menu_blank = $_REQUEST['menu_blank']; | 		$post_menu_blank = $_POST['menu_blank']; | ||||||
| 		$post_menu_color = $_REQUEST['menu_color']; | 		$post_menu_color = $_POST['menu_color']; | ||||||
| 		if (count($post_menu) != count($post_menu_link)) { | 		if (count($post_menu) != count($post_menu_link)) { | ||||||
| 			echo 'Menu count is not equal menu links. Something went wrong when sending form.'; | 			echo 'Menu count is not equal menu links. Something went wrong when sending form.'; | ||||||
| 			return; | 			return; | ||||||
| @@ -69,9 +72,10 @@ if (isset($_REQUEST['template'])) { | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (isset($_REQUEST['reset_colors'])) { | 	if (isset($_GET['reset_colors'])) { | ||||||
| 		if (isset($config['menu_default_color'])) { | 		if (isset($config['menu_default_color'])) { | ||||||
| 			Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]); | 			Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]); | ||||||
|  | 			success('Colors has been reset.'); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			warning('There is no default color defined, cannot reset colors.'); | 			warning('There is no default color defined, cannot reset colors.'); | ||||||
| @@ -93,6 +97,7 @@ if (isset($_REQUEST['template'])) { | |||||||
| 		</p> | 		</p> | ||||||
| 		<?php if (isset($config['menu_default_color'])) {?> | 		<?php if (isset($config['menu_default_color'])) {?> | ||||||
| 		<form method="post" action="?p=menus&reset_colors" onsubmit="return confirm('Do you really want to reset colors?');"> | 		<form method="post" action="?p=menus&reset_colors" onsubmit="return confirm('Do you really want to reset colors?');"> | ||||||
|  | 			<?php csrf(); ?> | ||||||
| 			<input type="hidden" name="template" value="<?php echo $template ?>"/> | 			<input type="hidden" name="template" value="<?php echo $template ?>"/> | ||||||
| 			<button type="submit" class="btn btn-danger">Reset Colors to default</button> | 			<button type="submit" class="btn btn-danger">Reset Colors to default</button> | ||||||
| 		</form> | 		</form> | ||||||
| @@ -112,6 +117,7 @@ if (isset($_REQUEST['template'])) { | |||||||
| 	$last_id = array(); | 	$last_id = array(); | ||||||
| 	?> | 	?> | ||||||
| 	<form method="post" id="menus-form" action="?p=menus"> | 	<form method="post" id="menus-form" action="?p=menus"> | ||||||
|  | 		<?php csrf(); ?> | ||||||
| 		<input type="hidden" name="template" value="<?php echo $template ?>"/> | 		<input type="hidden" name="template" value="<?php echo $template ?>"/> | ||||||
| 		<button type="submit" class="btn btn-info">Save</button><br/><br/> | 		<button type="submit" class="btn btn-info">Save</button><br/><br/> | ||||||
| 		<div class="row"> | 		<div class="row"> | ||||||
|   | |||||||
| @@ -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( | ||||||
|   | |||||||
| @@ -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 %} | ||||||
|   | |||||||
| @@ -1,28 +1,32 @@ | |||||||
| <div class="col-12 col-md-6"> | <div class="col-12 col-md-6"> | ||||||
| 	<div class="card card-warning card-outline"> | 	<div class="card card-warning card-outline"> | ||||||
| 		<form action="?p=dashboard&maintenance" method="post" class="form-horizontal"> | 		<div class="card-header"> | ||||||
| 			<div class="card-header"> | 			<span class="m-0">Website Status<span class="float-right"> | ||||||
| 				<span class="m-0">Website Status<span class="float-right"> | 			<div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success"> | ||||||
| 				<div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success"> | 				<input form="maintenance-form" type="checkbox" class="custom-control-input" name="status" id="status" value="true" {% if not is_closed %} checked{% endif %}> | ||||||
| 					<input type="checkbox" class="custom-control-input" name="status" id="status" value="true" {% if not is_closed %} checked{% endif %}> | 				<label id="status-label" class="custom-control-label" for="status"> {% if is_closed %}Closed{% else %}Open{% endif %}</label> | ||||||
| 					<label id="status-label" class="custom-control-label" for="status"> {% if is_closed %}Closed{% else %}Open{% endif %}</label> | 			</div></span> | ||||||
| 				</div></span> | 			</span> | ||||||
| 				</span> | 		</div> | ||||||
|  | 		<div class="card-body p-2"> | ||||||
|  | 			<div class="col-sm-12"> | ||||||
|  | 				<label for="message" class="col-form-label">Maintenance Message</label> | ||||||
|  | 				<textarea form="maintenance-form" name="message" class="form-control" cols="40" rows="3" maxlength="255" placeholder="Enter ...">{{ closed_message }}</textarea> | ||||||
|  | 				<small>(only visible if closed)</small> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div class="card-body p-2"> | 		</div> | ||||||
| 				<div class="col-sm-12"> | 		<div class="card-footer"> | ||||||
| 					<label for="message" class="col-form-label">Maintenance Message</label> | 			<form id="maintenance-form" method="post" action="?p=dashboard" class="float-left"> | ||||||
| 					<textarea name="message" class="form-control" cols="40" rows="3" maxlength="255" placeholder="Enter ...">{{ closed_message }}</textarea> | 				{{ csrf() }} | ||||||
| 					<small>(only visible if closed)</small> | 				<input type="hidden" name="maintenance" value="1" /> | ||||||
| 				</div> |  | ||||||
| 			</div> |  | ||||||
| 			<div class="card-footer"> |  | ||||||
| 				<button type="submit" class="btn btn-info"><i class="far fa-update"></i> Update</button> | 				<button type="submit" class="btn btn-info"><i class="far fa-update"></i> Update</button> | ||||||
| 				<a href="?p=dashboard&clear_cache" onclick="return confirm('Are you sure?');" class="float-right"> | 			</form> | ||||||
| 					<span class="btn btn-danger"><i class="fas fa-clear"></i>Clear cache</span> | 			<form method="post" action="?p=dashboard" class="float-right"> | ||||||
| 				</a> | 				{{ csrf() }} | ||||||
| 			</div> | 				<input type="hidden" name="clear_cache" value="1" /> | ||||||
| 		</form> | 				<button type="submit" onclick="return confirm('Are you sure that you want to clear cache?');" class="btn btn-danger" title="Clear Cache"><i class="fas fa-clear"></i>Clear cache</button> | ||||||
|  | 			</form> | ||||||
|  | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,12 +7,16 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\Forum; | ||||||
|  | use MyAAC\News; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
| require_once LIBS . 'forum.php'; |  | ||||||
| require_once LIBS . 'news.php'; |  | ||||||
|  |  | ||||||
| $title = 'News Panel'; | $title = 'News Panel'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| $use_datatable = true; | $use_datatable = true; | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | ||||||
| @@ -22,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; | ||||||
| @@ -31,73 +35,71 @@ const ARTICLE_IMAGE_LIMIT = 100; | |||||||
| $name = $p_title = ''; | $name = $p_title = ''; | ||||||
| if(!empty($action)) | if(!empty($action)) | ||||||
| { | { | ||||||
| 	$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null; | 	$id = $_POST['id'] ?? null; | ||||||
| 	$p_title = isset($_REQUEST['title']) ? $_REQUEST['title'] : null; | 	$p_title = $_POST['title'] ?? null; | ||||||
| 	$body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null; | 	$body = isset($_POST['body']) ? stripslashes($_POST['body']) : null; | ||||||
| 	$comments = isset($_REQUEST['comments']) ? $_REQUEST['comments'] : null; | 	$comments = $_POST['comments'] ?? null; | ||||||
| 	$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null; | 	$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : 1; | ||||||
| 	$category = isset($_REQUEST['category']) ? (int)$_REQUEST['category'] : null; | 	$category = isset($_POST['category']) ? (int)$_POST['category'] : null; | ||||||
| 	$player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null; | 	$player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : null; | ||||||
| 	$article_text = isset($_REQUEST['article_text']) ? $_REQUEST['article_text'] : null; | 	$article_text = $_POST['article_text'] ?? null; | ||||||
| 	$article_image = isset($_REQUEST['article_image']) ? $_REQUEST['article_image'] : null; | 	$article_image = $_POST['article_image'] ?? null; | ||||||
| 	$forum_section = isset($_REQUEST['forum_section']) ? $_REQUEST['forum_section'] : null; | 	$forum_section = $_POST['forum_section'] ?? null; | ||||||
| 	$errors = array(); | 	$errors = []; | ||||||
|  |  | ||||||
| 	if($action == 'new') { | 	if (isRequestMethod('post')) { | ||||||
| 		if(isset($forum_section) && $forum_section != '-1') { | 		if ($action == 'new') { | ||||||
| 			$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors); | 			if (isset($forum_section) && $forum_section != '-1') { | ||||||
| 		} | 				$forum_add = Forum::add_thread($p_title, $body, $forum_section, $player_id, $account_logged->getId(), $errors); | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 		if(isset($p_title) && News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) { | 			if (isset($p_title) && News::add($p_title, $body, $type, $category, $player_id, isset($forum_add) && $forum_add != 0 ? $forum_add : 0, $article_text, $article_image, $errors)) { | ||||||
| 			$p_title = $body = $comments = $article_text = $article_image = ''; | 				$p_title = $body = $comments = $article_text = $article_image = ''; | ||||||
| 			$type = $category = $player_id = 0; |  | ||||||
|  |  | ||||||
| 			success('Added successful.'); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else if($action == 'delete') { |  | ||||||
| 		if (News::delete($id, $errors)) { |  | ||||||
| 			success('Deleted successful.'); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else if($action == 'edit') |  | ||||||
| 	{ |  | ||||||
| 		if(isset($id) && !isset($p_title)) { |  | ||||||
| 			$news = News::get($id); |  | ||||||
| 			$p_title = $news['title']; |  | ||||||
| 			$body = $news['body']; |  | ||||||
| 			$comments = $news['comments']; |  | ||||||
| 			$type = $news['type']; |  | ||||||
| 			$category = $news['category']; |  | ||||||
| 			$player_id = $news['player_id']; |  | ||||||
| 			$article_text = $news['article_text']; |  | ||||||
| 			$article_image = $news['article_image']; |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			if(News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) { |  | ||||||
| 				// update forum thread if exists |  | ||||||
| 				if(isset($forum_section) && Validator::number($forum_section)) { |  | ||||||
| 					$db->query("UPDATE `" . TABLE_PREFIX . "forum` SET `author_guid` = ".(int) $player_id.", `post_text` = ".$db->quote($body).", `post_topic` = ".$db->quote($p_title).", `edit_date` = " . time() . " WHERE `id` = " . $db->quote($forum_section)); |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				$action = $p_title = $body = $comments = $article_text = $article_image = ''; |  | ||||||
| 				$type = $category = $player_id = 0; | 				$type = $category = $player_id = 0; | ||||||
|  |  | ||||||
| 				success('Updated successful.'); | 				success('Added successful.'); | ||||||
|  | 			} | ||||||
|  | 		} else if ($action == 'delete') { | ||||||
|  | 			if (News::delete($id, $errors)) { | ||||||
|  | 				success('Deleted successful.'); | ||||||
|  | 			} | ||||||
|  | 		} else if ($action == 'edit') { | ||||||
|  | 			if (isset($id) && !isset($p_title)) { | ||||||
|  | 				$news = News::get($id); | ||||||
|  | 				$p_title = $news['title']; | ||||||
|  | 				$body = $news['body']; | ||||||
|  | 				$comments = $news['comments']; | ||||||
|  | 				$type = $news['type']; | ||||||
|  | 				$category = $news['category']; | ||||||
|  | 				$player_id = $news['player_id']; | ||||||
|  | 				$article_text = $news['article_text']; | ||||||
|  | 				$article_image = $news['article_image']; | ||||||
|  | 			} else { | ||||||
|  | 				if (News::update($id, $p_title, $body, $type, $category, $player_id, $forum_section, $article_text, $article_image, $errors)) { | ||||||
|  | 					// update forum thread if exists | ||||||
|  | 					if (isset($forum_section) && Validator::number($forum_section)) { | ||||||
|  | 						$db->query("UPDATE `" . TABLE_PREFIX . "forum` SET `author_guid` = " . (int)$player_id . ", `post_text` = " . $db->quote($body) . ", `post_topic` = " . $db->quote($p_title) . ", `edit_date` = " . time() . " WHERE `id` = " . $db->quote($forum_section)); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					$action = $p_title = $body = $comments = $article_text = $article_image = ''; | ||||||
|  | 					$type = $category = $player_id = 0; | ||||||
|  |  | ||||||
|  | 					success('Updated successful.'); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} else if ($action == 'hide') { | ||||||
|  | 			if (News::toggleHide($id, $errors, $status)) { | ||||||
|  | 				success(($status == 1 ? 'Hide' : 'Show') . ' successful.'); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else if($action == 'hide') { |  | ||||||
| 		News::toggleHidden($id, $errors, $status); |  | ||||||
| 		success(($status == 1 ? 'Show' : 'Hide') . " successful."); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if(!empty($errors)) | 	if(!empty($errors)) | ||||||
| 		error(implode(", ", $errors)); | 		error(implode(", ", $errors)); | ||||||
| } | } | ||||||
|  |  | ||||||
| $categories = array(); | $categories = array(); | ||||||
| foreach($db->query('SELECT `id`, `name`, `icon_id` FROM `' . TABLE_PREFIX . 'news_categories` WHERE `hidden` != 1') as $cat) | foreach($db->query('SELECT `id`, `name`, `icon_id` FROM `' . TABLE_PREFIX . 'news_categories` WHERE `hide` != 1') as $cat) | ||||||
| { | { | ||||||
| 	$categories[$cat['id']] = array( | 	$categories[$cat['id']] = array( | ||||||
| 		'name' => $cat['name'], | 		'name' => $cat['name'], | ||||||
| @@ -115,12 +117,10 @@ if($action == 'edit' || $action == 'new') { | |||||||
| 	$account_players->orderBy('group_id', POT::ORDER_DESC); | 	$account_players->orderBy('group_id', POT::ORDER_DESC); | ||||||
| 	$twig->display('admin.news.form.html.twig', array( | 	$twig->display('admin.news.form.html.twig', array( | ||||||
| 		'action' => $action, | 		'action' => $action, | ||||||
| 		'news_link' => getLink(PAGE), |  | ||||||
| 		'news_link_form' => '?p=news&action=' . ($action == 'edit' ? 'edit' : 'new'), |  | ||||||
| 		'news_id' => $id ?? null, | 		'news_id' => $id ?? null, | ||||||
| 		'title' => $p_title ?? '', | 		'title' => $p_title ?? '', | ||||||
| 		'body' => isset($body) ? escapeHtml($body) : '', | 		'body' => isset($body) ? escapeHtml($body) : '', | ||||||
| 		'type' => $type ?? null, | 		'type' => $type, | ||||||
| 		'player' => isset($player) && $player->isLoaded() ? $player : null, | 		'player' => isset($player) && $player->isLoaded() ? $player : null, | ||||||
| 		'player_id' => $player_id ?? null, | 		'player_id' => $player_id ?? null, | ||||||
| 		'account_players' => $account_players, | 		'account_players' => $account_players, | ||||||
| @@ -136,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) { | ||||||
| 	$_player = new OTS_Player(); | 	$playerId = $_news['player_id']; | ||||||
| 	$_player->load($_news['player_id']); | 	if (isset($cachePlayers[$playerId])) { | ||||||
|  | 		$_player = $cachePlayers[$playerId]; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		$_player = new OTS_Player(); | ||||||
|  | 		$_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) : '', | ||||||
| 	); | 	); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,8 +13,10 @@ use MyAAC\Models\Notepad as ModelsNotepad; | |||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Notepad'; | $title = 'Notepad'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @var $account_logged OTS_Account |  * @var OTS_Account $account_logged | ||||||
|  */ |  */ | ||||||
| $_content = ''; | $_content = ''; | ||||||
| $notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first(); | $notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first(); | ||||||
|   | |||||||
| @@ -9,11 +9,14 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Models\Pages as ModelsPages; | use MyAAC\Models\Pages as ModelsPages; | ||||||
|  | use MyAAC\Admin\Pages; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Pages'; | $title = 'Pages'; | ||||||
| $use_datatable = true; | $use_datatable = true; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { | ||||||
| 	echo 'Access denied.'; | 	echo 'Access denied.'; | ||||||
| 	return; | 	return; | ||||||
| @@ -29,31 +32,36 @@ $enable_tinymce = true; | |||||||
| $access = 0; | $access = 0; | ||||||
|  |  | ||||||
| // some constants, used mainly by database (cannot by modified without schema changes) | // some constants, used mainly by database (cannot by modified without schema changes) | ||||||
| define('PAGE_TITLE_LIMIT', 30); | const PAGE_TITLE_LIMIT = 30; | ||||||
| define('PAGE_NAME_LIMIT', 30); | const PAGE_NAME_LIMIT = 30; | ||||||
| define('PAGE_BODY_LIMIT', 65535); // maximum page body length | const PAGE_BODY_LIMIT = 65535; // maximum page body length | ||||||
|  |  | ||||||
| if (!empty($action)) { | if (!empty($action) && isRequestMethod('post')) { | ||||||
| 	if ($action == 'delete' || $action == 'edit' || $action == 'hide') | 	if ($action == 'delete' || $action == 'edit' || $action == 'hide') { | ||||||
| 		$id = $_REQUEST['id']; | 		$id = $_POST['id']; | ||||||
|  |  | ||||||
| 	if (isset($_REQUEST['name'])) |  | ||||||
| 		$name = $_REQUEST['name']; |  | ||||||
|  |  | ||||||
| 	if (isset($_REQUEST['title'])) |  | ||||||
| 		$p_title = $_REQUEST['title']; |  | ||||||
|  |  | ||||||
| 	$php = isset($_REQUEST['php']) && $_REQUEST['php'] == 1; |  | ||||||
| 	$enable_tinymce = isset($_REQUEST['enable_tinymce']) && $_REQUEST['enable_tinymce'] == 1; |  | ||||||
| 	if ($php) |  | ||||||
| 		$body = $_REQUEST['body']; |  | ||||||
| 	else if (isset($_REQUEST['body'])) { |  | ||||||
| 		//$body = $_REQUEST['body']; |  | ||||||
| 		$body = html_entity_decode(stripslashes($_REQUEST['body'])); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (isset($_REQUEST['access'])) | 	if (isset($_POST['name'])) { | ||||||
| 		$access = $_REQUEST['access']; | 		$name = $_POST['name']; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (isset($_POST['title'])) { | ||||||
|  | 		$p_title = $_POST['title']; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$php = isset($_POST['php']) && $_POST['php'] == 1; | ||||||
|  | 	$enable_tinymce = (isset($_POST['enable_tinymce']) && $_POST['enable_tinymce'] == 1) ?: $enable_tinymce; | ||||||
|  | 	if ($php) { | ||||||
|  | 		$body = $_POST['body']; | ||||||
|  | 	} | ||||||
|  | 	else if (isset($_POST['body'])) { | ||||||
|  | 		//$body = $_POST['body']; | ||||||
|  | 		$body = html_entity_decode(stripslashes($_POST['body'])); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (isset($_POST['access'])) { | ||||||
|  | 		$access = $_POST['access']; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	$errors = array(); | 	$errors = array(); | ||||||
| 	$player_id = 1; | 	$player_id = 1; | ||||||
| @@ -70,7 +78,7 @@ if (!empty($action)) { | |||||||
| 		if (Pages::delete($id, $errors)) | 		if (Pages::delete($id, $errors)) | ||||||
| 			success('Page with id ' . $id . ' has been deleted'); | 			success('Page with id ' . $id . ' has been deleted'); | ||||||
| 	} else if ($action == 'edit') { | 	} else if ($action == 'edit') { | ||||||
| 		if (isset($id) && !isset($_REQUEST['name'])) { | 		if (isset($id) && !isset($_POST['name'])) { | ||||||
| 			$_page = Pages::get($id); | 			$_page = Pages::get($id); | ||||||
| 			$name = $_page['name']; | 			$name = $_page['name']; | ||||||
| 			$p_title = $_page['title']; | 			$p_title = $_page['title']; | ||||||
| @@ -89,8 +97,9 @@ if (!empty($action)) { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} else if ($action == 'hide') { | 	} else if ($action == 'hide') { | ||||||
| 		Pages::toggleHidden($id, $errors, $status); | 		if (Pages::toggleHide($id, $errors, $status)) { | ||||||
| 		success(($status == 1 ? 'Show' : 'Hide') . ' successful.'); | 			success(($status == 0 ? 'Show' : 'Hide') . ' successful.'); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!empty($errors)) | 	if (!empty($errors)) | ||||||
| @@ -103,11 +112,11 @@ $pages = ModelsPages::all()->map(function ($e) { | |||||||
| 		'title' => substr($e->title, 0, 20), | 		'title' => substr($e->title, 0, 20), | ||||||
| 		'php' => $e->php == '1', | 		'php' => $e->php == '1', | ||||||
| 		'id' => $e->id, | 		'id' => $e->id, | ||||||
| 		'hidden' => $e->hidden | 		'hide' => $e->hide | ||||||
| 	]; | 	]; | ||||||
| })->toArray(); | })->toArray(); | ||||||
|  |  | ||||||
| $twig->display('admin.pages.form.html.twig', array( | $twig->display('admin.pages.form.html.twig', [ | ||||||
| 	'action' => $action, | 	'action' => $action, | ||||||
| 	'id' => $action == 'edit' ? $id : null, | 	'id' => $action == 'edit' ? $id : null, | ||||||
| 	'name' => $name, | 	'name' => $name, | ||||||
| @@ -117,136 +126,8 @@ $twig->display('admin.pages.form.html.twig', array( | |||||||
| 	'body' => isset($body) ? escapeHtml($body) : '', | 	'body' => isset($body) ? escapeHtml($body) : '', | ||||||
| 	'groups' => $groups->getGroups(), | 	'groups' => $groups->getGroups(), | ||||||
| 	'access' => $access | 	'access' => $access | ||||||
| )); | ]); | ||||||
|  |  | ||||||
| $twig->display('admin.pages.html.twig', array( | $twig->display('admin.pages.html.twig', [ | ||||||
| 	'pages' => $pages | 	'pages' => $pages | ||||||
| )); | ]); | ||||||
|  |  | ||||||
| class Pages |  | ||||||
| { |  | ||||||
| 	static public function verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors) |  | ||||||
| 	{ |  | ||||||
| 		if(!isset($title[0]) || !isset($body[0])) { |  | ||||||
| 			$errors[] = 'Please fill all inputs.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		if(strlen($name) > PAGE_NAME_LIMIT) { |  | ||||||
| 			$errors[] = 'Page name cannot be longer than ' . PAGE_NAME_LIMIT . ' characters.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		if(strlen($title) > PAGE_TITLE_LIMIT) { |  | ||||||
| 			$errors[] = 'Page title cannot be longer than ' . PAGE_TITLE_LIMIT . ' characters.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		if(strlen($body) > PAGE_BODY_LIMIT) { |  | ||||||
| 			$errors[] = 'Page content cannot be longer than ' . PAGE_BODY_LIMIT . ' characters.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		if(!isset($player_id) || $player_id == 0) { |  | ||||||
| 			$errors[] = 'Player ID is wrong.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		if(!isset($php) || ($php != 0 && $php != 1)) { |  | ||||||
| 			$errors[] = 'Enable PHP is wrong.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		if ($php == 1 && !getBoolean(setting('core.admin_pages_php_enable'))) { |  | ||||||
| 			$errors[] = 'PHP pages disabled on this server. To enable go to Settings in Admin Panel and enable <strong>Enable PHP Pages</strong>.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		if(!isset($enable_tinymce) || ($enable_tinymce != 0 && $enable_tinymce != 1)) { |  | ||||||
| 			$errors[] = 'Enable TinyMCE is wrong.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		if(!isset($access) || $access < 0 || $access > PHP_INT_MAX) { |  | ||||||
| 			$errors[] = 'Access is wrong.'; |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return true; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	static public function get($id) |  | ||||||
| 	{ |  | ||||||
| 		$row = ModelsPages::find($id); |  | ||||||
| 		if ($row) { |  | ||||||
| 			return $row->toArray(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	static public function add($name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors) |  | ||||||
| 	{ |  | ||||||
| 		if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (!ModelsPages::where('name', $name)->exists()) |  | ||||||
| 			ModelsPages::create([ |  | ||||||
| 				'name' => $name, |  | ||||||
| 				'title' => $title, |  | ||||||
| 				'body' => $body, |  | ||||||
| 				'player_id' => $player_id, |  | ||||||
| 				'php' => $php ? '1' : '0', |  | ||||||
| 				'enable_tinymce' => $enable_tinymce ? '1' : '0', |  | ||||||
| 				'access' => $access |  | ||||||
| 			]); |  | ||||||
| 		else |  | ||||||
| 			$errors[] = 'Page with this link already exists.'; |  | ||||||
|  |  | ||||||
| 		return !count($errors); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	static public function update($id, $name, $title, $body, $player_id, $php, $enable_tinymce, $access, &$errors) |  | ||||||
| 	{ |  | ||||||
| 		if(!self::verify($name, $title, $body, $player_id, $php, $enable_tinymce, $access, $errors)) { |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		ModelsPages::where('id', $id)->update([ |  | ||||||
| 			'name' => $name, |  | ||||||
| 			'title' => $title, |  | ||||||
| 			'body' => $body, |  | ||||||
| 			'player_id' => $player_id, |  | ||||||
| 			'php' => $php ? '1' : '0', |  | ||||||
| 			'enable_tinymce' => $enable_tinymce ? '1' : '0', |  | ||||||
| 			'access' => $access |  | ||||||
| 		]); |  | ||||||
| 		return true; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	static public function delete($id, &$errors) |  | ||||||
| 	{ |  | ||||||
| 		if (isset($id)) { |  | ||||||
| 			$row = ModelsPages::find($id); |  | ||||||
| 			if ($row) { |  | ||||||
| 				$row->delete(); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 				$errors[] = 'Page with id ' . $id . ' does not exists.'; |  | ||||||
| 		} else |  | ||||||
| 			$errors[] = 'id not set'; |  | ||||||
|  |  | ||||||
| 		return !count($errors); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	static public function toggleHidden($id, &$errors, &$status) |  | ||||||
| 	{ |  | ||||||
| 		if (isset($id)) { |  | ||||||
| 			$row = ModelsPages::find($id); |  | ||||||
| 			if ($row) { |  | ||||||
| 				$row->hidden = $row->hidden == 1 ? 0 : 1; |  | ||||||
| 				$row->save(); |  | ||||||
| 				$status = $row->hidden; |  | ||||||
| 			} |  | ||||||
| 			else { |  | ||||||
| 				$errors[] = 'Page with id ' . $id . ' does not exists.'; |  | ||||||
| 			} |  | ||||||
| 		} else |  | ||||||
| 			$errors[] = 'id not set'; |  | ||||||
|  |  | ||||||
| 		return !count($errors); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -8,15 +8,18 @@ | |||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\Forum; | ||||||
| use MyAAC\Models\Player; | use MyAAC\Models\Player; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
| $title = 'Player editor'; | $title = 'Player editor'; | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| $player_base = ADMIN_URL . '?p=players'; | $player_base = ADMIN_URL . '?p=players'; | ||||||
|  |  | ||||||
| $use_datatable = true; | $use_datatable = true; | ||||||
| require_once LIBS . 'forum.php'; |  | ||||||
|  |  | ||||||
| $skills = array( | $skills = array( | ||||||
| 	POT::SKILL_FIST => array('Fist fighting', 'fist'), | 	POT::SKILL_FIST => array('Fist fighting', 'fist'), | ||||||
| @@ -48,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 . '%')); | 			$str_construct = 'Do you mean?<ul>'; | ||||||
| 			if ($query->rowCount() > 0 && $query->rowCount() <= 10) { | 			foreach ($query as $row) { | ||||||
| 				$str_construct = 'Do you mean?<ul>'; | 				$str_construct .= '<li><a href="' . $player_base . '&id=' . $row->getKey() . '">' . $row->name . '</a></li>'; | ||||||
| 				foreach ($query as $row) | 			} | ||||||
| 					$str_construct .= '<li><a href="' . $player_base . '&id=' . $row['id'] . '">' . $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.'); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -75,7 +76,7 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 		$player = new OTS_Player(); | 		$player = new OTS_Player(); | ||||||
| 		$player->load($id); | 		$player->load($id); | ||||||
|  |  | ||||||
| 		if (isset($player) && $player->isLoaded() && isset($_POST['save'])) {// we want to save | 		if ($player->isLoaded() && isset($_POST['save'])) {// we want to save | ||||||
| 			$error = false; | 			$error = false; | ||||||
|  |  | ||||||
| 			if ($player->isOnline()) | 			if ($player->isOnline()) | ||||||
| @@ -199,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']; | ||||||
| @@ -210,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); | ||||||
| @@ -271,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) { | ||||||
| @@ -287,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); | ||||||
| @@ -304,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"> | ||||||
| @@ -324,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> | ||||||
| @@ -372,7 +373,8 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 						</li> | 						</li> | ||||||
| 					</ul> | 					</ul> | ||||||
| 				</div> | 				</div> | ||||||
| 				<form action="<?php echo $player_base . ((isset($id) && $id > 0) ? '&id=' . $id : ''); ?>" method="post"> | 				<form action="<?php echo $player_base . ($id > 0 ? '&id=' . $id : ''); ?>" method="post"> | ||||||
|  | 					<?php csrf(); ?> | ||||||
| 					<div class="card-body"> | 					<div class="card-body"> | ||||||
| 						<div class="tab-content" id="tabs-tabContent"> | 						<div class="tab-content" id="tabs-tabContent"> | ||||||
| 							<div class="tab-pane fade active show" id="tabs-home"> | 							<div class="tab-pane fade active show" id="tabs-home"> | ||||||
| @@ -481,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> | ||||||
| @@ -870,6 +872,7 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 			<div class="card-body row"> | 			<div class="card-body row"> | ||||||
| 				<div class="col-6 col-lg-12"> | 				<div class="col-6 col-lg-12"> | ||||||
| 					<form action="<?php echo $player_base; ?>" method="post"> | 					<form action="<?php echo $player_base; ?>" method="post"> | ||||||
|  | 						<?php csrf(); ?> | ||||||
| 						<label for="search">Player Name:</label> | 						<label for="search">Player Name:</label> | ||||||
| 						<div class="input-group input-group-sm"> | 						<div class="input-group input-group-sm"> | ||||||
| 							<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_player); ?>" maxlength="32" size="32"> | 							<input type="text" class="form-control" id="search" name="search" value="<?= escapeHtml($search_player); ?>" maxlength="32" size="32"> | ||||||
| @@ -879,6 +882,7 @@ else if (isset($_REQUEST['search'])) { | |||||||
| 				</div> | 				</div> | ||||||
| 				<div class="col-6 col-lg-12"> | 				<div class="col-6 col-lg-12"> | ||||||
| 					<form action="<?php echo $player_base; ?>" method="post"> | 					<form action="<?php echo $player_base; ?>" method="post"> | ||||||
|  | 						<?php csrf(); ?> | ||||||
| 						<label for="id">Player ID:</label> | 						<label for="id">Player ID:</label> | ||||||
| 						<div class="input-group input-group-sm"> | 						<div class="input-group input-group-sm"> | ||||||
| 							<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32"> | 							<input type="text" class="form-control" id="id" name="id" value="<?= $id; ?>" maxlength="32" size="32"> | ||||||
|   | |||||||
| @@ -7,35 +7,45 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\Plugins; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Plugin manager'; | $title = 'Plugin manager'; | ||||||
| $use_datatable = true; |  | ||||||
|  |  | ||||||
| require_once LIBS . 'plugins.php'; | csrfProtect(); | ||||||
|  |  | ||||||
|  | $use_datatable = true; | ||||||
|  |  | ||||||
| if (!getBoolean(setting('core.admin_plugins_manage_enable'))) { | if (!getBoolean(setting('core.admin_plugins_manage_enable'))) { | ||||||
| 	warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.'); | 	warning('Plugin installation and management is disabled in Settings.<br/>If you wish to enable, go to Settings and enable <strong>Enable Plugins Manage</strong>.'); | ||||||
| } | } | ||||||
| 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; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (isset($_REQUEST['uninstall'])) { | 	$twig->display('admin.plugins.form.html.twig', ['pluginUploadEnabled' => $pluginUploadEnabled]); | ||||||
| 		$uninstall = $_REQUEST['uninstall']; |  | ||||||
|  | 	if (isset($_POST['uninstall'])) { | ||||||
|  | 		$uninstall = $_POST['uninstall']; | ||||||
|  |  | ||||||
| 		if (Plugins::uninstall($uninstall)) { | 		if (Plugins::uninstall($uninstall)) { | ||||||
| 			success('Successfully uninstalled plugin ' . $uninstall); | 			success('Successfully uninstalled plugin ' . $uninstall); | ||||||
| 		} else { | 		} else { | ||||||
| 			error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); | 			error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); | ||||||
| 		} | 		} | ||||||
| 	} else if (isset($_REQUEST['enable'])) { | 	} else if (isset($_POST['enable'])) { | ||||||
| 		$enable = $_REQUEST['enable']; | 		$enable = $_POST['enable']; | ||||||
| 		if (Plugins::enable($enable)) { | 		if (Plugins::enable($enable)) { | ||||||
| 			success('Successfully enabled plugin ' . $enable); | 			success('Successfully enabled plugin ' . $enable); | ||||||
| 		} else { | 		} else { | ||||||
| 			error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError()); | 			error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError()); | ||||||
| 		} | 		} | ||||||
| 	} else if (isset($_REQUEST['disable'])) { | 	} else if (isset($_POST['disable'])) { | ||||||
| 		$disable = $_REQUEST['disable']; | 		$disable = $_POST['disable']; | ||||||
| 		if (Plugins::disable($disable)) { | 		if (Plugins::disable($disable)) { | ||||||
| 			success('Successfully disabled plugin ' . $disable); | 			success('Successfully disabled plugin ' . $disable); | ||||||
| 		} else { | 		} else { | ||||||
| @@ -116,7 +126,7 @@ foreach (get_plugins(true) as $plugin) { | |||||||
| 	if (!$plugin_info) { | 	if (!$plugin_info) { | ||||||
| 		warning('Cannot load plugin info ' . $plugin . '.json'); | 		warning('Cannot load plugin info ' . $plugin . '.json'); | ||||||
| 	} else { | 	} else { | ||||||
| 		$disabled = (strpos($plugin, 'disabled.') !== false); | 		$disabled = (str_contains($plugin, 'disabled.')); | ||||||
| 		$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin); | 		$pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin); | ||||||
| 		$plugins[] = array( | 		$plugins[] = array( | ||||||
| 			'name' => $plugin_info['name'] ?? '', | 			'name' => $plugin_info['name'] ?? '', | ||||||
|   | |||||||
| @@ -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']); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ defined('MYAAC') or die('Direct access not allowed!'); | |||||||
| use DeviceDetector\DeviceDetector; | use DeviceDetector\DeviceDetector; | ||||||
| use DeviceDetector\Parser\Client\Browser; | use DeviceDetector\Parser\Client\Browser; | ||||||
| use DeviceDetector\Parser\OperatingSystem; | use DeviceDetector\Parser\OperatingSystem; | ||||||
|  | use MyAAC\Visitors; | ||||||
|  |  | ||||||
| $title = 'Visitors'; | $title = 'Visitors'; | ||||||
| $use_datatable = true; | $use_datatable = true; | ||||||
| @@ -24,7 +25,6 @@ if (!setting('core.visitors_counter')): ?> | |||||||
| 	return; | 	return; | ||||||
| endif; | endif; | ||||||
|  |  | ||||||
| require SYSTEM . 'libs/visitors.php'; |  | ||||||
| $visitors = new Visitors(setting('core.visitors_counter_ttl')); | $visitors = new Visitors(setting('core.visitors_counter_ttl')); | ||||||
|  |  | ||||||
| function compare($a, $b): int { | function compare($a, $b): int { | ||||||
|   | |||||||
| @@ -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' | ||||||
|   | |||||||
| @@ -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 */ | ||||||
|   | |||||||
| @@ -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> | ||||||
|   | |||||||
| @@ -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'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,8 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
|  | use MyAAC\Hooks; | ||||||
|  | use MyAAC\Settings; | ||||||
|  |  | ||||||
| const MYAAC_ADMIN = true; | const MYAAC_ADMIN = true; | ||||||
|  |  | ||||||
| require '../../common.php'; | require '../../common.php'; | ||||||
| @@ -6,16 +10,13 @@ require SYSTEM . 'functions.php'; | |||||||
| require SYSTEM . 'init.php'; | require SYSTEM . 'init.php'; | ||||||
| require SYSTEM . 'login.php'; | require SYSTEM . 'login.php'; | ||||||
|  |  | ||||||
| // event system |  | ||||||
| require_once SYSTEM . 'hooks.php'; |  | ||||||
| $hooks = new Hooks(); |  | ||||||
| $hooks->load(); |  | ||||||
|  |  | ||||||
| if(!admin()) { | if(!admin()) { | ||||||
| 	http_response_code(500); | 	http_response_code(500); | ||||||
| 	die('Access denied.'); | 	die('Access denied.'); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | csrfProtect(); | ||||||
|  |  | ||||||
| if (!isset($_REQUEST['plugin'])) { | if (!isset($_REQUEST['plugin'])) { | ||||||
| 	http_response_code(500); | 	http_response_code(500); | ||||||
| 	die('Please enter plugin name.'); | 	die('Please enter plugin name.'); | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								common.php
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								common.php
									
									
									
									
									
								
							| @@ -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 = '0.10.0-dev'; | const MYAAC_VERSION = '1.0-RC.2'; | ||||||
| const DATABASE_VERSION = 36; | const DATABASE_VERSION = 41; | ||||||
| const TABLE_PREFIX = 'myaac_'; | const TABLE_PREFIX = 'myaac_'; | ||||||
| define('START_TIME', microtime(true)); | define('START_TIME', microtime(true)); | ||||||
| define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); | define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); | ||||||
| @@ -108,6 +108,13 @@ const TFS_FIRST = TFS_02; | |||||||
| const TFS_LAST = TFS_03; | const TFS_LAST = TFS_03; | ||||||
|  |  | ||||||
| // other definitions | // other definitions | ||||||
|  | const MAIL_MAIL = 0; | ||||||
|  | const MAIL_SMTP = 1; | ||||||
|  |  | ||||||
|  | const SMTP_SECURITY_NONE = 0; | ||||||
|  | const SMTP_SECURITY_SSL = 1; | ||||||
|  | const SMTP_SECURITY_TLS = 2; | ||||||
|  |  | ||||||
| const ACCOUNT_NUMBER_LENGTH = 8; | const ACCOUNT_NUMBER_LENGTH = 8; | ||||||
|  |  | ||||||
| if (!IS_CLI) { | if (!IS_CLI) { | ||||||
| @@ -149,7 +156,7 @@ if (file_exists(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); | ||||||
|   | |||||||
| @@ -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": "*", | ||||||
| @@ -13,14 +13,20 @@ | |||||||
|         "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.*" | ||||||
|     }, |     }, | ||||||
|     "require-dev": { |     "require-dev": { | ||||||
|         "filp/whoops": "^2.15" |         "phpstan/phpstan": "^1.10" | ||||||
|     }, |     }, | ||||||
|     "autoload": { |     "autoload": { | ||||||
|         "psr-4": { |         "psr-4": { | ||||||
|             "MyAAC\\": "system/src" |             "MyAAC\\": "system/src" | ||||||
|         } |         }, | ||||||
|  |         "files": ["system/src/global.php"] | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										2915
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2915
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -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') | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -82,7 +82,7 @@ describe('Check Public Pages', () => { | |||||||
|  |  | ||||||
| 	it('Go to last kills page', () => { | 	it('Go to last kills page', () => { | ||||||
| 		cy.visit({ | 		cy.visit({ | ||||||
| 			url: Cypress.env('URL') + '/lastkills', | 			url: Cypress.env('URL') + '/last-kills', | ||||||
| 			method: 'GET', | 			method: 'GET', | ||||||
| 		}) | 		}) | ||||||
| 	}) | 	}) | ||||||
| @@ -132,7 +132,7 @@ describe('Check Public Pages', () => { | |||||||
|  |  | ||||||
| 	it('Go to server info page', () => { | 	it('Go to server info page', () => { | ||||||
| 		cy.visit({ | 		cy.visit({ | ||||||
| 			url: Cypress.env('URL') + '/serverInfo', | 			url: Cypress.env('URL') + '/server-info', | ||||||
| 			method: 'GET', | 			method: 'GET', | ||||||
| 		}) | 		}) | ||||||
| 	}) | 	}) | ||||||
| @@ -160,7 +160,7 @@ describe('Check Public Pages', () => { | |||||||
|  |  | ||||||
| 	it('Go to experience table page', () => { | 	it('Go to experience table page', () => { | ||||||
| 		cy.visit({ | 		cy.visit({ | ||||||
| 			url: Cypress.env('URL') + '/experienceTable', | 			url: Cypress.env('URL') + '/exp-table', | ||||||
| 			method: 'GET', | 			method: 'GET', | ||||||
| 		}) | 		}) | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | services: | ||||||
|  |   web: | ||||||
|  |     ports: | ||||||
|  |       - 8001:80 | ||||||
|  |     build: | ||||||
|  |       args: | ||||||
|  |         user: www-data | ||||||
|  |         uid: 33 | ||||||
|  |       context: ./ | ||||||
|  |       dockerfile: ./docker/Dockerfile | ||||||
|  |     restart: unless-stopped | ||||||
|  |     working_dir: /var/www/html | ||||||
|  |     depends_on: | ||||||
|  |       - db | ||||||
|  |     #volumes: | ||||||
|  |     #  - ./:/var/www/html | ||||||
|  |  | ||||||
|  |   db: | ||||||
|  |     image: mysql:8.0 | ||||||
|  |     restart: unless-stopped # always? | ||||||
|  |     environment: | ||||||
|  |       MYSQL_RANDOM_ROOT_PASSWORD: "yes" | ||||||
|  |       MYSQL_DATABASE: myaac | ||||||
|  |       #MYSQL_ROOT_PASSWORD: root | ||||||
|  |       MYSQL_PASSWORD: myaac | ||||||
|  |       MYSQL_USER: myaac | ||||||
|  |     ports: | ||||||
|  |       - 8003:3306 | ||||||
|  |     volumes: | ||||||
|  |       - ./docker/tfs_schema.sql:/docker-entrypoint-initdb.d/tfs_schema.sql | ||||||
|  |       - db:/var/lib/mysql | ||||||
|  |  | ||||||
|  |   phpmyadmin: | ||||||
|  |     image: phpmyadmin | ||||||
|  |     restart: always | ||||||
|  |     ports: | ||||||
|  |       - 8002:80 | ||||||
|  |  | ||||||
|  | volumes: | ||||||
|  |   db: | ||||||
							
								
								
									
										56
									
								
								docker/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								docker/Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | FROM php:8.2-apache | ||||||
|  |  | ||||||
|  | ARG APCU_VERSION=5.1.22 | ||||||
|  |  | ||||||
|  | # Arguments defined in docker-compose.yml | ||||||
|  | ARG user | ||||||
|  | ARG uid | ||||||
|  |  | ||||||
|  | # Install system dependencies | ||||||
|  | RUN apt-get update && apt-get install -y \ | ||||||
|  |     git \ | ||||||
|  |     curl \ | ||||||
|  |     libpng-dev \ | ||||||
|  |     libonig-dev \ | ||||||
|  |     libxml2-dev \ | ||||||
|  |     libzip-dev \ | ||||||
|  |     zip \ | ||||||
|  |     unzip \ | ||||||
|  |     nano \ | ||||||
|  |     vim | ||||||
|  |  | ||||||
|  | RUN apt-get install -y nodejs npm | ||||||
|  |  | ||||||
|  | # Clear cache | ||||||
|  | RUN apt-get clean && rm -rf /var/lib/apt/lists/* | ||||||
|  |  | ||||||
|  | # Install PHP extensions | ||||||
|  | RUN docker-php-ext-install pdo pdo_mysql gd zip opcache | ||||||
|  | RUN docker-php-ext-configure opcache --enable-opcache | ||||||
|  | RUN pecl install apcu-${APCU_VERSION} && docker-php-ext-enable apcu | ||||||
|  |  | ||||||
|  | # Get latest Composer | ||||||
|  | COPY --from=composer:latest /usr/bin/composer /usr/bin/composer | ||||||
|  |  | ||||||
|  | # Create system user to run Composer Commands | ||||||
|  | #RUN useradd -G www-data,root -u $uid -d /home/$user $user | ||||||
|  | RUN mkdir -p /home/$user/.composer && \ | ||||||
|  |     chown -R $user:$user /home/$user | ||||||
|  |  | ||||||
|  | RUN chown -R www-data.www-data /var/www | ||||||
|  |  | ||||||
|  | USER $user | ||||||
|  |  | ||||||
|  | WORKDIR /home/$user | ||||||
|  | RUN git clone https://github.com/otland/forgottenserver.git | ||||||
|  |  | ||||||
|  | COPY --chown=www-data:www-data docker/config.lua /home/$user/forgottenserver | ||||||
|  | COPY --chown=www-data:www-data docker/config.local.php /var/www/html | ||||||
|  |  | ||||||
|  | #WORKDIR /home/$user/forgottenserver | ||||||
|  |  | ||||||
|  | WORKDIR /var/www/html | ||||||
|  |  | ||||||
|  | COPY --chown=www-data:www-data . . | ||||||
|  | RUN composer install | ||||||
|  | RUN npm install | ||||||
							
								
								
									
										4
									
								
								docker/config.local.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								docker/config.local.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | <?php | ||||||
|  | $config['installed'] = false; | ||||||
|  | $config['server_path'] = '/home/www-data/forgottenserver'; | ||||||
|  | $config['install_ignore_ip_check'] = true; | ||||||
							
								
								
									
										12
									
								
								docker/config.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								docker/config.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | serverName = "Forgotten" | ||||||
|  | mysqlHost = "db" | ||||||
|  | mysqlUser = "myaac" | ||||||
|  | mysqlPass = "myaac" | ||||||
|  | mysqlDatabase = "myaac" | ||||||
|  | mysqlPort = 3306 | ||||||
|  | mysqlSock = "" | ||||||
|  |  | ||||||
|  | ip = "192.168.176.1" | ||||||
|  | statusPort = 7171 | ||||||
|  | statusTimeout = 2000 | ||||||
|  |  | ||||||
							
								
								
									
										384
									
								
								docker/tfs_schema.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										384
									
								
								docker/tfs_schema.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,384 @@ | |||||||
|  | CREATE TABLE IF NOT EXISTS `accounts` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `name` varchar(32) NOT NULL, | ||||||
|  |   `password` char(40) NOT NULL, | ||||||
|  |   `secret` char(16) DEFAULT NULL, | ||||||
|  |   `type` int NOT NULL DEFAULT '1', | ||||||
|  |   `premium_ends_at` int unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `email` varchar(255) NOT NULL DEFAULT '', | ||||||
|  |   `creation` int NOT NULL DEFAULT '0', | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   UNIQUE KEY `name` (`name`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `players` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `name` varchar(255) NOT NULL, | ||||||
|  |   `group_id` int NOT NULL DEFAULT '1', | ||||||
|  |   `account_id` int NOT NULL DEFAULT '0', | ||||||
|  |   `level` int NOT NULL DEFAULT '1', | ||||||
|  |   `vocation` int NOT NULL DEFAULT '0', | ||||||
|  |   `health` int NOT NULL DEFAULT '150', | ||||||
|  |   `healthmax` int NOT NULL DEFAULT '150', | ||||||
|  |   `experience` bigint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `lookbody` int NOT NULL DEFAULT '0', | ||||||
|  |   `lookfeet` int NOT NULL DEFAULT '0', | ||||||
|  |   `lookhead` int NOT NULL DEFAULT '0', | ||||||
|  |   `looklegs` int NOT NULL DEFAULT '0', | ||||||
|  |   `looktype` int NOT NULL DEFAULT '136', | ||||||
|  |   `lookaddons` int NOT NULL DEFAULT '0', | ||||||
|  |   `lookmount` int NOT NULL DEFAULT '0', | ||||||
|  |   `lookmounthead` int NOT NULL DEFAULT '0', | ||||||
|  |   `lookmountbody` int NOT NULL DEFAULT '0', | ||||||
|  |   `lookmountlegs` int NOT NULL DEFAULT '0', | ||||||
|  |   `lookmountfeet` int NOT NULL DEFAULT '0', | ||||||
|  |   `randomizemount` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `direction` tinyint unsigned NOT NULL DEFAULT '2', | ||||||
|  |   `maglevel` int NOT NULL DEFAULT '0', | ||||||
|  |   `mana` int NOT NULL DEFAULT '0', | ||||||
|  |   `manamax` int NOT NULL DEFAULT '0', | ||||||
|  |   `manaspent` bigint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `soul` int unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `town_id` int NOT NULL DEFAULT '1', | ||||||
|  |   `posx` int NOT NULL DEFAULT '0', | ||||||
|  |   `posy` int NOT NULL DEFAULT '0', | ||||||
|  |   `posz` int NOT NULL DEFAULT '0', | ||||||
|  |   `conditions` blob DEFAULT NULL, | ||||||
|  |   `cap` int NOT NULL DEFAULT '400', | ||||||
|  |   `sex` int NOT NULL DEFAULT '0', | ||||||
|  |   `lastlogin` bigint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `lastip` varbinary(16) NOT NULL DEFAULT '0', | ||||||
|  |   `save` tinyint NOT NULL DEFAULT '1', | ||||||
|  |   `skull` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `skulltime` bigint NOT NULL DEFAULT '0', | ||||||
|  |   `lastlogout` bigint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `blessings` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `onlinetime` bigint NOT NULL DEFAULT '0', | ||||||
|  |   `deletion` bigint NOT NULL DEFAULT '0', | ||||||
|  |   `balance` bigint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `offlinetraining_time` smallint unsigned NOT NULL DEFAULT '43200', | ||||||
|  |   `offlinetraining_skill` int NOT NULL DEFAULT '-1', | ||||||
|  |   `stamina` smallint unsigned NOT NULL DEFAULT '2520', | ||||||
|  |   `skill_fist` int unsigned NOT NULL DEFAULT 10, | ||||||
|  |   `skill_fist_tries` bigint unsigned NOT NULL DEFAULT 0, | ||||||
|  |   `skill_club` int unsigned NOT NULL DEFAULT 10, | ||||||
|  |   `skill_club_tries` bigint unsigned NOT NULL DEFAULT 0, | ||||||
|  |   `skill_sword` int unsigned NOT NULL DEFAULT 10, | ||||||
|  |   `skill_sword_tries` bigint unsigned NOT NULL DEFAULT 0, | ||||||
|  |   `skill_axe` int unsigned NOT NULL DEFAULT 10, | ||||||
|  |   `skill_axe_tries` bigint unsigned NOT NULL DEFAULT 0, | ||||||
|  |   `skill_dist` int unsigned NOT NULL DEFAULT 10, | ||||||
|  |   `skill_dist_tries` bigint unsigned NOT NULL DEFAULT 0, | ||||||
|  |   `skill_shielding` int unsigned NOT NULL DEFAULT 10, | ||||||
|  |   `skill_shielding_tries` bigint unsigned NOT NULL DEFAULT 0, | ||||||
|  |   `skill_fishing` int unsigned NOT NULL DEFAULT 10, | ||||||
|  |   `skill_fishing_tries` bigint unsigned NOT NULL DEFAULT 0, | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   UNIQUE KEY `name` (`name`), | ||||||
|  |   FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE, | ||||||
|  |   KEY `vocation` (`vocation`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `account_bans` ( | ||||||
|  |   `account_id` int NOT NULL, | ||||||
|  |   `reason` varchar(255) NOT NULL, | ||||||
|  |   `banned_at` bigint NOT NULL, | ||||||
|  |   `expires_at` bigint NOT NULL, | ||||||
|  |   `banned_by` int NOT NULL, | ||||||
|  |   PRIMARY KEY (`account_id`), | ||||||
|  |   FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, | ||||||
|  |   FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `account_ban_history` ( | ||||||
|  |   `id` int unsigned NOT NULL AUTO_INCREMENT, | ||||||
|  |   `account_id` int NOT NULL, | ||||||
|  |   `reason` varchar(255) NOT NULL, | ||||||
|  |   `banned_at` bigint NOT NULL, | ||||||
|  |   `expired_at` bigint NOT NULL, | ||||||
|  |   `banned_by` int NOT NULL, | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, | ||||||
|  |   FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `account_storage` ( | ||||||
|  |   `account_id` int NOT NULL, | ||||||
|  |   `key` int unsigned NOT NULL, | ||||||
|  |   `value` int NOT NULL, | ||||||
|  |   PRIMARY KEY (`account_id`, `key`), | ||||||
|  |   FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `ip_bans` ( | ||||||
|  |   `ip` varbinary(16) NOT NULL, | ||||||
|  |   `reason` varchar(255) NOT NULL, | ||||||
|  |   `banned_at` bigint NOT NULL, | ||||||
|  |   `expires_at` bigint NOT NULL, | ||||||
|  |   `banned_by` int NOT NULL, | ||||||
|  |   PRIMARY KEY (`ip`), | ||||||
|  |   FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `player_namelocks` ( | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `reason` varchar(255) NOT NULL, | ||||||
|  |   `namelocked_at` bigint NOT NULL, | ||||||
|  |   `namelocked_by` int NOT NULL, | ||||||
|  |   PRIMARY KEY (`player_id`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, | ||||||
|  |   FOREIGN KEY (`namelocked_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `account_viplist` ( | ||||||
|  |   `account_id` int NOT NULL COMMENT 'id of account whose viplist entry it is', | ||||||
|  |   `player_id` int NOT NULL COMMENT 'id of target player of viplist entry', | ||||||
|  |   `description` varchar(128) NOT NULL DEFAULT '', | ||||||
|  |   `icon` tinyint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `notify` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   UNIQUE KEY `account_player_index` (`account_id`,`player_id`), | ||||||
|  |   FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE, | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `guilds` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `name` varchar(255) NOT NULL, | ||||||
|  |   `ownerid` int NOT NULL, | ||||||
|  |   `creationdata` int NOT NULL, | ||||||
|  |   `motd` varchar(255) NOT NULL DEFAULT '', | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   UNIQUE KEY (`name`), | ||||||
|  |   UNIQUE KEY (`ownerid`), | ||||||
|  |   FOREIGN KEY (`ownerid`) REFERENCES `players`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `guild_invites` ( | ||||||
|  |   `player_id` int NOT NULL DEFAULT '0', | ||||||
|  |   `guild_id` int NOT NULL DEFAULT '0', | ||||||
|  |   PRIMARY KEY (`player_id`,`guild_id`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE, | ||||||
|  |   FOREIGN KEY (`guild_id`) REFERENCES `guilds` (`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `guild_ranks` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `guild_id` int NOT NULL COMMENT 'guild', | ||||||
|  |   `name` varchar(255) NOT NULL COMMENT 'rank name', | ||||||
|  |   `level` int NOT NULL COMMENT 'rank level - leader, vice, member, maybe something else', | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   FOREIGN KEY (`guild_id`) REFERENCES `guilds` (`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `guild_membership` ( | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `guild_id` int NOT NULL, | ||||||
|  |   `rank_id` int NOT NULL, | ||||||
|  |   `nick` varchar(15) NOT NULL DEFAULT '', | ||||||
|  |   PRIMARY KEY (`player_id`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, | ||||||
|  |   FOREIGN KEY (`guild_id`) REFERENCES `guilds` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, | ||||||
|  |   FOREIGN KEY (`rank_id`) REFERENCES `guild_ranks` (`id`) ON DELETE CASCADE ON UPDATE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `guild_wars` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `guild1` int NOT NULL DEFAULT '0', | ||||||
|  |   `guild2` int NOT NULL DEFAULT '0', | ||||||
|  |   `name1` varchar(255) NOT NULL, | ||||||
|  |   `name2` varchar(255) NOT NULL, | ||||||
|  |   `status` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `started` bigint NOT NULL DEFAULT '0', | ||||||
|  |   `ended` bigint NOT NULL DEFAULT '0', | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   KEY `guild1` (`guild1`), | ||||||
|  |   KEY `guild2` (`guild2`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `guildwar_kills` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `killer` varchar(50) NOT NULL, | ||||||
|  |   `target` varchar(50) NOT NULL, | ||||||
|  |   `killerguild` int NOT NULL DEFAULT '0', | ||||||
|  |   `targetguild` int NOT NULL DEFAULT '0', | ||||||
|  |   `warid` int NOT NULL DEFAULT '0', | ||||||
|  |   `time` bigint NOT NULL, | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   FOREIGN KEY (`warid`) REFERENCES `guild_wars` (`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `houses` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `owner` int NOT NULL, | ||||||
|  |   `paid` int unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `warnings` int NOT NULL DEFAULT '0', | ||||||
|  |   `name` varchar(255) NOT NULL, | ||||||
|  |   `rent` int NOT NULL DEFAULT '0', | ||||||
|  |   `town_id` int NOT NULL DEFAULT '0', | ||||||
|  |   `bid` int NOT NULL DEFAULT '0', | ||||||
|  |   `bid_end` int NOT NULL DEFAULT '0', | ||||||
|  |   `last_bid` int NOT NULL DEFAULT '0', | ||||||
|  |   `highest_bidder` int NOT NULL DEFAULT '0', | ||||||
|  |   `size` int NOT NULL DEFAULT '0', | ||||||
|  |   `beds` int NOT NULL DEFAULT '0', | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   KEY `owner` (`owner`), | ||||||
|  |   KEY `town_id` (`town_id`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `house_lists` ( | ||||||
|  |   `house_id` int NOT NULL, | ||||||
|  |   `listid` int NOT NULL, | ||||||
|  |   `list` text NOT NULL, | ||||||
|  |   FOREIGN KEY (`house_id`) REFERENCES `houses` (`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `market_history` ( | ||||||
|  |   `id` int unsigned NOT NULL AUTO_INCREMENT, | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `sale` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `itemtype` smallint unsigned NOT NULL, | ||||||
|  |   `amount` smallint unsigned NOT NULL, | ||||||
|  |   `price` bigint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `expires_at` bigint unsigned NOT NULL, | ||||||
|  |   `inserted` bigint unsigned NOT NULL, | ||||||
|  |   `state` tinyint unsigned NOT NULL, | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   KEY `player_id` (`player_id`, `sale`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `market_offers` ( | ||||||
|  |   `id` int unsigned NOT NULL AUTO_INCREMENT, | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `sale` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `itemtype` smallint unsigned NOT NULL, | ||||||
|  |   `amount` smallint unsigned NOT NULL, | ||||||
|  |   `created` bigint unsigned NOT NULL, | ||||||
|  |   `anonymous` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `price` bigint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   KEY `sale` (`sale`,`itemtype`), | ||||||
|  |   KEY `created` (`created`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `players_online` ( | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   PRIMARY KEY (`player_id`) | ||||||
|  | ) ENGINE=MEMORY DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `player_deaths` ( | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `time` bigint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `level` int NOT NULL DEFAULT '1', | ||||||
|  |   `killed_by` varchar(255) NOT NULL, | ||||||
|  |   `is_player` tinyint NOT NULL DEFAULT '1', | ||||||
|  |   `mostdamage_by` varchar(100) NOT NULL, | ||||||
|  |   `mostdamage_is_player` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `unjustified` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   `mostdamage_unjustified` tinyint NOT NULL DEFAULT '0', | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE, | ||||||
|  |   KEY `killed_by` (`killed_by`), | ||||||
|  |   KEY `mostdamage_by` (`mostdamage_by`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `player_depotitems` ( | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `sid` int NOT NULL COMMENT 'any given range eg 0-100 will be reserved for depot lockers and all > 100 will be then normal items inside depots', | ||||||
|  |   `pid` int NOT NULL DEFAULT '0', | ||||||
|  |   `itemtype` smallint unsigned NOT NULL, | ||||||
|  |   `count` smallint NOT NULL DEFAULT '0', | ||||||
|  |   `attributes` blob NOT NULL, | ||||||
|  |   UNIQUE KEY `player_id_2` (`player_id`, `sid`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `player_inboxitems` ( | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `sid` int NOT NULL, | ||||||
|  |   `pid` int NOT NULL DEFAULT '0', | ||||||
|  |   `itemtype` smallint unsigned NOT NULL, | ||||||
|  |   `count` smallint NOT NULL DEFAULT '0', | ||||||
|  |   `attributes` blob NOT NULL, | ||||||
|  |   UNIQUE KEY `player_id_2` (`player_id`, `sid`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `player_storeinboxitems` ( | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `sid` int NOT NULL, | ||||||
|  |   `pid` int NOT NULL DEFAULT '0', | ||||||
|  |   `itemtype` smallint unsigned NOT NULL, | ||||||
|  |   `count` smallint NOT NULL DEFAULT '0', | ||||||
|  |   `attributes` blob NOT NULL, | ||||||
|  |   UNIQUE KEY `player_id_2` (`player_id`, `sid`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `player_items` ( | ||||||
|  |   `player_id` int NOT NULL DEFAULT '0', | ||||||
|  |   `pid` int NOT NULL DEFAULT '0', | ||||||
|  |   `sid` int NOT NULL DEFAULT '0', | ||||||
|  |   `itemtype` smallint unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `count` smallint NOT NULL DEFAULT '0', | ||||||
|  |   `attributes` blob NOT NULL, | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE, | ||||||
|  |   KEY `sid` (`sid`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `player_spells` ( | ||||||
|  |   `player_id` int NOT NULL, | ||||||
|  |   `name` varchar(255) NOT NULL, | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `player_storage` ( | ||||||
|  |   `player_id` int NOT NULL DEFAULT '0', | ||||||
|  |   `key` int unsigned NOT NULL DEFAULT '0', | ||||||
|  |   `value` int NOT NULL DEFAULT '0', | ||||||
|  |   PRIMARY KEY (`player_id`,`key`), | ||||||
|  |   FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `server_config` ( | ||||||
|  |   `config` varchar(50) NOT NULL, | ||||||
|  |   `value` varchar(256) NOT NULL DEFAULT '', | ||||||
|  |   PRIMARY KEY `config` (`config`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `tile_store` ( | ||||||
|  |   `house_id` int NOT NULL, | ||||||
|  |   `data` longblob NOT NULL, | ||||||
|  |   FOREIGN KEY (`house_id`) REFERENCES `houses` (`id`) ON DELETE CASCADE | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS `towns` ( | ||||||
|  |   `id` int NOT NULL AUTO_INCREMENT, | ||||||
|  |   `name` varchar(255) NOT NULL, | ||||||
|  |   `posx` int NOT NULL DEFAULT '0', | ||||||
|  |   `posy` int NOT NULL DEFAULT '0', | ||||||
|  |   `posz` int NOT NULL DEFAULT '0', | ||||||
|  |   PRIMARY KEY (`id`), | ||||||
|  |   UNIQUE KEY `name` (`name`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ||||||
|  |  | ||||||
|  | INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '35'), ('players_record', '0'); | ||||||
|  |  | ||||||
|  | DROP TRIGGER IF EXISTS `ondelete_players`; | ||||||
|  | DROP TRIGGER IF EXISTS `oncreate_guilds`; | ||||||
|  |  | ||||||
|  | DELIMITER // | ||||||
|  | CREATE TRIGGER `ondelete_players` BEFORE DELETE ON `players` | ||||||
|  |  FOR EACH ROW BEGIN | ||||||
|  |     UPDATE `houses` SET `owner` = 0 WHERE `owner` = OLD.`id`; | ||||||
|  | END | ||||||
|  | // | ||||||
|  | CREATE TRIGGER `oncreate_guilds` AFTER INSERT ON `guilds` | ||||||
|  |  FOR EACH ROW BEGIN | ||||||
|  |     INSERT INTO `guild_ranks` (`name`, `level`, `guild_id`) VALUES ('the Leader', 3, NEW.`id`); | ||||||
|  |     INSERT INTO `guild_ranks` (`name`, `level`, `guild_id`) VALUES ('a Vice-Leader', 2, NEW.`id`); | ||||||
|  |     INSERT INTO `guild_ranks` (`name`, `level`, `guild_id`) VALUES ('a Member', 1, NEW.`id`); | ||||||
|  | END | ||||||
|  | // | ||||||
|  | DELIMITER ; | ||||||
							
								
								
									
										102
									
								
								index.php
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								index.php
									
									
									
									
									
								
							| @@ -24,6 +24,9 @@ | |||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\UsageStatistics; | ||||||
|  | use MyAAC\Visitors; | ||||||
|  |  | ||||||
| require_once 'common.php'; | require_once 'common.php'; | ||||||
| require_once SYSTEM . 'functions.php'; | require_once SYSTEM . 'functions.php'; | ||||||
|  |  | ||||||
| @@ -59,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,6 @@ require_once SYSTEM . 'status.php'; | |||||||
| $twig->addGlobal('config', $config); | $twig->addGlobal('config', $config); | ||||||
| $twig->addGlobal('status', $status); | $twig->addGlobal('status', $status); | ||||||
|  |  | ||||||
| require_once SYSTEM . 'router.php'; |  | ||||||
|  |  | ||||||
| $hooks->trigger(HOOK_STARTUP); |  | ||||||
|  |  | ||||||
| // anonymous usage statistics |  | ||||||
| // sent only when user agrees |  | ||||||
| if(setting('core.anonymous_usage_statistics')) { |  | ||||||
| 	$report_time = 30 * 24 * 60 * 60; // report one time per 30 days |  | ||||||
| 	$should_report = true; |  | ||||||
|  |  | ||||||
| 	$value = ''; |  | ||||||
| 	if($cache->enabled() && $cache->fetch('last_usage_report', $value)) { |  | ||||||
| 		$should_report = time() > (int)$value + $report_time; |  | ||||||
| 	} |  | ||||||
| 	else { |  | ||||||
| 		$value = ''; |  | ||||||
| 		if(fetchDatabaseConfig('last_usage_report', $value)) { |  | ||||||
| 			$should_report = time() > (int)$value + $report_time; |  | ||||||
| 			if($cache->enabled()) { |  | ||||||
| 				$cache->set('last_usage_report', $value); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			registerDatabaseConfig('last_usage_report', time() - ($report_time - (7 * 24 * 60 * 60))); // first report after a week |  | ||||||
| 			$should_report = false; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if($should_report) { |  | ||||||
| 		require_once LIBS . 'usage_statistics.php'; |  | ||||||
| 		Usage_Statistics::report(); |  | ||||||
|  |  | ||||||
| 		updateDatabaseConfig('last_usage_report', time()); |  | ||||||
| 		if($cache->enabled()) { |  | ||||||
| 			$cache->set('last_usage_report', time()); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if(setting('core.views_counter')) |  | ||||||
| 	require_once SYSTEM . 'counter.php'; |  | ||||||
|  |  | ||||||
| if(setting('core.visitors_counter')) { |  | ||||||
| 	require_once SYSTEM . 'libs/visitors.php'; |  | ||||||
| 	$visitors = new Visitors(setting('core.visitors_counter_ttl')); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // backward support for gesior | // backward support for gesior | ||||||
| if(setting('core.backward_support')) { | if(setting('core.backward_support')) { | ||||||
| 	define('INITIALIZED', true); | 	define('INITIALIZED', true); | ||||||
| @@ -164,6 +115,51 @@ if(setting('core.backward_support')) { | |||||||
| 		$config['status']['serverStatus_' . $key] = $value; | 		$config['status']['serverStatus_' . $key] = $value; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | require_once SYSTEM . 'router.php'; | ||||||
|  |  | ||||||
|  | $hooks->trigger(HOOK_STARTUP); | ||||||
|  |  | ||||||
|  | // anonymous usage statistics | ||||||
|  | // sent only when user agrees | ||||||
|  | if(setting('core.anonymous_usage_statistics')) { | ||||||
|  | 	$report_time = 30 * 24 * 60 * 60; // report one time per 30 days | ||||||
|  | 	$should_report = true; | ||||||
|  |  | ||||||
|  | 	$value = ''; | ||||||
|  | 	if($cache->enabled() && $cache->fetch('last_usage_report', $value)) { | ||||||
|  | 		$should_report = time() > (int)$value + $report_time; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		$value = ''; | ||||||
|  | 		if(fetchDatabaseConfig('last_usage_report', $value)) { | ||||||
|  | 			$should_report = time() > (int)$value + $report_time; | ||||||
|  | 			if($cache->enabled()) { | ||||||
|  | 				$cache->set('last_usage_report', $value); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			registerDatabaseConfig('last_usage_report', time() - ($report_time - (7 * 24 * 60 * 60))); // first report after a week | ||||||
|  | 			$should_report = false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if($should_report) { | ||||||
|  | 		UsageStatistics::report(); | ||||||
|  |  | ||||||
|  | 		updateDatabaseConfig('last_usage_report', time()); | ||||||
|  | 		if($cache->enabled()) { | ||||||
|  | 			$cache->set('last_usage_report', time()); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if(setting('core.views_counter')) | ||||||
|  | 	require_once SYSTEM . 'counter.php'; | ||||||
|  |  | ||||||
|  | if(setting('core.visitors_counter')) { | ||||||
|  | 	$visitors = new Visitors(setting('core.visitors_counter_ttl')); | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @var OTS_Account $account_logged |  * @var OTS_Account $account_logged | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -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])); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| SET @myaac_database_version = 36; | SET @myaac_database_version = 41; | ||||||
|  |  | ||||||
| CREATE TABLE `myaac_account_actions` | CREATE TABLE `myaac_account_actions` | ||||||
| ( | ( | ||||||
| @@ -8,7 +8,7 @@ CREATE TABLE `myaac_account_actions` | |||||||
| 	`date` INT(11) NOT NULL DEFAULT 0, | 	`date` INT(11) 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` | ||||||
| ( | ( | ||||||
| @@ -19,22 +19,7 @@ CREATE TABLE `myaac_admin_menu` | |||||||
| 	`flags` INT(11) NOT NULL DEFAULT 0, | 	`flags` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`enabled` INT(1) NOT NULL DEFAULT 1, | 	`enabled` INT(1) 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` | ||||||
| ( | ( | ||||||
| @@ -44,11 +29,11 @@ CREATE TABLE `myaac_changelog` | |||||||
| 	`where` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - server, 2 - site', | 	`where` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - server, 2 - site', | ||||||
| 	`date` INT(11) NOT NULL DEFAULT 0, | 	`date` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`player_id` INT(11) NOT NULL DEFAULT 0, | 	`player_id` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`hidden` TINYINT(1) NOT NULL DEFAULT 0, | 	`hide` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	PRIMARY KEY (`id`) | 	PRIMARY KEY (`id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=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` | ||||||
| ( | ( | ||||||
| @@ -57,7 +42,7 @@ CREATE TABLE `myaac_config` | |||||||
| 	`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); | ||||||
|  |  | ||||||
| @@ -67,9 +52,9 @@ CREATE TABLE `myaac_faq` | |||||||
| 	`question` VARCHAR(255) NOT NULL DEFAULT '', | 	`question` VARCHAR(255) NOT NULL DEFAULT '', | ||||||
| 	`answer` VARCHAR(1020) NOT NULL DEFAULT '', | 	`answer` VARCHAR(1020) NOT NULL DEFAULT '', | ||||||
| 	`ordering` INT(11) NOT NULL DEFAULT 0, | 	`ordering` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`hidden` TINYINT(1) NOT NULL DEFAULT 0, | 	`hide` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	PRIMARY KEY (`id`) | 	PRIMARY KEY (`id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; | ||||||
|  |  | ||||||
| CREATE TABLE `myaac_forum_boards` | CREATE TABLE `myaac_forum_boards` | ||||||
| ( | ( | ||||||
| @@ -80,9 +65,9 @@ CREATE TABLE `myaac_forum_boards` | |||||||
| 	`guild` INT(11) NOT NULL DEFAULT 0, | 	`guild` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`access` INT(11) NOT NULL DEFAULT 0, | 	`access` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`closed` TINYINT(1) NOT NULL DEFAULT 0, | 	`closed` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	`hidden` TINYINT(1) NOT NULL DEFAULT 0, | 	`hide` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	PRIMARY KEY (`id`) | 	PRIMARY KEY (`id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=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); | ||||||
| @@ -111,7 +96,7 @@ CREATE TABLE `myaac_forum` | |||||||
| 	`closed` tinyint(1) NOT NULL DEFAULT '0', | 	`closed` tinyint(1) 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` | ||||||
| ( | ( | ||||||
| @@ -125,11 +110,11 @@ CREATE TABLE `myaac_menu` | |||||||
| 	`ordering` INT(11) NOT NULL DEFAULT 0, | 	`ordering` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`enabled` INT(1) NOT NULL DEFAULT 1, | 	`enabled` INT(1) 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(11) NOT NULL AUTO_INCREMENT, | ||||||
| 	`hidden` tinyint(1) NOT NULL default 0, | 	`hide` tinyint(1) NOT NULL default 0, | ||||||
| 	`name` varchar(255) NOT NULL, | 	`name` varchar(255) NOT NULL, | ||||||
| 	`mana` int(11) NOT NULL DEFAULT 0, | 	`mana` int(11) NOT NULL DEFAULT 0, | ||||||
| 	`exp` int(11) NOT NULL, | 	`exp` int(11) NOT NULL, | ||||||
| @@ -158,7 +143,7 @@ CREATE TABLE `myaac_monsters` ( | |||||||
| 	`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` | ||||||
| ( | ( | ||||||
| @@ -174,9 +159,9 @@ CREATE TABLE `myaac_news` | |||||||
| 	`comments` VARCHAR(50) NOT NULL DEFAULT '', | 	`comments` VARCHAR(50) NOT NULL DEFAULT '', | ||||||
| 	`article_text` VARCHAR(300) NOT NULL DEFAULT '', | 	`article_text` VARCHAR(300) NOT NULL DEFAULT '', | ||||||
| 	`article_image` VARCHAR(100) NOT NULL DEFAULT '', | 	`article_image` VARCHAR(100) NOT NULL DEFAULT '', | ||||||
| 	`hidden` TINYINT(1) NOT NULL DEFAULT 0, | 	`hide` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	PRIMARY KEY (`id`) | 	PRIMARY KEY (`id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; | ||||||
|  |  | ||||||
| CREATE TABLE `myaac_news_categories` | CREATE TABLE `myaac_news_categories` | ||||||
| ( | ( | ||||||
| @@ -184,9 +169,9 @@ CREATE TABLE `myaac_news_categories` | |||||||
| 	`name` VARCHAR(50) NOT NULL DEFAULT "", | 	`name` VARCHAR(50) NOT NULL DEFAULT "", | ||||||
| 	`description` VARCHAR(50) NOT NULL DEFAULT "", | 	`description` VARCHAR(50) NOT NULL DEFAULT "", | ||||||
| 	`icon_id` INT(2) NOT NULL DEFAULT 0, | 	`icon_id` INT(2) NOT NULL DEFAULT 0, | ||||||
| 	`hidden` TINYINT(1) NOT NULL DEFAULT 0, | 	`hide` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	PRIMARY KEY (`id`) | 	PRIMARY KEY (`id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=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); | ||||||
| @@ -202,7 +187,7 @@ CREATE TABLE `myaac_notepad` | |||||||
| 	`content` TEXT NOT NULL, | 	`content` TEXT NOT NULL, | ||||||
| 	/*`public` TINYINT(1) NOT NULL DEFAULT 0*/ | 	/*`public` TINYINT(1) 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` | ||||||
| ( | ( | ||||||
| @@ -215,10 +200,10 @@ CREATE TABLE `myaac_pages` | |||||||
| 	`php` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 - plain html, 1 - php', | 	`php` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 - plain html, 1 - php', | ||||||
| 	`enable_tinymce` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 - enabled, 0 - disabled', | 	`enable_tinymce` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1 - enabled, 0 - disabled', | ||||||
| 	`access` TINYINT(2) NOT NULL DEFAULT 0, | 	`access` TINYINT(2) NOT NULL DEFAULT 0, | ||||||
| 	`hidden` TINYINT(1) NOT NULL DEFAULT 0, | 	`hide` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	PRIMARY KEY (`id`), | 	PRIMARY KEY (`id`), | ||||||
| 	UNIQUE (`name`) | 	UNIQUE (`name`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; | ||||||
|  |  | ||||||
| CREATE TABLE `myaac_gallery` | CREATE TABLE `myaac_gallery` | ||||||
| ( | ( | ||||||
| @@ -228,9 +213,9 @@ CREATE TABLE `myaac_gallery` | |||||||
| 	`thumb` VARCHAR(255) NOT NULL, | 	`thumb` VARCHAR(255) NOT NULL, | ||||||
| 	`author` VARCHAR(50) NOT NULL DEFAULT '', | 	`author` VARCHAR(50) NOT NULL DEFAULT '', | ||||||
| 	`ordering` INT(11) NOT NULL DEFAULT 0, | 	`ordering` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`hidden` TINYINT(1) NOT NULL DEFAULT 0, | 	`hide` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	PRIMARY KEY (`id`) | 	PRIMARY KEY (`id`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=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'); | ||||||
|  |  | ||||||
| @@ -242,7 +227,7 @@ CREATE TABLE `myaac_settings` | |||||||
| 	`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` | ||||||
| ( | ( | ||||||
| @@ -262,10 +247,10 @@ CREATE TABLE `myaac_spells` | |||||||
| 	`item_id` INT(11) NOT NULL DEFAULT 0, | 	`item_id` INT(11) NOT NULL DEFAULT 0, | ||||||
| 	`premium` TINYINT(1) NOT NULL DEFAULT 0, | 	`premium` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	`vocations` VARCHAR(100) NOT NULL DEFAULT '', | 	`vocations` VARCHAR(100) NOT NULL DEFAULT '', | ||||||
| 	`hidden` TINYINT(1) NOT NULL DEFAULT 0, | 	`hide` TINYINT(1) NOT NULL DEFAULT 0, | ||||||
| 	PRIMARY KEY (`id`), | 	PRIMARY KEY (`id`), | ||||||
| 	UNIQUE (`name`) | 	UNIQUE (`name`) | ||||||
| ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; | ||||||
|  |  | ||||||
| CREATE TABLE `myaac_visitors` | CREATE TABLE `myaac_visitors` | ||||||
| ( | ( | ||||||
| @@ -274,7 +259,7 @@ CREATE TABLE `myaac_visitors` | |||||||
| 	`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` | ||||||
| ( | ( | ||||||
| @@ -283,4 +268,4 @@ CREATE TABLE `myaac_weapons` | |||||||
| 	`maglevel` INT(11) NOT NULL DEFAULT 0, | 	`maglevel` INT(11) 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; | ||||||
|   | |||||||
| @@ -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,12 +159,13 @@ else if($step == 'finish') { | |||||||
| 		$errors[] = $locale['step_admin_password_confirm_error_not_same']; | 		$errors[] = $locale['step_admin_password_confirm_error_not_same']; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// player name check | 	if (isset($player_name)) { | ||||||
| 	if(empty($player_name)) { | 		// player name check | ||||||
| 		$errors[] = $locale['step_admin_player_name_error_empty']; | 		if (empty($player_name)) { | ||||||
| 	} | 			$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)) { | ||||||
| @@ -183,23 +183,23 @@ 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; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(!$allow) | 		if(!$allow && !config('install_ignore_ip_check')) | ||||||
| 		{ | 		{ | ||||||
| 			$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(); | ||||||
|   | |||||||
| @@ -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>'; | ||||||
| ?> |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ foreach($config['clients'] as $client) { | |||||||
| } | } | ||||||
|  |  | ||||||
| $twig->display('install.config.html.twig', array( | $twig->display('install.config.html.twig', array( | ||||||
|  | 	'config' => $config, | ||||||
| 	'clients' => $clients, | 	'clients' => $clients, | ||||||
| 	'timezones' => DateTimeZone::listIdentifiers(), | 	'timezones' => DateTimeZone::listIdentifiers(), | ||||||
| 	'locale' => $locale, | 	'locale' => $locale, | ||||||
|   | |||||||
| @@ -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,58 +40,49 @@ 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 (isset($config['install_ignore_ip_check'])) { | ||||||
|  | 		$configToSave['install_ignore_ip_check'] = $config['install_ignore_ip_check']; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if(!$error) { | 	if(!$error) { | ||||||
| 		require BASE . 'install/includes/database.php'; | 		$content = ''; | ||||||
|  | 		$saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content); | ||||||
|  | 		if ($saved) { | ||||||
|  | 			success($locale['step_database_config_saved']); | ||||||
|  | 			$_SESSION['saved'] = true; | ||||||
|  |  | ||||||
| 		$locale['step_database_importing'] = str_replace('$DATABASE_NAME$', config('database_name'), $locale['step_database_importing']); | 			require BASE . 'config.local.php'; | ||||||
| 		success($locale['step_database_importing']); | 			require BASE . 'install/includes/config.php'; | ||||||
|  |  | ||||||
| 		if(isset($database_error)) { // we failed connect to the database | 			if (!$error) { | ||||||
| 			error($database_error); | 				require BASE . 'install/includes/database.php'; | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			if(!$db->hasTable('accounts')) { |  | ||||||
| 				$tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']); |  | ||||||
| 				error($tmp); |  | ||||||
| 				$error = true; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if(!$db->hasTable('players')) { | 				if (isset($database_error)) { // we failed connect to the database | ||||||
| 				$tmp = str_replace('$TABLE$', 'players', $locale['step_database_error_table']); | 					error($database_error); | ||||||
| 				error($tmp); |  | ||||||
| 				$error = true; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if(!$db->hasTable('guilds')) { |  | ||||||
| 				$tmp = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']); |  | ||||||
| 				error($tmp); |  | ||||||
| 				$error = true; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if(!$error) { |  | ||||||
| 				$twig->display('install.installer.html.twig', array( |  | ||||||
| 					'url' => 'tools/5-database.php', |  | ||||||
| 					'message' => $locale['loading_spinner'] |  | ||||||
| 				)); |  | ||||||
|  |  | ||||||
| 				$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; | 					if (!$db->hasTable('accounts')) { | ||||||
| 					unset($_SESSION['saved']); | 						$tmp = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']); | ||||||
|  | 						error($tmp); | ||||||
|  | 						$error = true; | ||||||
|  | 					} | ||||||
|  |  | ||||||
| 					$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.php</b>', $locale['step_database_error_file']); | 					if (!$error) { | ||||||
| 					error($locale['step_database_error_file'] . '<br/> | 						$twig->display('install.installer.html.twig', array( | ||||||
| 						<textarea cols="70" rows="10">' . $content . '</textarea>'); | 							'url' => 'tools/5-database.php', | ||||||
|  | 							'message' => $locale['loading_spinner'] | ||||||
|  | 						)); | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 		} else { | ||||||
|  | 			$_SESSION['config_content'] = $content; | ||||||
|  | 			unset($_SESSION['saved']); | ||||||
|  |  | ||||||
|  | 					$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']); | ||||||
|  | 			error($locale['step_database_error_file'] . '<br/> | ||||||
|  | 				<textarea cols="70" rows="10">' . $content . '</textarea>'); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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) | ||||||
| 	)); | 	)); | ||||||
|   | |||||||
| @@ -1,169 +1,207 @@ | |||||||
| <?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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $cache = Cache::getInstance(); | ||||||
|  | if ($cache->enabled()) { | ||||||
|  | 	// clear plugin_hooks to have fresh hooks | ||||||
|  | 	$cache->delete('plugins_hooks'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | require SYSTEM . 'init.php'; | ||||||
|  | if($error) { | ||||||
|  | 	return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER) | ||||||
|  | 	$account = $_SESSION['var_account'] ?? null; | ||||||
|  | else | ||||||
|  | 	$account_id = $_SESSION['var_account_id'] ?? null; | ||||||
|  |  | ||||||
|  | $password = $_SESSION['var_password']; | ||||||
|  |  | ||||||
|  | if(USE_ACCOUNT_SALT) | ||||||
|  | { | ||||||
|  | 	$salt = generateRandomString(10, false, true, true); | ||||||
|  | 	$password = $salt . $password; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $account_db = new OTS_Account(); | ||||||
|  | if(isset($account)) | ||||||
|  | 	$account_db->find($account); | ||||||
|  | else | ||||||
|  | 	$account_db->load($account_id); | ||||||
|  |  | ||||||
|  | if ($db->hasTable('players')) { | ||||||
|  | 	$player_name = $_SESSION['var_player_name']; | ||||||
|  | 	$player_db = new OTS_Player(); | ||||||
|  | 	$player_db->find($player_name); | ||||||
|  |  | ||||||
|  | 	if(!$player_db->isLoaded()) | ||||||
|  | 	{ | ||||||
|  | 		$player = new OTS_Player(); | ||||||
|  | 		$player->setName($player_name); | ||||||
|  |  | ||||||
|  | 		$player_used = &$player; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		$player_used = &$player_db; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$groups = new OTS_Groups_List(); | ||||||
|  | 	$player_used->setGroupId($groups->getHighestId()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $email = $_SESSION['var_email']; | ||||||
|  | if($account_db->isLoaded()) { | ||||||
|  | 	$account_db->setPassword(encrypt($password)); | ||||||
|  | 	$account_db->setEMail($email); | ||||||
|  | 	$account_db->save(); | ||||||
|  |  | ||||||
|  | 	$account_used = &$account_db; | ||||||
| } | } | ||||||
| else { | else { | ||||||
| 	require SYSTEM . 'init.php'; | 	$new_account = new OTS_Account(); | ||||||
| 	if(!$error) { | 	if(USE_ACCOUNT_NAME) { | ||||||
| 		if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER) | 		$new_account->create($account); | ||||||
| 			$account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null; | 	} | ||||||
| 		else | 	else { | ||||||
| 			$account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null; | 		$new_account->create(null, $account_id); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 		$password = $_SESSION['var_password']; | 	$new_account->setPassword(encrypt($password)); | ||||||
|  | 	$new_account->setEMail($email); | ||||||
|  |  | ||||||
| 		if(USE_ACCOUNT_SALT) | 	$new_account->save(); | ||||||
| 		{ |  | ||||||
| 			$salt = generateRandomString(10, false, true, true); |  | ||||||
| 			$password = $salt . $password; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		$account_db = new OTS_Account(); | 	$new_account->setCustomField('created', time()); | ||||||
| 		if(isset($account)) | 	$new_account->logAction('Account created.'); | ||||||
| 			$account_db->find($account); |  | ||||||
| 		else |  | ||||||
| 			$account_db->load($account_id); |  | ||||||
|  |  | ||||||
| 		$player_name = $_SESSION['var_player_name']; | 	$account_used = &$new_account; | ||||||
| 		$player_db = new OTS_Player(); | } | ||||||
| 		$player_db->find($player_name); |  | ||||||
|  |  | ||||||
| 		if(!$player_db->isLoaded()) | if(USE_ACCOUNT_SALT) | ||||||
| 		{ | 	$account_used->setCustomField('salt', $salt); | ||||||
| 			$player = new OTS_Player(); |  | ||||||
| 			$player->setName($player_name); |  | ||||||
|  |  | ||||||
| 			$player_used = &$player; | $account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN); | ||||||
| 		} | $account_used->setCustomField('country', 'us'); | ||||||
| 		else { | $account_used->setCustomField('email_verified', 1); | ||||||
| 			$player_used = &$player_db; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		$groups = new OTS_Groups_List(); | if($db->hasColumn('accounts', 'group_id')) | ||||||
| 		$player_used->setGroupId($groups->getHighestId()); | 	$account_used->setCustomField('group_id', $groups->getHighestId()); | ||||||
|  | if($db->hasColumn('accounts', 'type')) | ||||||
|  | 	$account_used->setCustomField('type', 6); | ||||||
|  |  | ||||||
| 		$email = $_SESSION['var_email']; | if ($db->hasTable('players')) { | ||||||
| 		if($account_db->isLoaded()) { | 	if(!$player_db->isLoaded()) { | ||||||
| 			$account_db->setPassword(encrypt($password)); | 		$player->setAccountId($account_used->getId()); | ||||||
| 			$account_db->setEMail($email); | 		$player->save(); | ||||||
| 			$account_db->save(); | 	} | ||||||
|  | 	else { | ||||||
| 			$account_used = &$account_db; | 		$player_db->setAccountId($account_used->getId()); | ||||||
| 		} | 		$player_db->save(); | ||||||
| 		else { |  | ||||||
| 			$new_account = new OTS_Account(); |  | ||||||
| 			if(USE_ACCOUNT_NAME) { |  | ||||||
| 				$new_account->create($account); |  | ||||||
| 			} |  | ||||||
| 			else { |  | ||||||
| 				$new_account->create(null, $account_id); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			$new_account->setPassword(encrypt($password)); |  | ||||||
| 			$new_account->setEMail($email); |  | ||||||
|  |  | ||||||
| 			$new_account->save(); |  | ||||||
|  |  | ||||||
| 			$new_account->setCustomField('created', time()); |  | ||||||
| 			$new_account->logAction('Account created.'); |  | ||||||
|  |  | ||||||
| 			$account_used = &$new_account; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if(USE_ACCOUNT_SALT) |  | ||||||
| 			$account_used->setCustomField('salt', $salt); |  | ||||||
|  |  | ||||||
| 		$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN); |  | ||||||
| 		$account_used->setCustomField('country', 'us'); |  | ||||||
| 		if($db->hasColumn('accounts', 'group_id')) |  | ||||||
| 			$account_used->setCustomField('group_id', $groups->getHighestId()); |  | ||||||
| 		if($db->hasColumn('accounts', 'type')) |  | ||||||
| 			$account_used->setCustomField('type', 6); |  | ||||||
|  |  | ||||||
| 		if(!$player_db->isLoaded()) |  | ||||||
| 			$player->setAccountId($account_used->getId()); |  | ||||||
| 		else |  | ||||||
| 			$player_db->setAccountId($account_used->getId()); |  | ||||||
|  |  | ||||||
| 		success($locale['step_database_created_account']); |  | ||||||
|  |  | ||||||
| 		setSession('account', $account_used->getId()); |  | ||||||
| 		setSession('password', encrypt($password)); |  | ||||||
| 		setSession('remember_me', true); |  | ||||||
|  |  | ||||||
| 		if($player_db->isLoaded()) { |  | ||||||
| 			$player_db->save(); |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			$player->save(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		$player_id = 0; |  | ||||||
| 		$query = $db->query("SELECT `id` FROM `players` WHERE `name` = " . $db->quote($player_name) . ";"); |  | ||||||
| 		if($query->rowCount() == 1) { |  | ||||||
| 			$query = $query->fetch(); |  | ||||||
| 			$player_id = $query['id']; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX ."news` WHERE `title` LIKE 'Hello!';"); |  | ||||||
| 		if($query->rowCount() == 0) { |  | ||||||
| 			if(query("INSERT INTO `" . TABLE_PREFIX ."news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '1', UNIX_TIMESTAMP(), '2', 'Hello!', 'MyAAC is just READY to use!', " . $player_id . ", 'https://my-aac.org', '0'); |  | ||||||
| 	INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '2', UNIX_TIMESTAMP(), '4', 'Hello tickets!', 'https://my-aac.org', " . $player_id . ", '', '0');")) { |  | ||||||
| 				success($locale['step_database_created_news']); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		$settings = Settings::getInstance(); |  | ||||||
| 		foreach($_SESSION as $key => $value) { |  | ||||||
| 			if (in_array($key, ['var_usage', 'var_date_timezone', 'var_client'])) { |  | ||||||
| 				if ($key == 'var_usage') { |  | ||||||
| 					$key = 'anonymous_usage_statistics'; |  | ||||||
| 					$value = ((int)$value == 1 ? 'true' : 'false'); |  | ||||||
| 				} elseif ($key == 'var_date_timezone') { |  | ||||||
| 					$key = 'date_timezone'; |  | ||||||
| 				} elseif ($key == 'var_client') { |  | ||||||
| 					$key = 'client'; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				$settings->updateInDatabase('core', $key, $value); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		success('Settings saved.'); |  | ||||||
|  |  | ||||||
| 		$twig->display('install.installer.html.twig', array( |  | ||||||
| 			'url' => 'tools/7-finish.php', |  | ||||||
| 			'message' => $locale['importing_spinner'] |  | ||||||
| 		)); |  | ||||||
|  |  | ||||||
| 		if(!isset($_SESSION['installed'])) { |  | ||||||
| 			if (!array_key_exists('CI', getenv())) { |  | ||||||
| 				$report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); |  | ||||||
| 				if (function_exists('curl_version')) |  | ||||||
| 				{ |  | ||||||
| 					$curl = curl_init(); |  | ||||||
| 					curl_setopt($curl, CURLOPT_URL, $report_url); |  | ||||||
| 					curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); |  | ||||||
| 					curl_exec($curl); |  | ||||||
| 					curl_close($curl); |  | ||||||
| 				} |  | ||||||
| 				else if (ini_get('allow_url_fopen') ) { |  | ||||||
| 					file_get_contents($report_url); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			$_SESSION['installed'] = true; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		foreach($_SESSION as $key => $value) { |  | ||||||
| 			if(strpos($key, 'var_') !== false) |  | ||||||
| 				unset($_SESSION[$key]); |  | ||||||
| 		} |  | ||||||
| 		unset($_SESSION['saved']); |  | ||||||
| 		if(file_exists(CACHE . 'install.txt')) { |  | ||||||
| 			unlink(CACHE . 'install.txt'); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  |  | ||||||
|  | 	if ($db->hasTable('players')) { | ||||||
|  | 		$tmpNewsPlayer = \MyAAC\Models\Player::where('name', $player_name)->first(); | ||||||
|  | 		if($tmpNewsPlayer) { | ||||||
|  | 			$player_id = $tmpNewsPlayer->id; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	News::create([ | ||||||
|  | 		'type' => 1, | ||||||
|  | 		'date' => time(), | ||||||
|  | 		'category' => 2, | ||||||
|  | 		'title' => 'Hello!', | ||||||
|  | 		'body' => 'MyAAC is just READY to use!', | ||||||
|  | 		'player_id' => $player_id, | ||||||
|  | 		'comments' => 'https://my-aac.org', | ||||||
|  | 		'hide' => 0, | ||||||
|  | 	]); | ||||||
|  |  | ||||||
|  | 	News::create([ | ||||||
|  | 		'type' => 2, | ||||||
|  | 		'date' => time(), | ||||||
|  | 		'category' => 4, | ||||||
|  | 		'title' => 'Hello tickers!', | ||||||
|  | 		'body' => 'https://my-aac.org', | ||||||
|  | 		'player_id' => $player_id, | ||||||
|  | 		'comments' => '', | ||||||
|  | 		'hide' => 0, | ||||||
|  | 	]); | ||||||
|  |  | ||||||
|  | 	success($locale['step_database_created_news']); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $settings = Settings::getInstance(); | ||||||
|  | foreach($_SESSION as $key => $value) { | ||||||
|  | 	if (in_array($key, ['var_usage', 'var_date_timezone', 'var_client'])) { | ||||||
|  | 		if ($key == 'var_usage') { | ||||||
|  | 			$key = 'anonymous_usage_statistics'; | ||||||
|  | 			$value = ((int)$value == 1 ? 'true' : 'false'); | ||||||
|  | 		} elseif ($key == 'var_date_timezone') { | ||||||
|  | 			$key = 'date_timezone'; | ||||||
|  | 		} elseif ($key == 'var_client') { | ||||||
|  | 			$key = 'client'; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		$settings->updateInDatabase('core', $key, $value); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | success('Settings saved.'); | ||||||
|  |  | ||||||
|  | $twig->display('install.installer.html.twig', array( | ||||||
|  | 	'url' => 'tools/7-finish.php', | ||||||
|  | 	'message' => $locale['importing_spinner'] | ||||||
|  | )); | ||||||
|  |  | ||||||
|  | if(!isset($_SESSION['installed'])) { | ||||||
|  | 	if (!array_key_exists('CI', getenv())) { | ||||||
|  | 		$report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); | ||||||
|  | 		if (function_exists('curl_version')) | ||||||
|  | 		{ | ||||||
|  | 			$curl = curl_init(); | ||||||
|  | 			curl_setopt($curl, CURLOPT_URL, $report_url); | ||||||
|  | 			curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); | ||||||
|  | 			curl_exec($curl); | ||||||
|  | 			curl_close($curl); | ||||||
|  | 		} | ||||||
|  | 		else if (ini_get('allow_url_fopen') ) { | ||||||
|  | 			file_get_contents($report_url); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$_SESSION['installed'] = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | foreach($_SESSION as $key => $value) { | ||||||
|  | 	if(strpos($key, 'var_') !== false) | ||||||
|  | 		unset($_SESSION[$key]); | ||||||
|  | } | ||||||
|  | unset($_SESSION['saved']); | ||||||
|  | if(file_exists(CACHE . 'install.txt')) { | ||||||
|  | 	unlink(CACHE . 'install.txt'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $hooks->trigger(HOOK_INSTALL_FINISH_END); | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
| 	<title>MyAAC - <?php echo $locale['installation']; ?></title> | 	<title>MyAAC - <?php echo $locale['installation']; ?></title> | ||||||
| 	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> | 	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> | ||||||
| 	<link rel="stylesheet" type="text/css" href="template/style.css" /> | 	<link rel="stylesheet" type="text/css" href="template/style.css" /> | ||||||
| 	<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/js/jquery.min.js"></script> | 	<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/ext/jquery/jquery.min.js"></script> | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,8 +11,10 @@ $error = false; | |||||||
| require BASE . 'install/includes/config.php'; | require BASE . 'install/includes/config.php'; | ||||||
|  |  | ||||||
| ini_set('max_execution_time', 300); | ini_set('max_execution_time', 300); | ||||||
|  |  | ||||||
|  | @ob_end_flush(); | ||||||
| ob_implicit_flush(); | ob_implicit_flush(); | ||||||
| ob_end_flush(); |  | ||||||
| header('X-Accel-Buffering: no'); | header('X-Accel-Buffering: no'); | ||||||
|  |  | ||||||
| if(!$error) { | if(!$error) { | ||||||
| @@ -30,6 +32,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,73 +141,74 @@ 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')) { | ||||||
| 		success($locale['step_database_modifying_field'] . ' guilds.checkdata...'); | 		if (query("ALTER TABLE `guilds` MODIFY `checkdata` INT NOT NULL DEFAULT 0;")) | ||||||
| } | 			success($locale['step_database_modifying_field'] . ' guilds.checkdata...'); | ||||||
|  |  | ||||||
| if(!$db->hasColumn('guilds', 'motd')) { |  | ||||||
| 	if(query("ALTER TABLE `guilds` ADD `motd` VARCHAR(255) NOT NULL DEFAULT '';")) |  | ||||||
| 		success($locale['step_database_adding_field'] . ' guilds.motd...'); |  | ||||||
| } |  | ||||||
| else { |  | ||||||
| 	if(query("ALTER TABLE `guilds` MODIFY `motd` VARCHAR(255) NOT NULL DEFAULT '';")) |  | ||||||
| 		success($locale['step_database_modifying_field'] . ' guilds.motd...'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if(!$db->hasColumn('guilds', 'description')) { |  | ||||||
| 	if(query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;")) |  | ||||||
| 		success($locale['step_database_adding_field'] . ' guilds.description...'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if($db->hasColumn('guilds', 'logo_gfx_name')) { |  | ||||||
| 	if(query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) { |  | ||||||
| 		$tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']); |  | ||||||
| 		$tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp); |  | ||||||
| 		success($tmp); |  | ||||||
| 	} | 	} | ||||||
| } |  | ||||||
| else if(!$db->hasColumn('guilds', 'logo_name')) { |  | ||||||
| 	if(query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) |  | ||||||
| 		success($locale['step_database_adding_field'] . ' guilds.logo_name...'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if(!$db->hasColumn('players', 'created')) { | 	if (!$db->hasColumn('guilds', 'motd')) { | ||||||
| 	if(query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;")) | 		if (query("ALTER TABLE `guilds` ADD `motd` VARCHAR(255) NOT NULL DEFAULT '';")) | ||||||
| 		success($locale['step_database_adding_field'] . ' players.created...'); | 			success($locale['step_database_adding_field'] . ' guilds.motd...'); | ||||||
| } | 	} else { | ||||||
|  | 		if (query("ALTER TABLE `guilds` MODIFY `motd` VARCHAR(255) NOT NULL DEFAULT '';")) | ||||||
|  | 			success($locale['step_database_modifying_field'] . ' guilds.motd...'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| if(!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion')) { | 	if (!$db->hasColumn('guilds', 'description')) { | ||||||
| 	if(query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;")) | 		if (query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;")) | ||||||
| 		success($locale['step_database_adding_field'] . ' players.deleted...'); | 			success($locale['step_database_adding_field'] . ' guilds.description...'); | ||||||
| } | 	} | ||||||
|  |  | ||||||
| if($db->hasColumn('players', 'hide_char')) { | 	if ($db->hasColumn('guilds', 'logo_gfx_name')) { | ||||||
| 	if(!$db->hasColumn('players', 'hidden')) { | 		if (query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) { | ||||||
| 		if(query("ALTER TABLE `players` CHANGE `hide_char` `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) { | 			$tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']); | ||||||
| 			$tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']); | 			$tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp); | ||||||
| 			$tmp = str_replace('$FIELD_NEW$', 'players.hidden', $tmp); |  | ||||||
| 			success($tmp); | 			success($tmp); | ||||||
| 		} | 		} | ||||||
|  | 	} else if (!$db->hasColumn('guilds', 'logo_name')) { | ||||||
|  | 		if (query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) | ||||||
|  | 			success($locale['step_database_adding_field'] . ' guilds.logo_name...'); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| else if(!$db->hasColumn('players', 'hidden')) { |  | ||||||
| 	if(query("ALTER TABLE `players` ADD `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) |  | ||||||
| 		success($locale['step_database_adding_field'] . ' players.hidden...'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if(!$db->hasColumn('players', 'comment')) { | if ($db->hasTable('players')) { | ||||||
| 	if(query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;")) | 	if (!$db->hasColumn('players', 'created')) { | ||||||
| 		success($locale['step_database_adding_field'] . ' players.comment...'); | 		if (query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;")) | ||||||
| } | 			success($locale['step_database_adding_field'] . ' players.created...'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| if($db->hasColumn('players', 'rank_id')) { | 	if (!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion')) { | ||||||
| 	if(query("ALTER TABLE players MODIFY `rank_id` INT(11) NOT NULL DEFAULT 0;")) | 		if (query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;")) | ||||||
| 		success($locale['step_database_modifying_field'] . ' players.rank_id...'); | 			success($locale['step_database_adding_field'] . ' players.deleted...'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if($db->hasColumn('players', 'guildnick')) { | 	if ($db->hasColumn('players', 'hide_char')) { | ||||||
| 		if(query("ALTER TABLE players MODIFY `guildnick` VARCHAR(255) NOT NULL DEFAULT '';")) { | 		if (!$db->hasColumn('players', 'hide')) { | ||||||
| 			success($locale['step_database_modifying_field'] . ' players.guildnick...'); | 			if (query("ALTER TABLE `players` CHANGE `hide_char` `hide` TINYINT(1) NOT NULL DEFAULT 0;")) { | ||||||
|  | 				$tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']); | ||||||
|  | 				$tmp = str_replace('$FIELD_NEW$', 'players.hide', $tmp); | ||||||
|  | 				success($tmp); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} else if (!$db->hasColumn('players', 'hide')) { | ||||||
|  | 		if (query("ALTER TABLE `players` ADD `hide` TINYINT(1) NOT NULL DEFAULT 0;")) | ||||||
|  | 			success($locale['step_database_adding_field'] . ' players.hide...'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!$db->hasColumn('players', 'comment')) { | ||||||
|  | 		if (query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;")) | ||||||
|  | 			success($locale['step_database_adding_field'] . ' players.comment...'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ($db->hasColumn('players', 'rank_id')) { | ||||||
|  | 		if (query("ALTER TABLE players MODIFY `rank_id` INT(11) NOT NULL DEFAULT 0;")) | ||||||
|  | 			success($locale['step_database_modifying_field'] . ' players.rank_id...'); | ||||||
|  |  | ||||||
|  | 		if ($db->hasColumn('players', 'guildnick')) { | ||||||
|  | 			if (query("ALTER TABLE players MODIFY `guildnick` VARCHAR(255) NOT NULL DEFAULT '';")) { | ||||||
|  | 				success($locale['step_database_modifying_field'] . ' players.guildnick...'); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,10 @@ | |||||||
| <?php | <?php | ||||||
| define('MYAAC_INSTALL', true); | define('MYAAC_INSTALL', true); | ||||||
|  |  | ||||||
|  | use MyAAC\DataLoader; | ||||||
|  | use MyAAC\Models\FAQ as ModelsFAQ; | ||||||
|  | use MyAAC\Plugins; | ||||||
|  |  | ||||||
| require_once '../../common.php'; | require_once '../../common.php'; | ||||||
|  |  | ||||||
| require SYSTEM . 'functions.php'; | require SYSTEM . 'functions.php'; | ||||||
| @@ -8,8 +12,10 @@ require BASE . 'install/includes/functions.php'; | |||||||
| require BASE . 'install/includes/locale.php'; | require BASE . 'install/includes/locale.php'; | ||||||
|  |  | ||||||
| ini_set('max_execution_time', 300); | ini_set('max_execution_time', 300); | ||||||
|  |  | ||||||
|  | @ob_end_flush(); | ||||||
| ob_implicit_flush(); | ob_implicit_flush(); | ||||||
| ob_end_flush(); |  | ||||||
| header('X-Accel-Buffering: no'); | header('X-Accel-Buffering: no'); | ||||||
| /* | /* | ||||||
| if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) { | if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) { | ||||||
| @@ -19,51 +25,59 @@ if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['save | |||||||
|  |  | ||||||
| require SYSTEM . 'init.php'; | require SYSTEM . 'init.php'; | ||||||
|  |  | ||||||
| $deleted = 'deleted'; | if ($db->hasTable('players')) { | ||||||
| if($db->hasColumn('players', 'deletion')) | 	$deleted = 'deleted'; | ||||||
| 	$deleted = 'deletion'; | 	if ($db->hasColumn('players', '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('kathrine', require TEMPLATES . 'kathrine/menus.php'); | ||||||
| Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php'); | Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php'); | ||||||
|  |  | ||||||
| require LIBS . 'DataLoader.php'; |  | ||||||
| DataLoader::setLocale($locale); | DataLoader::setLocale($locale); | ||||||
| DataLoader::load(); | DataLoader::load(); | ||||||
|  |  | ||||||
| // 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(); | ||||||
|  |  | ||||||
| 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 +85,10 @@ if(ModelsFAQ::count() == 0) { | |||||||
| 	]); | 	]); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | $hooks->trigger(HOOK_INSTALL_FINISH); | ||||||
|  |  | ||||||
|  | $db->setClearCacheAfter(true); | ||||||
|  |  | ||||||
| $locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']); | $locale['step_finish_desc'] = str_replace('$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']); | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								login.php
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								login.php
									
									
									
									
									
								
							| @@ -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'; | ||||||
| @@ -130,12 +131,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 +163,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'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,22 +10,25 @@ 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 | 	location /vendor { | ||||||
| 	location ~ /\.ht { | 		deny all; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	# block .htaccess, CHANGELOG.md, composer.json etc. | ||||||
|  | 	# this is to prevent finding software versions | ||||||
|  | 	location ~\.(ht|md|json|dist)$ { | ||||||
| 		deny all; | 		deny all; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	# block git files and folders | 	# block git files and folders | ||||||
| 	location ~ /\.git { | 	location ~ /\.git { | ||||||
| 		return 404; |  | ||||||
| 		deny all; | 		deny all; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	location / { | 	location / { | ||||||
| 		try_files $uri $uri/ /index.php; | 		try_files $uri $uri/ /index.php?$query_string;; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	location ~ \.php$ { | 	location ~ \.php$ { | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								npm-post-install.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								npm-post-install.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | const fse = require('fs-extra'); | ||||||
|  | const path = require('path'); | ||||||
|  |  | ||||||
|  | const nodeModulesDir = path.join(__dirname, 'node_modules'); | ||||||
|  | const publicDir = path.join(__dirname, 'tools/ext'); | ||||||
|  |  | ||||||
|  | fse.emptyDirSync(path.join(publicDir, 'jquery')); | ||||||
|  | fse.emptyDirSync(path.join(publicDir, 'jquery-ui')); | ||||||
|  | fse.emptyDirSync(path.join(publicDir, 'bootstrap')); | ||||||
|  | fse.emptyDirSync(path.join(publicDir, 'tinymce')); | ||||||
|  | fse.emptyDirSync(path.join(publicDir, 'tinymce-jquery')); | ||||||
|  | fse.copySync(path.join(nodeModulesDir, 'jquery', 'dist'), path.join(publicDir, 'jquery'), { overwrite: true }); | ||||||
|  | fse.copySync(path.join(nodeModulesDir, 'jquery-ui', 'dist'), path.join(publicDir, 'jquery-ui'), { overwrite: true }); | ||||||
|  | fse.copySync(path.join(nodeModulesDir, 'bootstrap', 'dist'), path.join(publicDir, 'bootstrap'), { overwrite: true }); | ||||||
|  | fse.copySync(path.join(nodeModulesDir, 'tinymce'), path.join(publicDir, 'tinymce'), { overwrite: true }); | ||||||
|  | fse.copySync(path.join(nodeModulesDir, '@tinymce', 'tinymce-jquery', 'dist'), path.join(publicDir, 'tinymce-jquery'), { overwrite: true }); | ||||||
							
								
								
									
										433
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										433
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -4,6 +4,15 @@ | |||||||
|   "requires": true, |   "requires": true, | ||||||
|   "packages": { |   "packages": { | ||||||
|     "": { |     "": { | ||||||
|  |       "hasInstallScript": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "@tinymce/tinymce-jquery": "^2.1.0", | ||||||
|  |         "bootstrap": "^4.6.2", | ||||||
|  |         "fs-extra": "^11.2.0", | ||||||
|  |         "jquery": "^3.7.1", | ||||||
|  |         "jquery-ui": "^1.13.2", | ||||||
|  |         "tinymce": "^6.8.3" | ||||||
|  |       }, | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "cypress": "^12.12.0" |         "cypress": "^12.12.0" | ||||||
|       } |       } | ||||||
| @@ -19,9 +28,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@cypress/request": { |     "node_modules/@cypress/request": { | ||||||
|       "version": "2.88.11", |       "version": "2.88.12", | ||||||
|       "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz", |       "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.12.tgz", | ||||||
|       "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==", |       "integrity": "sha512-tOn+0mDZxASFM+cuAP9szGUGPI1HwWVSvdzm7V4cCsPdFTx6qMj29CwaQmRAMIEhORIUBFBsYROYJcveK4uOjA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "aws-sign2": "~0.7.0", |         "aws-sign2": "~0.7.0", | ||||||
| @@ -39,7 +48,7 @@ | |||||||
|         "performance-now": "^2.1.0", |         "performance-now": "^2.1.0", | ||||||
|         "qs": "~6.10.3", |         "qs": "~6.10.3", | ||||||
|         "safe-buffer": "^5.1.2", |         "safe-buffer": "^5.1.2", | ||||||
|         "tough-cookie": "~2.5.0", |         "tough-cookie": "^4.1.3", | ||||||
|         "tunnel-agent": "^0.6.0", |         "tunnel-agent": "^0.6.0", | ||||||
|         "uuid": "^8.3.2" |         "uuid": "^8.3.2" | ||||||
|       }, |       }, | ||||||
| @@ -66,10 +75,15 @@ | |||||||
|         "ms": "^2.1.1" |         "ms": "^2.1.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@tinymce/tinymce-jquery": { | ||||||
|  |       "version": "2.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@tinymce/tinymce-jquery/-/tinymce-jquery-2.1.0.tgz", | ||||||
|  |       "integrity": "sha512-ynfgfL/n5/Us7h3AnJL3mAwsShuE/USvAJFOdilJDkZuVCypWSwVVo3E3wIqSzDGvqyU+293ok1+sD+jxraT8w==" | ||||||
|  |     }, | ||||||
|     "node_modules/@types/node": { |     "node_modules/@types/node": { | ||||||
|       "version": "14.18.47", |       "version": "16.18.82", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.47.tgz", |       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz", | ||||||
|       "integrity": "sha512-OuJi8bIng4wYHHA3YpKauL58dZrPxro3d0tabPHyiNF8rKfGKuVfr83oFlPLmKri1cX+Z3cJP39GXmnqkP11Gw==", |       "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/@types/sinonjs__fake-timers": { |     "node_modules/@types/sinonjs__fake-timers": { | ||||||
| @@ -79,15 +93,15 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/@types/sizzle": { |     "node_modules/@types/sizzle": { | ||||||
|       "version": "2.3.3", |       "version": "2.3.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", |       "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", | ||||||
|       "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", |       "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/@types/yauzl": { |     "node_modules/@types/yauzl": { | ||||||
|       "version": "2.10.0", |       "version": "2.10.3", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", |       "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", | ||||||
|       "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", |       "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
| @@ -203,9 +217,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/async": { |     "node_modules/async": { | ||||||
|       "version": "3.2.4", |       "version": "3.2.5", | ||||||
|       "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", |       "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", | ||||||
|       "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", |       "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/asynckit": { |     "node_modules/asynckit": { | ||||||
| @@ -285,6 +299,25 @@ | |||||||
|       "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", |       "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/bootstrap": { | ||||||
|  |       "version": "4.6.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", | ||||||
|  |       "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==", | ||||||
|  |       "funding": [ | ||||||
|  |         { | ||||||
|  |           "type": "github", | ||||||
|  |           "url": "https://github.com/sponsors/twbs" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "opencollective", | ||||||
|  |           "url": "https://opencollective.com/bootstrap" | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "jquery": "1.9.1 - 3", | ||||||
|  |         "popper.js": "^1.16.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/brace-expansion": { |     "node_modules/brace-expansion": { | ||||||
|       "version": "1.1.11", |       "version": "1.1.11", | ||||||
|       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", |       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||||||
| @@ -329,22 +362,28 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/cachedir": { |     "node_modules/cachedir": { | ||||||
|       "version": "2.3.0", |       "version": "2.4.0", | ||||||
|       "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", |       "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", | ||||||
|       "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", |       "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">=6" |         "node": ">=6" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/call-bind": { |     "node_modules/call-bind": { | ||||||
|       "version": "1.0.2", |       "version": "1.0.7", | ||||||
|       "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", |       "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", | ||||||
|       "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", |       "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "function-bind": "^1.1.1", |         "es-define-property": "^1.0.0", | ||||||
|         "get-intrinsic": "^1.0.2" |         "es-errors": "^1.3.0", | ||||||
|  |         "function-bind": "^1.1.2", | ||||||
|  |         "get-intrinsic": "^1.2.4", | ||||||
|  |         "set-function-length": "^1.2.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.4" | ||||||
|       }, |       }, | ||||||
|       "funding": { |       "funding": { | ||||||
|         "url": "https://github.com/sponsors/ljharb" |         "url": "https://github.com/sponsors/ljharb" | ||||||
| @@ -394,9 +433,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/ci-info": { |     "node_modules/ci-info": { | ||||||
|       "version": "3.8.0", |       "version": "3.9.0", | ||||||
|       "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", |       "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", | ||||||
|       "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", |       "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "funding": [ |       "funding": [ | ||||||
|         { |         { | ||||||
| @@ -541,15 +580,15 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/cypress": { |     "node_modules/cypress": { | ||||||
|       "version": "12.12.0", |       "version": "12.17.4", | ||||||
|       "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.12.0.tgz", |       "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.17.4.tgz", | ||||||
|       "integrity": "sha512-UU5wFQ7SMVCR/hyKok/KmzG6fpZgBHHfrXcHzDmPHWrT+UUetxFzQgt7cxCszlwfozckzwkd22dxMwl/vNkWRw==", |       "integrity": "sha512-gAN8Pmns9MA5eCDFSDJXWKUpaL3IDd89N9TtIupjYnzLSmlpVr+ZR+vb4U/qaMp+lB6tBvAmt7504c3Z4RU5KQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "hasInstallScript": true, |       "hasInstallScript": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@cypress/request": "^2.88.10", |         "@cypress/request": "2.88.12", | ||||||
|         "@cypress/xvfb": "^1.2.4", |         "@cypress/xvfb": "^1.2.4", | ||||||
|         "@types/node": "^14.14.31", |         "@types/node": "^16.18.39", | ||||||
|         "@types/sinonjs__fake-timers": "8.1.1", |         "@types/sinonjs__fake-timers": "8.1.1", | ||||||
|         "@types/sizzle": "^2.3.2", |         "@types/sizzle": "^2.3.2", | ||||||
|         "arch": "^2.2.0", |         "arch": "^2.2.0", | ||||||
| @@ -582,9 +621,10 @@ | |||||||
|         "minimist": "^1.2.8", |         "minimist": "^1.2.8", | ||||||
|         "ospath": "^1.2.2", |         "ospath": "^1.2.2", | ||||||
|         "pretty-bytes": "^5.6.0", |         "pretty-bytes": "^5.6.0", | ||||||
|  |         "process": "^0.11.10", | ||||||
|         "proxy-from-env": "1.0.0", |         "proxy-from-env": "1.0.0", | ||||||
|         "request-progress": "^3.0.0", |         "request-progress": "^3.0.0", | ||||||
|         "semver": "^7.3.2", |         "semver": "^7.5.3", | ||||||
|         "supports-color": "^8.1.1", |         "supports-color": "^8.1.1", | ||||||
|         "tmp": "~0.2.1", |         "tmp": "~0.2.1", | ||||||
|         "untildify": "^4.0.0", |         "untildify": "^4.0.0", | ||||||
| @@ -597,6 +637,21 @@ | |||||||
|         "node": "^14.0.0 || ^16.0.0 || >=18.0.0" |         "node": "^14.0.0 || ^16.0.0 || >=18.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/cypress/node_modules/fs-extra": { | ||||||
|  |       "version": "9.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", | ||||||
|  |       "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "at-least-node": "^1.0.0", | ||||||
|  |         "graceful-fs": "^4.2.0", | ||||||
|  |         "jsonfile": "^6.0.1", | ||||||
|  |         "universalify": "^2.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/dashdash": { |     "node_modules/dashdash": { | ||||||
|       "version": "1.14.1", |       "version": "1.14.1", | ||||||
|       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", |       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", | ||||||
| @@ -610,9 +665,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/dayjs": { |     "node_modules/dayjs": { | ||||||
|       "version": "1.11.7", |       "version": "1.11.10", | ||||||
|       "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", |       "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", | ||||||
|       "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==", |       "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/debug": { |     "node_modules/debug": { | ||||||
| @@ -632,6 +687,23 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/define-data-property": { | ||||||
|  |       "version": "1.1.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", | ||||||
|  |       "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", | ||||||
|  |       "dev": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "es-define-property": "^1.0.0", | ||||||
|  |         "es-errors": "^1.3.0", | ||||||
|  |         "gopd": "^1.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.4" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/sponsors/ljharb" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/delayed-stream": { |     "node_modules/delayed-stream": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", | ||||||
| @@ -667,17 +739,39 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/enquirer": { |     "node_modules/enquirer": { | ||||||
|       "version": "2.3.6", |       "version": "2.4.1", | ||||||
|       "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", |       "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", | ||||||
|       "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", |       "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "ansi-colors": "^4.1.1" |         "ansi-colors": "^4.1.1", | ||||||
|  |         "strip-ansi": "^6.0.1" | ||||||
|       }, |       }, | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">=8.6" |         "node": ">=8.6" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/es-define-property": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", | ||||||
|  |       "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "get-intrinsic": "^1.2.4" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/es-errors": { | ||||||
|  |       "version": "1.3.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", | ||||||
|  |       "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/escape-string-regexp": { |     "node_modules/escape-string-regexp": { | ||||||
|       "version": "1.0.5", |       "version": "1.0.5", | ||||||
|       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", |       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", | ||||||
| @@ -811,18 +905,16 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/fs-extra": { |     "node_modules/fs-extra": { | ||||||
|       "version": "9.1.0", |       "version": "11.2.0", | ||||||
|       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", |       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", | ||||||
|       "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", |       "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "at-least-node": "^1.0.0", |  | ||||||
|         "graceful-fs": "^4.2.0", |         "graceful-fs": "^4.2.0", | ||||||
|         "jsonfile": "^6.0.1", |         "jsonfile": "^6.0.1", | ||||||
|         "universalify": "^2.0.0" |         "universalify": "^2.0.0" | ||||||
|       }, |       }, | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">=10" |         "node": ">=14.14" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/fs.realpath": { |     "node_modules/fs.realpath": { | ||||||
| @@ -832,21 +924,28 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/function-bind": { |     "node_modules/function-bind": { | ||||||
|       "version": "1.1.1", |       "version": "1.1.2", | ||||||
|       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", |       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", | ||||||
|       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", |       "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", | ||||||
|       "dev": true |       "dev": true, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/sponsors/ljharb" | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/get-intrinsic": { |     "node_modules/get-intrinsic": { | ||||||
|       "version": "1.2.1", |       "version": "1.2.4", | ||||||
|       "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", |       "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", | ||||||
|       "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", |       "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "function-bind": "^1.1.1", |         "es-errors": "^1.3.0", | ||||||
|         "has": "^1.0.3", |         "function-bind": "^1.1.2", | ||||||
|         "has-proto": "^1.0.1", |         "has-proto": "^1.0.1", | ||||||
|         "has-symbols": "^1.0.3" |         "has-symbols": "^1.0.3", | ||||||
|  |         "hasown": "^2.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.4" | ||||||
|       }, |       }, | ||||||
|       "funding": { |       "funding": { | ||||||
|         "url": "https://github.com/sponsors/ljharb" |         "url": "https://github.com/sponsors/ljharb" | ||||||
| @@ -920,23 +1019,22 @@ | |||||||
|         "url": "https://github.com/sponsors/sindresorhus" |         "url": "https://github.com/sponsors/sindresorhus" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/gopd": { | ||||||
|  |       "version": "1.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", | ||||||
|  |       "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "get-intrinsic": "^1.1.3" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/sponsors/ljharb" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/graceful-fs": { |     "node_modules/graceful-fs": { | ||||||
|       "version": "4.2.11", |       "version": "4.2.11", | ||||||
|       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", |       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", | ||||||
|       "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", |       "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" | ||||||
|       "dev": true |  | ||||||
|     }, |  | ||||||
|     "node_modules/has": { |  | ||||||
|       "version": "1.0.3", |  | ||||||
|       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", |  | ||||||
|       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", |  | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |  | ||||||
|         "function-bind": "^1.1.1" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": ">= 0.4.0" |  | ||||||
|       } |  | ||||||
|     }, |     }, | ||||||
|     "node_modules/has-flag": { |     "node_modules/has-flag": { | ||||||
|       "version": "4.0.0", |       "version": "4.0.0", | ||||||
| @@ -947,6 +1045,18 @@ | |||||||
|         "node": ">=8" |         "node": ">=8" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/has-property-descriptors": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", | ||||||
|  |       "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "es-define-property": "^1.0.0" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/sponsors/ljharb" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/has-proto": { |     "node_modules/has-proto": { | ||||||
|       "version": "1.0.1", |       "version": "1.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", |       "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", | ||||||
| @@ -971,6 +1081,18 @@ | |||||||
|         "url": "https://github.com/sponsors/ljharb" |         "url": "https://github.com/sponsors/ljharb" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/hasown": { | ||||||
|  |       "version": "2.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", | ||||||
|  |       "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "function-bind": "^1.1.2" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/http-signature": { |     "node_modules/http-signature": { | ||||||
|       "version": "1.3.6", |       "version": "1.3.6", | ||||||
|       "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", |       "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", | ||||||
| @@ -1136,6 +1258,19 @@ | |||||||
|       "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", |       "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/jquery": { | ||||||
|  |       "version": "3.7.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", | ||||||
|  |       "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/jquery-ui": { | ||||||
|  |       "version": "1.13.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.13.2.tgz", | ||||||
|  |       "integrity": "sha512-wBZPnqWs5GaYJmo1Jj0k/mrSkzdQzKDwhXNtHKcBdAcKVxMM3KNYFq+iJ2i1rwiG53Z8M4mTn3Qxrm17uH1D4Q==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "jquery": ">=1.8.0 <4.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/jsbn": { |     "node_modules/jsbn": { | ||||||
|       "version": "0.1.1", |       "version": "0.1.1", | ||||||
|       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", |       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", | ||||||
| @@ -1158,7 +1293,6 @@ | |||||||
|       "version": "6.1.0", |       "version": "6.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", |       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", | ||||||
|       "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", |       "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "universalify": "^2.0.0" |         "universalify": "^2.0.0" | ||||||
|       }, |       }, | ||||||
| @@ -1382,9 +1516,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/object-inspect": { |     "node_modules/object-inspect": { | ||||||
|       "version": "1.12.3", |       "version": "1.13.1", | ||||||
|       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", |       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", | ||||||
|       "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", |       "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "funding": { |       "funding": { | ||||||
|         "url": "https://github.com/sponsors/ljharb" |         "url": "https://github.com/sponsors/ljharb" | ||||||
| @@ -1474,6 +1608,17 @@ | |||||||
|         "node": ">=0.10.0" |         "node": ">=0.10.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/popper.js": { | ||||||
|  |       "version": "1.16.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", | ||||||
|  |       "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", | ||||||
|  |       "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", | ||||||
|  |       "peer": true, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "opencollective", | ||||||
|  |         "url": "https://opencollective.com/popperjs" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/pretty-bytes": { |     "node_modules/pretty-bytes": { | ||||||
|       "version": "5.6.0", |       "version": "5.6.0", | ||||||
|       "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", |       "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", | ||||||
| @@ -1486,6 +1631,15 @@ | |||||||
|         "url": "https://github.com/sponsors/sindresorhus" |         "url": "https://github.com/sponsors/sindresorhus" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/process": { | ||||||
|  |       "version": "0.11.10", | ||||||
|  |       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", | ||||||
|  |       "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", | ||||||
|  |       "dev": true, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.6.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/proxy-from-env": { |     "node_modules/proxy-from-env": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", | ||||||
| @@ -1509,9 +1663,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/punycode": { |     "node_modules/punycode": { | ||||||
|       "version": "2.3.0", |       "version": "2.3.1", | ||||||
|       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", |       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", | ||||||
|       "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", |       "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">=6" |         "node": ">=6" | ||||||
| @@ -1532,6 +1686,12 @@ | |||||||
|         "url": "https://github.com/sponsors/ljharb" |         "url": "https://github.com/sponsors/ljharb" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/querystringify": { | ||||||
|  |       "version": "2.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", | ||||||
|  |       "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|     "node_modules/request-progress": { |     "node_modules/request-progress": { | ||||||
|       "version": "3.0.0", |       "version": "3.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", |       "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", | ||||||
| @@ -1541,6 +1701,12 @@ | |||||||
|         "throttleit": "^1.0.0" |         "throttleit": "^1.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/requires-port": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", | ||||||
|  |       "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|     "node_modules/restore-cursor": { |     "node_modules/restore-cursor": { | ||||||
|       "version": "3.1.0", |       "version": "3.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", |       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", | ||||||
| @@ -1555,9 +1721,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/rfdc": { |     "node_modules/rfdc": { | ||||||
|       "version": "1.3.0", |       "version": "1.3.1", | ||||||
|       "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", |       "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", | ||||||
|       "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", |       "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/rimraf": { |     "node_modules/rimraf": { | ||||||
| @@ -1611,9 +1777,9 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/semver": { |     "node_modules/semver": { | ||||||
|       "version": "7.5.1", |       "version": "7.6.0", | ||||||
|       "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", |       "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", | ||||||
|       "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", |       "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "lru-cache": "^6.0.0" |         "lru-cache": "^6.0.0" | ||||||
| @@ -1625,6 +1791,23 @@ | |||||||
|         "node": ">=10" |         "node": ">=10" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/set-function-length": { | ||||||
|  |       "version": "1.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", | ||||||
|  |       "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", | ||||||
|  |       "dev": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "define-data-property": "^1.1.2", | ||||||
|  |         "es-errors": "^1.3.0", | ||||||
|  |         "function-bind": "^1.1.2", | ||||||
|  |         "get-intrinsic": "^1.2.3", | ||||||
|  |         "gopd": "^1.0.1", | ||||||
|  |         "has-property-descriptors": "^1.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/shebang-command": { |     "node_modules/shebang-command": { | ||||||
|       "version": "2.0.0", |       "version": "2.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", |       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||||||
| @@ -1647,14 +1830,18 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/side-channel": { |     "node_modules/side-channel": { | ||||||
|       "version": "1.0.4", |       "version": "1.0.5", | ||||||
|       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", |       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", | ||||||
|       "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", |       "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "call-bind": "^1.0.0", |         "call-bind": "^1.0.6", | ||||||
|         "get-intrinsic": "^1.0.2", |         "es-errors": "^1.3.0", | ||||||
|         "object-inspect": "^1.9.0" |         "get-intrinsic": "^1.2.4", | ||||||
|  |         "object-inspect": "^1.13.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.4" | ||||||
|       }, |       }, | ||||||
|       "funding": { |       "funding": { | ||||||
|         "url": "https://github.com/sponsors/ljharb" |         "url": "https://github.com/sponsors/ljharb" | ||||||
| @@ -1681,9 +1868,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/sshpk": { |     "node_modules/sshpk": { | ||||||
|       "version": "1.17.0", |       "version": "1.18.0", | ||||||
|       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", |       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", | ||||||
|       "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", |       "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "asn1": "~0.2.3", |         "asn1": "~0.2.3", | ||||||
| @@ -1756,10 +1943,13 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/throttleit": { |     "node_modules/throttleit": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", | ||||||
|       "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==", |       "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", | ||||||
|       "dev": true |       "dev": true, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/sponsors/sindresorhus" | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/through": { |     "node_modules/through": { | ||||||
|       "version": "2.3.8", |       "version": "2.3.8", | ||||||
| @@ -1767,6 +1957,11 @@ | |||||||
|       "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", |       "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/tinymce": { | ||||||
|  |       "version": "6.8.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.8.3.tgz", | ||||||
|  |       "integrity": "sha512-3fCHKAeqT+xNwBVESf6iDbDV0VNwZNmfrkx9c/6Gz5iB8piMfaO6s7FvoiTrj1hf1gVbfyLTnz1DooI6DhgINQ==" | ||||||
|  |     }, | ||||||
|     "node_modules/tmp": { |     "node_modules/tmp": { | ||||||
|       "version": "0.2.1", |       "version": "0.2.1", | ||||||
|       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", |       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", | ||||||
| @@ -1780,22 +1975,33 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/tough-cookie": { |     "node_modules/tough-cookie": { | ||||||
|       "version": "2.5.0", |       "version": "4.1.3", | ||||||
|       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", |       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", | ||||||
|       "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", |       "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "psl": "^1.1.28", |         "psl": "^1.1.33", | ||||||
|         "punycode": "^2.1.1" |         "punycode": "^2.1.1", | ||||||
|  |         "universalify": "^0.2.0", | ||||||
|  |         "url-parse": "^1.5.3" | ||||||
|       }, |       }, | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">=0.8" |         "node": ">=6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/tough-cookie/node_modules/universalify": { | ||||||
|  |       "version": "0.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", | ||||||
|  |       "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 4.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/tslib": { |     "node_modules/tslib": { | ||||||
|       "version": "2.5.1", |       "version": "2.6.2", | ||||||
|       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.1.tgz", |       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", | ||||||
|       "integrity": "sha512-KaI6gPil5m9vF7DKaoXxx1ia9fxS4qG5YveErRRVknPDXXriu5M8h48YRjB6h5ZUOKuAKlSJYb0GaDe8I39fRw==", |       "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/tunnel-agent": { |     "node_modules/tunnel-agent": { | ||||||
| @@ -1829,10 +2035,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/universalify": { |     "node_modules/universalify": { | ||||||
|       "version": "2.0.0", |       "version": "2.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", |       "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", | ||||||
|       "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", |       "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", | ||||||
|       "dev": true, |  | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">= 10.0.0" |         "node": ">= 10.0.0" | ||||||
|       } |       } | ||||||
| @@ -1846,6 +2051,16 @@ | |||||||
|         "node": ">=8" |         "node": ">=8" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/url-parse": { | ||||||
|  |       "version": "1.5.10", | ||||||
|  |       "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", | ||||||
|  |       "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "dependencies": { | ||||||
|  |         "querystringify": "^2.1.1", | ||||||
|  |         "requires-port": "^1.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/uuid": { |     "node_modules/uuid": { | ||||||
|       "version": "8.3.2", |       "version": "8.3.2", | ||||||
|       "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", |       "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,8 +1,17 @@ | |||||||
| { | { | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "cypress:open": "cypress open" |     "cypress:open": "cypress open", | ||||||
|  |     "postinstall": "node ./npm-post-install.js" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "cypress": "^12.12.0" |     "cypress": "^12.12.0" | ||||||
|  |   }, | ||||||
|  |   "dependencies": { | ||||||
|  |     "@tinymce/tinymce-jquery": "^2.1.0", | ||||||
|  |     "bootstrap": "^4.6.2", | ||||||
|  |     "fs-extra": "^11.2.0", | ||||||
|  |     "jquery": "^3.7.1", | ||||||
|  |     "jquery-ui": "^1.13.2", | ||||||
|  |     "tinymce": "^6.8.3" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								phpstan-bootstrap.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								phpstan-bootstrap.php
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										39
									
								
								phpstan.neon
									
									
									
									
									
										Normal 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 | ||||||
| @@ -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) { | ||||||
|   | |||||||
| @@ -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,20 @@ | |||||||
| 			"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, | ||||||
|  | 		"pagesSubFolders": false, | ||||||
|  | 		"commands": true, | ||||||
|  | 		"themes": true | ||||||
|  | 	} | ||||||
|  } |  } | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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); |  | ||||||
| } |  | ||||||
| @@ -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(); |  | ||||||
| @@ -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; |  | ||||||
| } |  | ||||||
| @@ -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); |  | ||||||
| } |  | ||||||
| @@ -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; |  | ||||||
| @@ -105,4 +105,8 @@ $config['clients'] = [ | |||||||
| 	1316, | 	1316, | ||||||
| 	1320, | 	1320, | ||||||
| 	1321, | 	1321, | ||||||
|  | 	1322, | ||||||
|  | 	1330, | ||||||
|  | 	1332, | ||||||
|  | 	1340, | ||||||
| ]; | ]; | ||||||
|   | |||||||
| @@ -9,6 +9,8 @@ | |||||||
|  */ |  */ | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
|  | class Validator extends \MyAAC\Validator {} | ||||||
|  |  | ||||||
| function check_name($name, &$errors = '') { | function check_name($name, &$errors = '') { | ||||||
| 	if(Validator::characterName($name)) | 	if(Validator::characterName($name)) | ||||||
| 		return true; | 		return true; | ||||||
| @@ -72,4 +74,7 @@ function fieldExist($field, $table) | |||||||
| 	global $db; | 	global $db; | ||||||
| 	return $db->hasColumn($table, $field); | 	return $db->hasColumn($table, $field); | ||||||
| } | } | ||||||
| ?> |  | ||||||
|  | function getCreatureImgPath($creature): string { | ||||||
|  | 	return getMonsterImgPath($creature); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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 {} | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ switch($page) | |||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 	case 'killstatistics': | 	case 'killstatistics': | ||||||
| 		$page = 'lastkills'; | 		$page = 'last-kills'; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 	case 'buypoints': | 	case 'buypoints': | ||||||
|   | |||||||
| @@ -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) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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([ | ||||||
| @@ -127,6 +128,7 @@ try { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	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 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,8 @@ | |||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\Exceptions\SensitiveException; | ||||||
|  |  | ||||||
| if (class_exists(\Whoops\Run::class)) { | if (class_exists(\Whoops\Run::class)) { | ||||||
| 	$whoops = new \Whoops\Run; | 	$whoops = new \Whoops\Run; | ||||||
| 	if(IS_CLI) { | 	if(IS_CLI) { | ||||||
| @@ -21,8 +23,6 @@ if (class_exists(\Whoops\Run::class)) { | |||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| require LIBS . 'SensitiveException.php'; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @param Exception $exception |  * @param Exception $exception | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -9,11 +9,17 @@ | |||||||
|  */ |  */ | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
|  | use MyAAC\Cache\Cache; | ||||||
|  | use MyAAC\CsrfToken; | ||||||
|  | use MyAAC\Items; | ||||||
| use MyAAC\Models\Config; | use MyAAC\Models\Config; | ||||||
| use MyAAC\Models\Guild; | use MyAAC\Models\Guild; | ||||||
| use MyAAC\Models\House; | use MyAAC\Models\House; | ||||||
| use MyAAC\Models\Pages; | use MyAAC\Models\Pages; | ||||||
| use MyAAC\Models\Player; | use MyAAC\Models\Player; | ||||||
|  | use MyAAC\News; | ||||||
|  | use MyAAC\Plugins; | ||||||
|  | use MyAAC\Settings; | ||||||
| use PHPMailer\PHPMailer\PHPMailer; | use PHPMailer\PHPMailer\PHPMailer; | ||||||
| use Twig\Loader\ArrayLoader as Twig_ArrayLoader; | use Twig\Loader\ArrayLoader as Twig_ArrayLoader; | ||||||
|  |  | ||||||
| @@ -43,7 +49,10 @@ function warning($message, $return = false) { | |||||||
| 	return message($message, 'warning', $return); | 	return message($message, 'warning', $return); | ||||||
| } | } | ||||||
| function note($message, $return = false) { | function note($message, $return = false) { | ||||||
| 	return message($message, 'note', $return); | 	return info($message, $return); | ||||||
|  | } | ||||||
|  | function info($message, $return = false) { | ||||||
|  | 	return message($message, 'info', $return); | ||||||
| } | } | ||||||
| function error($message, $return = false) { | function error($message, $return = false) { | ||||||
| 	return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return); | 	return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return); | ||||||
| @@ -78,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(); | ||||||
| 		$player->load((int)$name); |  | ||||||
| 		if($player->isLoaded()) | 		if(is_numeric($name)) { | ||||||
| 			$name = $player->getName(); | 			$player->load((int)$name); | ||||||
|  | 		} | ||||||
|  | 		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/' . urlencode($name); | ||||||
|  |  | ||||||
| 	if(!$generate) return $url; | 	if(!$generate) return $url; | ||||||
| 	return generateLink($url, $name); | 	return generateLink($url, $name); | ||||||
| @@ -133,7 +158,6 @@ function getGuildLink($name, $generate = true): string | |||||||
| } | } | ||||||
|  |  | ||||||
| function getItemNameById($id) { | function getItemNameById($id) { | ||||||
| 	require_once LIBS . 'items.php'; |  | ||||||
| 	$item = Items::get($id); | 	$item = Items::get($id); | ||||||
| 	return !empty($item['name']) ? $item['name'] : ''; | 	return !empty($item['name']) ? $item['name'] : ''; | ||||||
| } | } | ||||||
| @@ -193,7 +217,7 @@ function getFlagImage($country): string | |||||||
|  * @param mixed $v Variable to check. |  * @param mixed $v Variable to check. | ||||||
|  * @return bool Value boolean status. |  * @return bool Value boolean status. | ||||||
|  */ |  */ | ||||||
| function getBoolean($v): bool | function getBoolean(mixed $v): bool | ||||||
| { | { | ||||||
| 	if(is_bool($v)) { | 	if(is_bool($v)) { | ||||||
| 		return $v; | 		return $v; | ||||||
| @@ -202,6 +226,10 @@ function getBoolean($v): bool | |||||||
| 	if(is_numeric($v)) | 	if(is_numeric($v)) | ||||||
| 		return (int)$v > 0; | 		return (int)$v > 0; | ||||||
|  |  | ||||||
|  | 	if (is_null($v)) { | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	$v = strtolower($v); | 	$v = strtolower($v); | ||||||
| 	return $v === 'yes' || $v === 'true'; | 	return $v === 'yes' || $v === 'true'; | ||||||
| } | } | ||||||
| @@ -249,7 +277,7 @@ function generateRandomString($length, $lowCase = true, $upCase = false, $numeri | |||||||
| function getForumBoards() | function getForumBoards() | ||||||
| { | { | ||||||
| 	global $db, $canEdit; | 	global $db, $canEdit; | ||||||
| 	$sections = $db->query('SELECT `id`, `name`, `description`, `closed`, `guild`, `access`' . ($canEdit ? ', `hidden`, `ordering`' : '') . ' FROM `' . TABLE_PREFIX . 'forum_boards` ' . (!$canEdit ? ' WHERE `hidden` != 1' : '') . | 	$sections = $db->query('SELECT `id`, `name`, `description`, `closed`, `guild`, `access`' . ($canEdit ? ', `hide`, `ordering`' : '') . ' FROM `' . TABLE_PREFIX . 'forum_boards` ' . (!$canEdit ? ' WHERE `hide` != 1' : '') . | ||||||
| 		' ORDER BY `ordering`;'); | 		' ORDER BY `ordering`;'); | ||||||
| 	if($sections) | 	if($sections) | ||||||
| 		return $sections->fetchAll(); | 		return $sections->fetchAll(); | ||||||
| @@ -406,7 +434,10 @@ function delete_guild($id) | |||||||
| 	if(count($rank_list) > 0) { | 	if(count($rank_list) > 0) { | ||||||
| 		$rank_list->orderBy('level'); | 		$rank_list->orderBy('level'); | ||||||
|  |  | ||||||
| 		global $db, $ots; | 		global $db; | ||||||
|  | 		/** | ||||||
|  | 		 * @var OTS_GuildRank $rank_in_guild | ||||||
|  | 		 */ | ||||||
| 		foreach($rank_list as $rank_in_guild) { | 		foreach($rank_list as $rank_in_guild) { | ||||||
| 			if($db->hasTable('guild_members')) | 			if($db->hasTable('guild_members')) | ||||||
| 				$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;'); | 				$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;'); | ||||||
| @@ -465,20 +496,30 @@ function tickers() | |||||||
|  */ |  */ | ||||||
| function template_place_holder($type): string | function template_place_holder($type): string | ||||||
| { | { | ||||||
| 	global $twig, $template_place_holders; | 	global $twig, $template_place_holders, $debugBar; | ||||||
| 	$ret = ''; | 	$ret = ''; | ||||||
|  |  | ||||||
|  | 	if (isset($debugBar)) { | ||||||
|  | 		$debugBarRenderer = $debugBar->getJavascriptRenderer(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if(array_key_exists($type, $template_place_holders) && is_array($template_place_holders[$type])) | 	if(array_key_exists($type, $template_place_holders) && is_array($template_place_holders[$type])) | ||||||
| 		$ret = implode($template_place_holders[$type]); | 		$ret = implode($template_place_holders[$type]); | ||||||
|  |  | ||||||
| 	if($type === 'head_start') { | 	if($type === 'head_start') { | ||||||
| 		$ret .= template_header(); | 		$ret .= template_header(); | ||||||
|  | 		if (isset($debugBar)) { | ||||||
|  | 			$ret .= $debugBarRenderer->renderHead(); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	elseif ($type === 'body_start') { | 	elseif ($type === 'body_start') { | ||||||
| 		$ret .= $twig->render('browsehappy.html.twig'); | 		$ret .= $twig->render('browsehappy.html.twig'); | ||||||
| 	} | 	} | ||||||
| 	elseif($type === 'body_end') { | 	elseif($type === 'body_end') { | ||||||
| 		$ret .= template_ga_code(); | 		$ret .= template_ga_code(); | ||||||
|  | 		if (isset($debugBar)) { | ||||||
|  | 			$ret .= $debugBarRenderer->render(); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return $ret; | 	return $ret; | ||||||
| @@ -688,11 +729,8 @@ function getSkillName($skillId, $suffix = true) | |||||||
| /** | /** | ||||||
|  * Performs flag check on the current logged in user. |  * Performs flag check on the current logged in user. | ||||||
|  * Table in database: accounts, field: website_flags |  * Table in database: accounts, field: website_flags | ||||||
|  * |  | ||||||
|  * @param int @flag Flag to be verified. |  | ||||||
|  * @return bool If user got flag. |  | ||||||
|  */ |  */ | ||||||
| function hasFlag($flag) { | function hasFlag(int $flag): bool { | ||||||
| 	global $logged, $logged_flags; | 	global $logged, $logged_flags; | ||||||
| 	return ($logged && ($logged_flags & $flag) == $flag); | 	return ($logged && ($logged_flags & $flag) == $flag); | ||||||
| } | } | ||||||
| @@ -765,7 +803,7 @@ function get_browser_languages() | |||||||
| 	$languages = str_replace(' ', '', $languages); | 	$languages = str_replace(' ', '', $languages); | ||||||
|  |  | ||||||
| 	foreach(explode(',', $languages) as $language_list) | 	foreach(explode(',', $languages) as $language_list) | ||||||
| 		$ret[] .= substr($language_list, 0, 2); | 		$ret[] = substr($language_list, 0, 2); | ||||||
|  |  | ||||||
| 	return $ret; | 	return $ret; | ||||||
| } | } | ||||||
| @@ -784,6 +822,10 @@ function get_templates() | |||||||
| 			$ret[] = $file; | 			$ret[] = $file; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	foreach (Plugins::getThemes() as $name => $path) { | ||||||
|  | 		$ret[] = $name; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return $ret; | 	return $ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -855,9 +897,6 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true) | |||||||
| 	else | 	else | ||||||
| 		$tmp_body = $body . '<br/><br/>' . $signature_html; | 		$tmp_body = $body . '<br/><br/>' . $signature_html; | ||||||
|  |  | ||||||
| 	define('MAIL_MAIL', 0); |  | ||||||
| 	define('MAIL_SMTP', 1); |  | ||||||
|  |  | ||||||
| 	$mailOption = setting('core.mail_option'); | 	$mailOption = setting('core.mail_option'); | ||||||
| 	if($mailOption == MAIL_SMTP) | 	if($mailOption == MAIL_SMTP) | ||||||
| 	{ | 	{ | ||||||
| @@ -868,10 +907,6 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true) | |||||||
| 		$mailer->Username = setting('core.smtp_user'); | 		$mailer->Username = setting('core.smtp_user'); | ||||||
| 		$mailer->Password = setting('core.smtp_pass'); | 		$mailer->Password = setting('core.smtp_pass'); | ||||||
|  |  | ||||||
| 		define('SMTP_SECURITY_NONE', 0); |  | ||||||
| 		define('SMTP_SECURITY_SSL', 1); |  | ||||||
| 		define('SMTP_SECURITY_TLS', 2); |  | ||||||
|  |  | ||||||
| 		$security = setting('core.smtp_security'); | 		$security = setting('core.smtp_security'); | ||||||
|  |  | ||||||
| 		$tmp = ''; | 		$tmp = ''; | ||||||
| @@ -1011,7 +1046,7 @@ function load_config_lua($filename) | |||||||
| 	return $result; | 	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)); | ||||||
| @@ -1045,6 +1080,28 @@ function unsetSession($key) { | |||||||
| 	unset($_SESSION[setting('core.session_prefix') . $key]); | 	unset($_SESSION[setting('core.session_prefix') . $key]); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function csrf(bool $return = false): string { | ||||||
|  | 	return CsrfToken::create($return); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function csrfToken(): string { | ||||||
|  | 	return CsrfToken::get(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function isValidToken(): bool { | ||||||
|  | 	$token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null; | ||||||
|  | 	return (!isRequestMethod('post') || (isset($token) && CsrfToken::isValid($token))); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function csrfProtect(): void | ||||||
|  | { | ||||||
|  | 	if (!isValidToken()) { | ||||||
|  | 		$lastUri = BASE_URL . str_replace_first('/', '', getSession('last_uri')); | ||||||
|  | 		echo 'Request has been cancelled due to security reasons - token is invalid. Go <a href="' . $lastUri . '">back</a>'; | ||||||
|  | 		exit(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| function getTopPlayers($limit = 5) { | function getTopPlayers($limit = 5) { | ||||||
| 	global $db; | 	global $db; | ||||||
|  |  | ||||||
| @@ -1162,86 +1219,70 @@ function setting($key) | |||||||
|  |  | ||||||
| function clearCache() | function clearCache() | ||||||
| { | { | ||||||
| 	require_once LIBS . 'news.php'; |  | ||||||
| 	News::clearCache(); | 	News::clearCache(); | ||||||
|  |  | ||||||
| 	$cache = Cache::getInstance(); | 	$cache = Cache::getInstance(); | ||||||
|  |  | ||||||
| 	if($cache->enabled()) { | 	if($cache->enabled()) { | ||||||
| 		$tmp = ''; | 		$keysToClear = [ | ||||||
|  | 			'status', 'templates', | ||||||
| 		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)) { | ||||||
| 		if ($cache->fetch('database_tables', $tmp)) { | 				$cache->delete($item); | ||||||
| 			$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'); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	deleteDirectory(CACHE . 'signatures', ['index.html'], true); | 	deleteDirectory(CACHE . 'signatures', ['index.html'], true); | ||||||
| 	deleteDirectory(CACHE . 'twig', ['index.html'], true); | 	deleteDirectory(CACHE . 'twig', ['index.html'], true); | ||||||
| 	deleteDirectory(CACHE . 'plugins', ['index.html'], true); | 	deleteDirectory(CACHE . 'plugins', ['index.html'], true); | ||||||
| 	deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html'], true); | 	deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html', 'persistent'], true); | ||||||
|  |  | ||||||
| 	// routes cache | 	// routes cache | ||||||
|  | 	clearRouteCache(); | ||||||
|  |  | ||||||
|  | 	global $hooks; | ||||||
|  | 	$hooks->trigger(HOOK_CACHE_CLEAR, ['cache' => Cache::getInstance()]); | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function clearRouteCache(): void | ||||||
|  | { | ||||||
| 	$routeCacheFile = CACHE . 'route.cache'; | 	$routeCacheFile = CACHE . 'route.cache'; | ||||||
| 	if (file_exists($routeCacheFile)) { | 	if (file_exists($routeCacheFile)) { | ||||||
| 		unlink($routeCacheFile); | 		unlink($routeCacheFile); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return true; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function getCustomPageInfo($name) | function getCustomPageInfo($name) | ||||||
| @@ -1283,13 +1324,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; | ||||||
| @@ -1299,11 +1333,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(); | ||||||
| @@ -1547,18 +1576,19 @@ function right($str, $length) { | |||||||
| 	return substr($str, -$length); | 	return substr($str, -$length); | ||||||
| } | } | ||||||
|  |  | ||||||
| function getCreatureImgPath($creature){ | function getMonsterImgPath($monster): string | ||||||
| 	$creature_path = setting('core.monsters_images_url'); | { | ||||||
| 	$creature_gfx_name = trim(strtolower($creature)) . setting('core.monsters_images_extension'); | 	$monster_path = setting('core.monsters_images_url'); | ||||||
| 	if (!file_exists($creature_path . $creature_gfx_name)) { | 	$monster_gfx_name = trim(strtolower($monster)) . setting('core.monsters_images_extension'); | ||||||
| 		$creature_gfx_name = str_replace(" ", "", $creature_gfx_name); | 	if (!file_exists($monster_path . $monster_gfx_name)) { | ||||||
| 		if (file_exists($creature_path . $creature_gfx_name)) { | 		$monster_gfx_name = str_replace(" ", "", $monster_gfx_name); | ||||||
| 			return $creature_path . $creature_gfx_name; | 		if (file_exists($monster_path . $monster_gfx_name)) { | ||||||
|  | 			return $monster_path . $monster_gfx_name; | ||||||
| 		} else { | 		} else { | ||||||
| 			return $creature_path . 'nophoto.png'; | 			return $monster_path . 'nophoto.png'; | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		return $creature_path . $creature_gfx_name; | 		return $monster_path . $monster_gfx_name; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1609,7 +1639,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) | ||||||
| @@ -1646,8 +1676,27 @@ 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 | ||||||
|   | |||||||
| @@ -7,8 +7,17 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use DebugBar\StandardDebugBar; | ||||||
|  | use MyAAC\Cache\Cache; | ||||||
|  | use MyAAC\CsrfToken; | ||||||
|  | use MyAAC\Hooks; | ||||||
|  | use MyAAC\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.'); | ||||||
| } | } | ||||||
| @@ -17,6 +26,10 @@ if(config('env') === 'dev') { | |||||||
| 	require SYSTEM . 'exception.php'; | 	require SYSTEM . 'exception.php'; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | if (config('env') === 'dev' || getBoolean(config('enable_debugbar'))) { | ||||||
|  | 	$debugBar = new StandardDebugBar(); | ||||||
|  | } | ||||||
|  |  | ||||||
| if(empty($config['server_path'])) { | if(empty($config['server_path'])) { | ||||||
| 	throw new RuntimeException('Server Path has been not set. Go to config.php and set it.'); | 	throw new RuntimeException('Server Path has been not set. Go to config.php and set it.'); | ||||||
| } | } | ||||||
| @@ -26,15 +39,15 @@ 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(); | ||||||
|  |  | ||||||
| // event system | // event system | ||||||
| require_once SYSTEM . 'hooks.php'; | global $hooks; | ||||||
| $hooks = new Hooks(); | $hooks = new Hooks(); | ||||||
| $hooks->load(); | $hooks->load(); | ||||||
|  |  | ||||||
| @@ -45,28 +58,24 @@ require_once SYSTEM . 'twig.php'; | |||||||
| $action = $_REQUEST['action'] ?? ''; | $action = $_REQUEST['action'] ?? ''; | ||||||
| define('ACTION', $action); | define('ACTION', $action); | ||||||
|  |  | ||||||
|  | // errors, is also often used | ||||||
|  | $errors = []; | ||||||
|  |  | ||||||
| // trim values we receive | // trim values we receive | ||||||
| if(isset($_POST)) | foreach($_POST as $var => $value) { | ||||||
| { | 	if(is_string($value)) { | ||||||
| 	foreach($_POST as $var => $value) { | 		$_POST[$var] = trim($value); | ||||||
| 		if(is_string($value)) { |  | ||||||
| 			$_POST[$var] = trim($value); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| if(isset($_GET)) |  | ||||||
| { | foreach($_GET as $var => $value) { | ||||||
| 	foreach($_GET as $var => $value) { | 	if(is_string($value)) | ||||||
| 		if(is_string($value)) | 		$_GET[$var] = trim($value); | ||||||
| 			$_GET[$var] = trim($value); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| if(isset($_REQUEST)) |  | ||||||
| { | foreach($_REQUEST as $var => $value) { | ||||||
| 	foreach($_REQUEST as $var => $value) { | 	if(is_string($value)) | ||||||
| 		if(is_string($value)) | 		$_REQUEST[$var] = trim($value); | ||||||
| 			$_REQUEST[$var] = trim($value); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // load otserv config file | // load otserv config file | ||||||
| @@ -122,30 +131,45 @@ 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'; | ||||||
|  |  | ||||||
|  | // verify myaac tables exists in database | ||||||
|  | if(!defined('MYAAC_INSTALL') && !$db->hasTable('myaac_account_actions')) { | ||||||
|  | 	throw new RuntimeException('Seems that the table myaac_account_actions of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting ' . BASE_URL . 'install'); | ||||||
|  | } | ||||||
|  |  | ||||||
| // execute migrations | // execute migrations | ||||||
| require SYSTEM . 'migrate.php'; | $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(); | ||||||
|  |  | ||||||
|  | // csrf protection | ||||||
|  | $token = getSession('csrf_token'); | ||||||
|  | if (!isset($token) || !$token) { | ||||||
|  | 	CsrfToken::generate(); | ||||||
|  | } | ||||||
|  |  | ||||||
| // deprecated config values | // deprecated config values | ||||||
| require_once SYSTEM . 'compat/config.php'; | require_once SYSTEM . 'compat/config.php'; | ||||||
|  |  | ||||||
|  | // 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') | ||||||
| 	] | 	] | ||||||
| ); | ); | ||||||
|  |  | ||||||
| @@ -158,5 +182,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); | ||||||
|   | |||||||
| @@ -1,3 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| class SensitiveException extends Exception {} |  | ||||||
| @@ -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 . '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(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -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; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -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; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -370,7 +370,14 @@ class POT | |||||||
|             throw new RuntimeException('Please install PHP pdo extension. MyAAC will not work without it.'); |             throw new RuntimeException('Please install PHP pdo extension. MyAAC will not work without it.'); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $this->db = new OTS_DB_MySQL($params); | 	    global $debugBar; | ||||||
|  | 		if (isset($debugBar)) { | ||||||
|  | 			$this->db = new DebugBar\DataCollector\PDO\TraceablePDO(new OTS_DB_MySQL($params)); | ||||||
|  | 			$debugBar->addCollector(new DebugBar\DataCollector\PDO\PDOCollector($this->db)); | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			$this->db = new OTS_DB_MySQL($params); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|         $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |         $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -952,7 +952,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable | |||||||
| 			return $query['group_id']; | 			return $query['group_id']; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return 0; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public function getAccGroupId() | 	public function getAccGroupId() | ||||||
|   | |||||||
| @@ -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; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /**#@-*/ |  | ||||||
|  |  | ||||||
| ?> |  | ||||||
|   | |||||||
| @@ -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. | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -42,24 +42,24 @@ class OTS_Buffer | |||||||
|  * |  * | ||||||
|  * @var string |  * @var string | ||||||
|  */ |  */ | ||||||
|     protected $buffer; | 	protected $buffer; | ||||||
| /** | /** | ||||||
|  * Properties stream pointer. |  * Properties stream pointer. | ||||||
|  * |  * | ||||||
|  * @var int |  * @var int | ||||||
|  */ |  */ | ||||||
|     protected $pos; | 	protected $pos; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Initializes new buffered reader. |  * Initializes new buffered reader. | ||||||
|  * |  * | ||||||
|  * @param string $buffer Buffer content. |  * @param string $buffer Buffer content. | ||||||
|  */ |  */ | ||||||
|     public function __construct($buffer = '') | 	public function __construct($buffer = '') | ||||||
|     { | 	{ | ||||||
|         $this->buffer = $buffer; | 		$this->buffer = $buffer; | ||||||
|         $this->pos = 0; | 		$this->pos = 0; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Magic PHP5 method. |  * Magic PHP5 method. | ||||||
| @@ -70,49 +70,49 @@ class OTS_Buffer | |||||||
|  * |  * | ||||||
|  * @param array $properties List of object properties. |  * @param array $properties List of object properties. | ||||||
|  */ |  */ | ||||||
|     public static function __set_state($properties) | 	public static function __set_state($properties) | ||||||
|     { | 	{ | ||||||
|         $object = new self(); | 		$object = new self(); | ||||||
|  |  | ||||||
|         // loads properties | 		// loads properties | ||||||
|         foreach($properties as $name => $value) | 		foreach($properties as $name => $value) | ||||||
|         { | 		{ | ||||||
|             $object->$name = $value; | 			$object->$name = $value; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $object; | 		return $object; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returs properties stream. |  * Returs properties stream. | ||||||
|  * |  * | ||||||
|  * @return string Properties stream. |  * @return string Properties stream. | ||||||
|  */ |  */ | ||||||
|     public function getBuffer() | 	public function getBuffer() | ||||||
|     { | 	{ | ||||||
|         return $this->buffer; | 		return $this->buffer; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Sets properties stream. |  * Sets properties stream. | ||||||
|  * |  * | ||||||
|  * @param string Properties stream. |  * @param string Properties stream. | ||||||
|  */ |  */ | ||||||
|     public function setBuffer($buffer) | 	public function setBuffer($buffer) | ||||||
|     { | 	{ | ||||||
|         $this->buffer = $buffer; | 		$this->buffer = $buffer; | ||||||
|         $this->pos = 0; | 		$this->pos = 0; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Checks if there is anything left in stream. |  * Checks if there is anything left in stream. | ||||||
|  * |  * | ||||||
|  * @return bool False if pointer is at the end of stream. |  * @return bool False if pointer is at the end of stream. | ||||||
|  */ |  */ | ||||||
|     public function isValid() | 	public function isValid() | ||||||
|     { | 	{ | ||||||
|         return $this->pos < strlen($this->buffer); | 		return $this->pos < strlen($this->buffer); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Checks stream end state. |  * Checks stream end state. | ||||||
| @@ -120,13 +120,13 @@ class OTS_Buffer | |||||||
|  * @param int $size Amount of bytes that are going to be read. |  * @param int $size Amount of bytes that are going to be read. | ||||||
|  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. |  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. | ||||||
|  */ |  */ | ||||||
|     protected function check($size = 1) | 	protected function check($size = 1) | ||||||
|     { | 	{ | ||||||
|         if( strlen($this->buffer) < $this->pos + $size) | 		if( strlen($this->buffer) < $this->pos + $size) | ||||||
|         { | 		{ | ||||||
|             throw new E_OTS_OutOfBuffer(); | 			throw new E_OTS_OutOfBuffer(); | ||||||
|         } | 		} | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns single byte. |  * Returns single byte. | ||||||
| @@ -134,25 +134,25 @@ class OTS_Buffer | |||||||
|  * @return int Byte (char) value. |  * @return int Byte (char) value. | ||||||
|  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. |  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. | ||||||
|  */ |  */ | ||||||
|     public function getChar() | 	public function getChar() | ||||||
|     { | 	{ | ||||||
|         // checks buffer size | 		// checks buffer size | ||||||
|         $this->check(); | 		$this->check(); | ||||||
|  |  | ||||||
|         $value = ord($this->buffer[$this->pos]); | 		$value = ord($this->buffer[$this->pos]); | ||||||
|         $this->pos++; | 		$this->pos++; | ||||||
|         return $value; | 		return $value; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Appends single byte to buffer. |  * Appends single byte to buffer. | ||||||
|  * |  * | ||||||
|  * @param int $char Byte (char) value. |  * @param int $char Byte (char) value. | ||||||
|  */ |  */ | ||||||
|     public function putChar($char) | 	public function putChar($char) | ||||||
|     { | 	{ | ||||||
|         $this->buffer .= chr($char); | 		$this->buffer .= chr($char); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns double byte. |  * Returns double byte. | ||||||
| @@ -160,25 +160,25 @@ class OTS_Buffer | |||||||
|  * @return int Word (short) value. |  * @return int Word (short) value. | ||||||
|  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. |  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. | ||||||
|  */ |  */ | ||||||
|     public function getShort() | 	public function getShort() | ||||||
|     { | 	{ | ||||||
|         // checks buffer size | 		// checks buffer size | ||||||
|         $this->check(2); | 		$this->check(2); | ||||||
|  |  | ||||||
|         $value = unpack('v', substr($this->buffer, $this->pos, 2) ); | 		$value = unpack('v', substr($this->buffer, $this->pos, 2) ); | ||||||
|         $this->pos += 2; | 		$this->pos += 2; | ||||||
|         return $value[1]; | 		return $value[1]; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Appends double byte to buffer. |  * Appends double byte to buffer. | ||||||
|  * |  * | ||||||
|  * @param int $short Word (short) value. |  * @param int $short Word (short) value. | ||||||
|  */ |  */ | ||||||
|     public function putShort($short) | 	public function putShort($short) | ||||||
|     { | 	{ | ||||||
|         $this->buffer .= pack('v', $short); | 		$this->buffer .= pack('v', $short); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns quater byte. |  * Returns quater byte. | ||||||
| @@ -186,25 +186,35 @@ class OTS_Buffer | |||||||
|  * @return int Double word (long) value. |  * @return int Double word (long) value. | ||||||
|  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. |  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. | ||||||
|  */ |  */ | ||||||
|     public function getLong() | 	public function getLong() | ||||||
|     { | 	{ | ||||||
|         // checks buffer size | 		// checks buffer size | ||||||
|         $this->check(4); | 		$this->check(4); | ||||||
|  |  | ||||||
|         $value = unpack('V', substr($this->buffer, $this->pos, 4) ); | 		$value = unpack('V', substr($this->buffer, $this->pos, 4) ); | ||||||
|         $this->pos += 4; | 		$this->pos += 4; | ||||||
|         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. | ||||||
|  * |  * | ||||||
|  * @param int $long Double word (long) value. |  * @param int $long Double word (long) value. | ||||||
|  */ |  */ | ||||||
|     public function putLong($long) | 	public function putLong($long) | ||||||
|     { | 	{ | ||||||
|         $this->buffer .= pack('V', $long); | 		$this->buffer .= pack('V', $long); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns string from buffer. |  * Returns string from buffer. | ||||||
| @@ -217,22 +227,22 @@ class OTS_Buffer | |||||||
|  * @return string First substring. |  * @return string First substring. | ||||||
|  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. |  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. | ||||||
|  */ |  */ | ||||||
|     public function getString($length = false) | 	public function getString($length = false) | ||||||
|     { | 	{ | ||||||
|         // reads string length if not given | 		// reads string length if not given | ||||||
|         if($length === false) | 		if($length === false) | ||||||
|         { | 		{ | ||||||
|             $length = $this->getShort(); | 			$length = $this->getShort(); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         // checks buffer size | 		// checks buffer size | ||||||
|         $this->check($length); | 		$this->check($length); | ||||||
|  |  | ||||||
|         // copies substring | 		// copies substring | ||||||
|         $value = substr($this->buffer, $this->pos, $length); | 		$value = substr($this->buffer, $this->pos, $length); | ||||||
|         $this->pos += $length; | 		$this->pos += $length; | ||||||
|         return $value; | 		return $value; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Appends string to buffer. |  * Appends string to buffer. | ||||||
| @@ -240,54 +250,54 @@ class OTS_Buffer | |||||||
|  * @param string $string Binary length. |  * @param string $string Binary length. | ||||||
|  * @param bool $dynamic Whether if string length is fixed or not (if it is dynamic then length will be inserted as short before string chunk). |  * @param bool $dynamic Whether if string length is fixed or not (if it is dynamic then length will be inserted as short before string chunk). | ||||||
|  */ |  */ | ||||||
|     public function putString($string, $dynamic = true) | 	public function putString($string, $dynamic = true) | ||||||
|     { | 	{ | ||||||
|         // appends string length if requires | 		// appends string length if requires | ||||||
|         if($dynamic) | 		if($dynamic) | ||||||
|         { | 		{ | ||||||
|             $this->putShort( strlen($string) ); | 			$this->putShort( strlen($string) ); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         $this->buffer .= $string; | 		$this->buffer .= $string; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Empties buffer. |  * Empties buffer. | ||||||
|  */ |  */ | ||||||
|     public function reset() | 	public function reset() | ||||||
|     { | 	{ | ||||||
|         $this->__construct(); | 		$this->__construct(); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns current read position. |  * Returns current read position. | ||||||
|  * |  * | ||||||
|  * @return int Read position. |  * @return int Read position. | ||||||
|  */ |  */ | ||||||
|     public function getPos() | 	public function getPos() | ||||||
|     { | 	{ | ||||||
|         return $this->pos; | 		return $this->pos; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Seeks current reading position. |  * Seeks current reading position. | ||||||
|  * |  * | ||||||
|  * @param int $pos Read position. |  * @param int $pos Read position. | ||||||
|  */ |  */ | ||||||
|     public function setPos($pos) | 	public function setPos($pos) | ||||||
|     { | 	{ | ||||||
|         $this->pos = $pos; | 		$this->pos = $pos; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns buffer size. |  * Returns buffer size. | ||||||
|  * |  * | ||||||
|  * @return int Buffer length. |  * @return int Buffer length. | ||||||
|  */ |  */ | ||||||
|     public function getSize() | 	public function getSize() | ||||||
|     { | 	{ | ||||||
|         return strlen($this->buffer); | 		return strlen($this->buffer); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Skips given amount of bytes. |  * Skips given amount of bytes. | ||||||
| @@ -295,11 +305,11 @@ class OTS_Buffer | |||||||
|  * @param int $n Bytes to skip. |  * @param int $n Bytes to skip. | ||||||
|  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. |  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. | ||||||
|  */ |  */ | ||||||
|     public function skip($n) | 	public function skip($n) | ||||||
|     { | 	{ | ||||||
|         $this->check($n); | 		$this->check($n); | ||||||
|         $this->pos += $n; | 		$this->pos += $n; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Magic PHP5 method. |  * Magic PHP5 method. | ||||||
| @@ -309,46 +319,46 @@ class OTS_Buffer | |||||||
|  * @throws OutOfBoundsException For non-supported properties. |  * @throws OutOfBoundsException For non-supported properties. | ||||||
|  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. |  * @throws E_OTS_OutOfBuffer When there is read attemp after end of stream. | ||||||
|  */ |  */ | ||||||
|     public function __get($name) | 	public function __get($name) | ||||||
|     { | 	{ | ||||||
|         switch($name) | 		switch($name) | ||||||
|         { | 		{ | ||||||
|             // simple properties | 			// simple properties | ||||||
|             case 'buffer': | 			case 'buffer': | ||||||
|                 return $this->buffer; | 				return $this->buffer; | ||||||
|  |  | ||||||
|             // isValid() wrapper | 			// isValid() wrapper | ||||||
|             case 'valid': | 			case 'valid': | ||||||
|                 return $this->isValid(); | 				return $this->isValid(); | ||||||
|  |  | ||||||
|             // getChar() wrapper | 			// getChar() wrapper | ||||||
|             case 'char': | 			case 'char': | ||||||
|                 return $this->getChar(); | 				return $this->getChar(); | ||||||
|  |  | ||||||
|             // getShort() wrapper | 			// getShort() wrapper | ||||||
|             case 'short': | 			case 'short': | ||||||
|                 return $this->getShort(); | 				return $this->getShort(); | ||||||
|  |  | ||||||
|             // getLong() wrapper | 			// getLong() wrapper | ||||||
|             case 'long': | 			case 'long': | ||||||
|                 return $this->getLong(); | 				return $this->getLong(); | ||||||
|  |  | ||||||
|             // getString() wrapper | 			// getString() wrapper | ||||||
|             case 'string': | 			case 'string': | ||||||
|                 return $this->getString(); | 				return $this->getString(); | ||||||
|  |  | ||||||
|             // getPos() wrapper | 			// getPos() wrapper | ||||||
|             case 'pos': | 			case 'pos': | ||||||
|                 return $this->getPos(); | 				return $this->getPos(); | ||||||
|  |  | ||||||
|             // getSize() wrapper | 			// getSize() wrapper | ||||||
|             case 'size': | 			case 'size': | ||||||
|                 return $this->getSize(); | 				return $this->getSize(); | ||||||
|  |  | ||||||
|             default: | 			default: | ||||||
|                 throw new OutOfBoundsException(); | 				throw new OutOfBoundsException(); | ||||||
|         } | 		} | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Magic PHP5 method. |  * Magic PHP5 method. | ||||||
| @@ -358,62 +368,62 @@ class OTS_Buffer | |||||||
|  * @param mixed $value Property value. |  * @param mixed $value Property value. | ||||||
|  * @throws OutOfBoundsException For non-supported properties. |  * @throws OutOfBoundsException For non-supported properties. | ||||||
|  */ |  */ | ||||||
|     public function __set($name, $value) | 	public function __set($name, $value) | ||||||
|     { | 	{ | ||||||
|         switch($name) | 		switch($name) | ||||||
|         { | 		{ | ||||||
|             // buffer needs to be reset | 			// buffer needs to be reset | ||||||
|             case 'buffer': | 			case 'buffer': | ||||||
|                 $this->setBuffer($value); | 				$this->setBuffer($value); | ||||||
|                 break; | 				break; | ||||||
|  |  | ||||||
|             // putChar() wrapper | 			// putChar() wrapper | ||||||
|             case 'char': | 			case 'char': | ||||||
|                 $this->putChar($value); | 				$this->putChar($value); | ||||||
|                 break; | 				break; | ||||||
|  |  | ||||||
|             // putShort() wrapper | 			// putShort() wrapper | ||||||
|             case 'short': | 			case 'short': | ||||||
|                 $this->putShort($value); | 				$this->putShort($value); | ||||||
|                 break; | 				break; | ||||||
|  |  | ||||||
|             // putLong() wrapper | 			// putLong() wrapper | ||||||
|             case 'long': | 			case 'long': | ||||||
|                 $this->putLong($value); | 				$this->putLong($value); | ||||||
|                 break; | 				break; | ||||||
|  |  | ||||||
|             // putString() wrapper | 			// putString() wrapper | ||||||
|             case 'string': | 			case 'string': | ||||||
|                 $this->putString($value); | 				$this->putString($value); | ||||||
|                 break; | 				break; | ||||||
|  |  | ||||||
|             // setPos() wrapper | 			// setPos() wrapper | ||||||
|             case 'pos': | 			case 'pos': | ||||||
|                 $this->setPos($value); | 				$this->setPos($value); | ||||||
|                 break; | 				break; | ||||||
|  |  | ||||||
|             default: | 			default: | ||||||
|                 throw new OutOfBoundsException(); | 				throw new OutOfBoundsException(); | ||||||
|         } | 		} | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns string representation of buffer object. |  * Returns string representation of buffer object. | ||||||
|  * |  * | ||||||
|  * @return string Object's buffer. |  * @return string Object's buffer. | ||||||
|  */ |  */ | ||||||
|     public function __toString() | 	public function __toString() | ||||||
|     { | 	{ | ||||||
|         return $this->buffer; | 		return $this->buffer; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Resets pointer of cloned object. |  * Resets pointer of cloned object. | ||||||
|  */ |  */ | ||||||
|     public function __clone() | 	public function __clone() | ||||||
|     { | 	{ | ||||||
|         $this->pos = 0; | 		$this->pos = 0; | ||||||
|     } | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| /**#@-*/ | /**#@-*/ | ||||||
|   | |||||||
| @@ -12,6 +12,8 @@ | |||||||
|  * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 |  * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\Cache\Cache; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * MySQL connection interface. |  * MySQL connection interface. | ||||||
|  * |  * | ||||||
| @@ -26,6 +28,8 @@ class OTS_DB_MySQL extends OTS_Base_DB | |||||||
| { | { | ||||||
| 	private $has_table_cache = array(); | 	private $has_table_cache = array(); | ||||||
| 	private $has_column_cache = array(); | 	private $has_column_cache = array(); | ||||||
|  |  | ||||||
|  | 	private $clearCacheAfter = false; | ||||||
| /** | /** | ||||||
|  * Creates database connection. |  * Creates database connection. | ||||||
|  * |  * | ||||||
| @@ -49,52 +53,53 @@ class OTS_DB_MySQL extends OTS_Base_DB | |||||||
|  * @param array $params Connection parameters. |  * @param array $params Connection parameters. | ||||||
|  * @throws PDOException On PDO operation error. |  * @throws PDOException On PDO operation error. | ||||||
|  */ |  */ | ||||||
|     public function __construct($params) | 	public function __construct($params) | ||||||
|     { | 	{ | ||||||
|         $user = null; | 		$user = null; | ||||||
|         $password = null; | 		$password = null; | ||||||
|         $dns = array(); | 		$dns = array(); | ||||||
|  |  | ||||||
|         // host:port support | 		// host:port support | ||||||
|         if( strpos(':', $params['host']) !== false) | 		if( strpos(':', $params['host']) !== false) | ||||||
|         { | 		{ | ||||||
|             $host = explode(':', $params['host'], 2); | 			$host = explode(':', $params['host'], 2); | ||||||
|  |  | ||||||
|             $params['host'] = $host[0]; | 			$params['host'] = $host[0]; | ||||||
|             $params['port'] = $host[1]; | 			$params['port'] = $host[1]; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         if( isset($params['database']) ) | 		if( isset($params['database']) ) | ||||||
|         { | 		{ | ||||||
|             $dns[] = 'dbname=' . $params['database']; | 			$dns[] = 'dbname=' . $params['database']; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         if( isset($params['user']) ) | 		if( isset($params['user']) ) | ||||||
|         { | 		{ | ||||||
|             $user = $params['user']; | 			$user = $params['user']; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         if( isset($params['password']) ) | 		if( isset($params['password']) ) | ||||||
|         { | 		{ | ||||||
|             $password = $params['password']; | 			$password = $params['password']; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         if( isset($params['prefix']) ) | 		if( isset($params['prefix']) ) | ||||||
|         { | 		{ | ||||||
|             $this->prefix = $params['prefix']; | 			$this->prefix = $params['prefix']; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         if( isset($params['log']) && $params['log'] ) | 		if( isset($params['log']) && $params['log'] ) | ||||||
|         { | 		{ | ||||||
|             $this->logged = true; | 			$this->logged = true; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         if( !isset($params['persistent']) ) { | 		if( !isset($params['persistent']) ) { | ||||||
|             $params['persistent'] = false; | 			$params['persistent'] = false; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
| 		global $config; | 		global $config; | ||||||
| 		if(class_exists('Cache') && ($cache = Cache::getInstance()) && $cache->enabled()) { | 		$cache = Cache::getInstance(); | ||||||
|  | 		if($cache->enabled()) { | ||||||
| 			$tmp = null; | 			$tmp = null; | ||||||
| 			$need_revalidation = true; | 			$need_revalidation = true; | ||||||
| 			if($cache->fetch('database_checksum', $tmp) && $tmp) { | 			if($cache->fetch('database_checksum', $tmp) && $tmp) { | ||||||
| @@ -117,12 +122,15 @@ class OTS_DB_MySQL extends OTS_Base_DB | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		$driverAttributes = []; // debugbar dont like persistent connection | ||||||
|  | 		if (config('env') !== 'dev' && !getBoolean(config('enable_debugbar'))) { | ||||||
|  | 			$driverAttributes[PDO::ATTR_PERSISTENT] = $params['persistent']; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if(isset($params['socket'][0])) { | 		if(isset($params['socket'][0])) { | ||||||
| 			$dns[] = 'unix_socket=' . $params['socket']; | 			$dns[] = 'unix_socket=' . $params['socket']; | ||||||
|  |  | ||||||
| 			parent::__construct('mysql:' . implode(';', $dns), $user, $password, array( | 			parent::__construct('mysql:' . implode(';', $dns), $user, $password, $driverAttributes); | ||||||
| 				PDO::ATTR_PERSISTENT => $params['persistent'] |  | ||||||
| 			)); |  | ||||||
|  |  | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| @@ -135,23 +143,30 @@ class OTS_DB_MySQL extends OTS_Base_DB | |||||||
| 			$dns[] = 'port=' . $params['port']; | 			$dns[] = 'port=' . $params['port']; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		parent::__construct('mysql:' . implode(';', $dns), $user, $password, array( | 		parent::__construct('mysql:' . implode(';', $dns), $user, $password, $driverAttributes); | ||||||
| 			PDO::ATTR_PERSISTENT => $params['persistent'] | 	} | ||||||
| 		)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| 	public function __destruct() | 	public function __destruct() | ||||||
|     { | 	{ | ||||||
| 		global $config; | 		global $config; | ||||||
|  |  | ||||||
| 	    if(class_exists('Cache') && ($cache = Cache::getInstance()) && $cache->enabled()) { | 		$cache = Cache::getInstance(); | ||||||
| 			$cache->set('database_tables', serialize($this->has_table_cache), 3600); | 		if($cache->enabled()) { | ||||||
| 			$cache->set('database_columns', serialize($this->has_column_cache), 3600); | 			if ($this->clearCacheAfter) { | ||||||
| 			$cache->set('database_checksum', serialize(sha1($config['database_host'] . '.' . $config['database_name'])), 3600); | 				$cache->delete('database_tables'); | ||||||
|  | 				$cache->delete('database_columns'); | ||||||
|  | 				$cache->delete('database_checksum'); | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				$cache->set('database_tables', serialize($this->has_table_cache), 3600); | ||||||
|  | 				$cache->set('database_columns', serialize($this->has_column_cache), 3600); | ||||||
|  | 				$cache->set('database_checksum', serialize(sha1($config['database_host'] . '.' . $config['database_name'])), 3600); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if($this->logged) { | 		if($this->logged) { | ||||||
| 			log_append('database.log', $_SERVER['REQUEST_URI'] . PHP_EOL . $this->getLog()); | 			$currentScript = $_SERVER['REQUEST_URI'] ?? $_SERVER['SCRIPT_FILENAME']; | ||||||
|  | 			log_append('database.log', $currentScript . PHP_EOL . $this->getLog()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -161,10 +176,10 @@ class OTS_DB_MySQL extends OTS_Base_DB | |||||||
|  * @param string $name Field name. |  * @param string $name Field name. | ||||||
|  * @return string Quoted name. |  * @return string Quoted name. | ||||||
|  */ |  */ | ||||||
|     public function fieldName($name) | 	public function fieldName($name) | ||||||
|     { | 	{ | ||||||
|         return '`' . $name . '`'; | 		return '`' . $name . '`'; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * LIMIT/OFFSET clause for queries. |  * LIMIT/OFFSET clause for queries. | ||||||
| @@ -173,26 +188,26 @@ class OTS_DB_MySQL extends OTS_Base_DB | |||||||
|  * @param int|bool $offset Number of rows to be skipped before applying query effects (false if no offset). |  * @param int|bool $offset Number of rows to be skipped before applying query effects (false if no offset). | ||||||
|  * @return string LIMIT/OFFSET SQL clause for query. |  * @return string LIMIT/OFFSET SQL clause for query. | ||||||
|  */ |  */ | ||||||
|     public function limit($limit = false, $offset = false) | 	public function limit($limit = false, $offset = false) | ||||||
|     { | 	{ | ||||||
|         // by default this is empty part | 		// by default this is empty part | ||||||
|         $sql = ''; | 		$sql = ''; | ||||||
|  |  | ||||||
|         if($limit !== false) | 		if($limit !== false) | ||||||
|         { | 		{ | ||||||
|             $sql = ' LIMIT '; | 			$sql = ' LIMIT '; | ||||||
|  |  | ||||||
|             // OFFSET has no effect if there is no LIMIT | 			// OFFSET has no effect if there is no LIMIT | ||||||
|             if($offset !== false) | 			if($offset !== false) | ||||||
|             { | 			{ | ||||||
|                 $sql .= $offset . ', '; | 				$sql .= $offset . ', '; | ||||||
|             } | 			} | ||||||
|  |  | ||||||
|             $sql .= $limit; | 			$sql .= $limit; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $sql; | 		return $sql; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| 	public function hasTable($name) { | 	public function hasTable($name) { | ||||||
| 		if(isset($this->has_table_cache[$name])) { | 		if(isset($this->has_table_cache[$name])) { | ||||||
| @@ -235,6 +250,11 @@ class OTS_DB_MySQL extends OTS_Base_DB | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	public function setClearCacheAfter($clearCache) | ||||||
|  | 	{ | ||||||
|  | 		$this->clearCacheAfter = $clearCache; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| /**#@-*/ | /**#@-*/ | ||||||
|   | |||||||
| @@ -8,6 +8,8 @@ | |||||||
|  * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 |  * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\Cache\Cache; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * List of groups. |  * List of groups. | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -60,12 +60,7 @@ class OTS_House extends OTS_Row_DAO | |||||||
|     private $tiles = array(); |     private $tiles = array(); | ||||||
|  |  | ||||||
| 	public function load($id) { | 	public function load($id) { | ||||||
| 		$this->data = $this->db->query('SELECT * FROM `houses` WHERE `id` = ' . $id )->fetch(); | 		$this->data = $this->db->query('SELECT * FROM `houses` WHERE `id` = ' . $id )->fetch(PDO::FETCH_ASSOC); | ||||||
| 		foreach($this->data as $key => $value) { |  | ||||||
| 			if(is_numeric($key)) { |  | ||||||
| 				unset($this->data[$key]); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     public function find($name) |     public function find($name) | ||||||
|   | |||||||
| @@ -41,9 +41,10 @@ | |||||||
| class OTS_Monster extends DOMDocument | class OTS_Monster extends DOMDocument | ||||||
| { | { | ||||||
| 	private $loaded = false; | 	private $loaded = false; | ||||||
| 	public function loadXML($source , $options = 0) | 	public function loadXML(string $source , int $options = 0): bool | ||||||
| 	{ | 	{ | ||||||
| 		$this->loaded = parent::loadXML($source, $options); | 		$this->loaded = parent::loadXML($source, $options); | ||||||
|  | 		return $this->loaded; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public function loaded() | 	public function loaded() | ||||||
| @@ -56,10 +57,10 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return string Name. |  * @return string Name. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getName() | 	public function getName() | ||||||
|     { | 	{ | ||||||
|         return $this->documentElement->getAttribute('name'); | 		return $this->documentElement->getAttribute('name'); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns monster race. |  * Returns monster race. | ||||||
| @@ -67,10 +68,10 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return string Race. |  * @return string Race. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getRace() | 	public function getRace() | ||||||
|     { | 	{ | ||||||
|         return $this->documentElement->getAttribute('race'); | 		return $this->documentElement->getAttribute('race'); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns amount of experience for killing this monster. |  * Returns amount of experience for killing this monster. | ||||||
| @@ -78,10 +79,10 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return int Experience points. |  * @return int Experience points. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getExperience() | 	public function getExperience() | ||||||
|     { | 	{ | ||||||
|         return (int) $this->documentElement->getAttribute('experience'); | 		return (int) $this->documentElement->getAttribute('experience'); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns monster speed. |  * Returns monster speed. | ||||||
| @@ -89,10 +90,10 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return int Speed. |  * @return int Speed. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getSpeed() | 	public function getSpeed() | ||||||
|     { | 	{ | ||||||
|         return (int) $this->documentElement->getAttribute('speed'); | 		return (int) $this->documentElement->getAttribute('speed'); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns amount of mana required to summon this monster. |  * Returns amount of mana required to summon this monster. | ||||||
| @@ -100,18 +101,18 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return int|bool Mana required (false if not possible). |  * @return int|bool Mana required (false if not possible). | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getManaCost() | 	public function getManaCost() | ||||||
|     { | 	{ | ||||||
|         // check if it is possible to summon this monster | 		// check if it is possible to summon this monster | ||||||
|         if( $this->documentElement->hasAttribute('manacost') ) | 		if( $this->documentElement->hasAttribute('manacost') ) | ||||||
|         { | 		{ | ||||||
|             return (int) $this->documentElement->getAttribute('manacost'); | 			return (int) $this->documentElement->getAttribute('manacost'); | ||||||
|         } | 		} | ||||||
|         else | 		else | ||||||
|         { | 		{ | ||||||
|             return false; | 			return false; | ||||||
|         } | 		} | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns monster HP. |  * Returns monster HP. | ||||||
| @@ -119,10 +120,10 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return int Hit points. |  * @return int Hit points. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getHealth() | 	public function getHealth() | ||||||
|     { | 	{ | ||||||
|         return (int) $this->documentElement->getElementsByTagName('health')->item(0)->getAttribute('max'); | 		return (int) $this->documentElement->getElementsByTagName('health')->item(0)->getAttribute('max'); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns all monster flags (in format flagname => value). |  * Returns all monster flags (in format flagname => value). | ||||||
| @@ -130,20 +131,21 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return array Flags. |  * @return array Flags. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getFlags() | 	public function getFlags() | ||||||
|     { | 	{ | ||||||
|         $flags = array(); | 		$flags = array(); | ||||||
|  |  | ||||||
|         // read all flags | 		if ($this->documentElement->getElementsByTagName('flags')->item(0)) { | ||||||
|         foreach( $this->documentElement->getElementsByTagName('flags')->item(0)->getElementsByTagName('flag') as $flag) | 			foreach( $this->documentElement->getElementsByTagName('flags')->item(0)->getElementsByTagName('flag') as $flag) | ||||||
|         { | 			{ | ||||||
|             $flag = $flag->attributes->item(0); | 				$flag = $flag->attributes->item(0); | ||||||
|  |  | ||||||
|             $flags[$flag->nodeName] = (int) $flag->nodeValue; | 				$flags[$flag->nodeName] = (int) $flag->nodeValue; | ||||||
|         } | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|         return $flags; | 		return $flags; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns specified flag value. |  * Returns specified flag value. | ||||||
| @@ -152,21 +154,21 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return int|bool Flag value (false if not set). |  * @return int|bool Flag value (false if not set). | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getFlag($flag) | 	public function getFlag($flag) | ||||||
|     { | 	{ | ||||||
|         // searches for flag | 		// searches for flag | ||||||
|         foreach( $this->documentElement->getElementsByTagName('flags')->item(0)->getElementsByTagName('flag') as $flag) | 		foreach( $this->documentElement->getElementsByTagName('flags')->item(0)->getElementsByTagName('flag') as $flag) | ||||||
|         { | 		{ | ||||||
|             // found | 			// found | ||||||
|             if( $flag->hasAttribute($flag) ) | 			if( $flag->hasAttribute($flag) ) | ||||||
|             { | 			{ | ||||||
|                 return (int) $flag->getAttribute($flag); | 				return (int) $flag->getAttribute($flag); | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         // not found | 		// not found | ||||||
|         return false; | 		return false; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns voices that monster can sound. |  * Returns voices that monster can sound. | ||||||
| @@ -174,64 +176,64 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return array List of voices. |  * @return array List of voices. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getVoices() | 	public function getVoices() | ||||||
|     { | 	{ | ||||||
|         $voices = array(); | 		$voices = array(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('voices')->item(0); | 		$element = $this->documentElement->getElementsByTagName('voices')->item(0); | ||||||
|  |  | ||||||
|         // checks if it has any voices | 		// checks if it has any voices | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             // loads all voices | 			// loads all voices | ||||||
|             foreach( $element->getElementsByTagName('voice') as $voice) | 			foreach( $element->getElementsByTagName('voice') as $voice) | ||||||
|             { | 			{ | ||||||
|                 $voices[] = $voice->getAttribute('sentence'); | 				$voices[] = $voice->getAttribute('sentence'); | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $voices; | 		return $voices; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @return array List of item IDs. |  * @return array List of item IDs. | ||||||
|  */ |  */ | ||||||
|     public function getLoot() | 	public function getLoot() | ||||||
|     { | 	{ | ||||||
|         $loot = array(); | 		$loot = array(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('loot')->item(0); | 		$element = $this->documentElement->getElementsByTagName('loot')->item(0); | ||||||
|  |  | ||||||
|         // checks if it has any loot | 		// checks if it has any loot | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             // adds all items | 			// adds all items | ||||||
|             foreach( $element->getElementsByTagName('item') as $item) | 			foreach( $element->getElementsByTagName('item') as $item) | ||||||
|             { | 			{ | ||||||
| 	            $chance = $item->getAttribute('chance'); | 				$chance = $item->getAttribute('chance'); | ||||||
| 	            if(empty($chance)) { | 				if(empty($chance)) { | ||||||
| 		            $chance = $item->getAttribute('chance1'); | 					$chance = $item->getAttribute('chance1'); | ||||||
| 		            if(empty($chance)) { | 					if(empty($chance)) { | ||||||
| 		                $chance = 100000; | 						$chance = 100000; | ||||||
|                     } | 					} | ||||||
|                 } | 				} | ||||||
|  |  | ||||||
|                 $count = $item->getAttribute('countmax'); | 				$count = $item->getAttribute('countmax'); | ||||||
| 	            if(empty($count)) { | 				if(empty($count)) { | ||||||
| 	                $count = 1; | 					$count = 1; | ||||||
|                 } | 				} | ||||||
|  |  | ||||||
|                 $id = $item->getAttribute('id'); | 				$id = $item->getAttribute('id'); | ||||||
|                 if(empty($id)) { | 				if(empty($id)) { | ||||||
|                     $id = $item->getAttribute('name'); | 					$id = $item->getAttribute('name'); | ||||||
|                 } | 				} | ||||||
|  |  | ||||||
|                 $loot[] = array('id' => $id, 'count' => $count, 'chance' => $chance); | 				$loot[] = array('id' => $id, 'count' => $count, 'chance' => $chance); | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $loot; | 		return $loot; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns all possible loot. |  * Returns all possible loot. | ||||||
| @@ -246,33 +248,33 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @throws E_OTS_NotLoaded When there is no items list available in global POT instance. |  * @throws E_OTS_NotLoaded When there is no items list available in global POT instance. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getItems() | 	public function getItems() | ||||||
|     { | 	{ | ||||||
|         $loot = array(); | 		$loot = array(); | ||||||
|         $keys = array(); | 		$keys = array(); | ||||||
|         $items = POT::getInstance()->getItemsList(); | 		$items = POT::getInstance()->getItemsList(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('loot')->item(0); | 		$element = $this->documentElement->getElementsByTagName('loot')->item(0); | ||||||
|  |  | ||||||
|         // checks if it has any loot | 		// checks if it has any loot | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             // adds all items | 			// adds all items | ||||||
|             foreach( $element->getElementsByTagName('item') as $item) | 			foreach( $element->getElementsByTagName('item') as $item) | ||||||
|             { | 			{ | ||||||
|                 $id = $item->getAttribute('id'); | 				$id = $item->getAttribute('id'); | ||||||
|  |  | ||||||
|                 // avoid redundancy | 				// avoid redundancy | ||||||
|                 if( !in_array($id, $keys) ) | 				if( !in_array($id, $keys) ) | ||||||
|                 { | 				{ | ||||||
|                     $keys[] = $id; | 					$keys[] = $id; | ||||||
|                     $loot[] = $items->getItemType($id); | 					$loot[] = $items->getItemType($id); | ||||||
|                 } | 				} | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $loot; | 		return $loot; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns look of the monster. |  * Returns look of the monster. | ||||||
| @@ -280,27 +282,27 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return array Look with all the attributes of the look. |  * @return array Look with all the attributes of the look. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getLook() | 	public function getLook() | ||||||
|     { | 	{ | ||||||
|         $look = array(); | 		$look = array(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('look')->item(0); | 		$element = $this->documentElement->getElementsByTagName('look')->item(0); | ||||||
|  |  | ||||||
|         if (!$element) { | 		if (!$element) { | ||||||
|             return $look; | 			return $look; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         $look['type'] = $element->getAttribute('type'); | 		$look['type'] = $element->getAttribute('type'); | ||||||
|         $look['typeex'] = $element->getAttribute('typeex'); | 		$look['typeex'] = $element->getAttribute('typeex'); | ||||||
|         $look['head'] = $element->getAttribute('head'); | 		$look['head'] = $element->getAttribute('head'); | ||||||
|         $look['body'] = $element->getAttribute('body'); | 		$look['body'] = $element->getAttribute('body'); | ||||||
|         $look['legs'] = $element->getAttribute('legs'); | 		$look['legs'] = $element->getAttribute('legs'); | ||||||
|         $look['feet'] = $element->getAttribute('feet'); | 		$look['feet'] = $element->getAttribute('feet'); | ||||||
|         $look['addons'] = $element->getAttribute('addons'); | 		$look['addons'] = $element->getAttribute('addons'); | ||||||
|         $look['corpse'] = $element->getAttribute('corpse'); | 		$look['corpse'] = $element->getAttribute('corpse'); | ||||||
|  |  | ||||||
|         return $look; | 		return $look; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns all monster summons. |  * Returns all monster summons. | ||||||
| @@ -310,24 +312,24 @@ class OTS_Monster extends DOMDocument | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| 	public function getSummons() | 	public function getSummons() | ||||||
|     { | 	{ | ||||||
|         $summons = array(); | 		$summons = array(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('summons')->item(0); | 		$element = $this->documentElement->getElementsByTagName('summons')->item(0); | ||||||
|  |  | ||||||
|         // checks if it has any Summons | 		// checks if it has any Summons | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             // adds all summons | 			// adds all summons | ||||||
|             foreach( $element->getElementsByTagName('summon') as $item) | 			foreach( $element->getElementsByTagName('summon') as $item) | ||||||
|             { | 			{ | ||||||
| 	            $chance = $item->getAttribute('chance'); | 				$chance = $item->getAttribute('chance'); | ||||||
|                 $id = $item->getAttribute('name'); | 				$id = $item->getAttribute('name'); | ||||||
|                 $summons[] = array('name' => $id, 'chance' => $chance); | 				$summons[] = array('name' => $id, 'chance' => $chance); | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|         return $summons; | 		return $summons; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns all monster elements. |  * Returns all monster elements. | ||||||
| @@ -335,30 +337,30 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return array elements. |  * @return array elements. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getElements() | 	public function getElements() | ||||||
|     { | 	{ | ||||||
|         $elements = array(); | 		$elements = array(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('elements')->item(0); | 		$element = $this->documentElement->getElementsByTagName('elements')->item(0); | ||||||
|  |  | ||||||
|         // checks if it has any elements | 		// checks if it has any elements | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             // read all elements | 			// read all elements | ||||||
|             foreach( $element->getElementsByTagName('element') as $elementv) | 			foreach( $element->getElementsByTagName('element') as $elementv) | ||||||
|             { | 			{ | ||||||
|                 $elementv = $elementv->attributes->item(0); | 				$elementv = $elementv->attributes->item(0); | ||||||
|  |  | ||||||
|                 // checks if element is set | 				// checks if element is set | ||||||
|                 if($elementv->nodeValue > 0) | 				if($elementv->nodeValue > 0) | ||||||
|                 { | 				{ | ||||||
| 					 $elements[] = array('name' => ucfirst(str_replace('Percent', '', $elementv->nodeName)), 'percent' => $elementv->nodeValue); | 					 $elements[] = array('name' => ucfirst(str_replace('Percent', '', $elementv->nodeName)), 'percent' => $elementv->nodeValue); | ||||||
|                 } | 				} | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $elements; | 		return $elements; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Checks if monster has given element. |  * Checks if monster has given element. | ||||||
| @@ -367,26 +369,26 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return bool element state. |  * @return bool element state. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function hasElement($name) | 	public function hasElement($name) | ||||||
|     { | 	{ | ||||||
|         $element = $this->documentElement->getElementsByTagName('elements')->item(0); | 		$element = $this->documentElement->getElementsByTagName('elements')->item(0); | ||||||
|  |  | ||||||
|         // if doesn't have any elements obviously doesn't have this one too | 		// if doesn't have any elements obviously doesn't have this one too | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             // read all elements | 			// read all elements | ||||||
|             foreach( $element->getElementsByTagName('element') as $element) | 			foreach( $element->getElementsByTagName('element') as $element) | ||||||
|             { | 			{ | ||||||
|                 // checks if this is what we are searching for | 				// checks if this is what we are searching for | ||||||
|                 if( $element->hasAttribute($name) ) | 				if( $element->hasAttribute($name) ) | ||||||
|                 { | 				{ | ||||||
|                     return $element->getAttribute($name) > 0; | 					return $element->getAttribute($name) > 0; | ||||||
|                 } | 				} | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return false; | 		return false; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns all monster immunities. |  * Returns all monster immunities. | ||||||
| @@ -394,30 +396,30 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return array Immunities. |  * @return array Immunities. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getImmunities() | 	public function getImmunities() | ||||||
|     { | 	{ | ||||||
|         $immunities = array(); | 		$immunities = array(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('immunities')->item(0); | 		$element = $this->documentElement->getElementsByTagName('immunities')->item(0); | ||||||
|  |  | ||||||
|         // checks if it has any immunities | 		// checks if it has any immunities | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             // read all immunities | 			// read all immunities | ||||||
|             foreach( $element->getElementsByTagName('immunity') as $immunity) | 			foreach( $element->getElementsByTagName('immunity') as $immunity) | ||||||
|             { | 			{ | ||||||
|                 $immunity = $immunity->attributes->item(0); | 				$immunity = $immunity->attributes->item(0); | ||||||
|  |  | ||||||
|                 // checks if immunity is set | 				// checks if immunity is set | ||||||
|                 if($immunity->nodeValue > 0) | 				if($immunity->nodeValue > 0) | ||||||
|                 { | 				{ | ||||||
|                     $immunities[] = $immunity->nodeName; | 					$immunities[] = $immunity->nodeName; | ||||||
|                 } | 				} | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $immunities; | 		return $immunities; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Checks if monster has given immunity. |  * Checks if monster has given immunity. | ||||||
| @@ -426,26 +428,26 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return bool Immunity state. |  * @return bool Immunity state. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function hasImmunity($name) | 	public function hasImmunity($name) | ||||||
|     { | 	{ | ||||||
|         $element = $this->documentElement->getElementsByTagName('immunities')->item(0); | 		$element = $this->documentElement->getElementsByTagName('immunities')->item(0); | ||||||
|  |  | ||||||
|         // if doesn't have any immunities obviously doesn't have this one too | 		// if doesn't have any immunities obviously doesn't have this one too | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             // read all immunities | 			// read all immunities | ||||||
|             foreach( $element->getElementsByTagName('immunity') as $immunity) | 			foreach( $element->getElementsByTagName('immunity') as $immunity) | ||||||
|             { | 			{ | ||||||
|                 // checks if this is what we are searching for | 				// checks if this is what we are searching for | ||||||
|                 if( $immunity->hasAttribute($name) ) | 				if( $immunity->hasAttribute($name) ) | ||||||
|                 { | 				{ | ||||||
|                     return $immunity->getAttribute($name) > 0; | 					return $immunity->getAttribute($name) > 0; | ||||||
|                 } | 				} | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return false; | 		return false; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns monster defense rate. |  * Returns monster defense rate. | ||||||
| @@ -453,18 +455,18 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return int Defense rate. |  * @return int Defense rate. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getDefense() | 	public function getDefense() | ||||||
|     { | 	{ | ||||||
|         $element = $this->documentElement->getElementsByTagName('defenses')->item(0); | 		$element = $this->documentElement->getElementsByTagName('defenses')->item(0); | ||||||
|  |  | ||||||
|         // checks if defenses element is set | 		// checks if defenses element is set | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             return (int) $element->getAttribute('defense'); | 			return (int) $element->getAttribute('defense'); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return 0; | 		return 0; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns monster armor. |  * Returns monster armor. | ||||||
| @@ -472,18 +474,18 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return int Armor rate. |  * @return int Armor rate. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getArmor() | 	public function getArmor() | ||||||
|     { | 	{ | ||||||
|         $element = $this->documentElement->getElementsByTagName('defenses')->item(0); | 		$element = $this->documentElement->getElementsByTagName('defenses')->item(0); | ||||||
|  |  | ||||||
|         // checks if defenses element is set | 		// checks if defenses element is set | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             return (int) $element->getAttribute('armor'); | 			return (int) $element->getAttribute('armor'); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return 0; | 		return 0; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns list of special defenses. |  * Returns list of special defenses. | ||||||
| @@ -491,23 +493,23 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return array List of defense effects. |  * @return array List of defense effects. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getDefenses() | 	public function getDefenses() | ||||||
|     { | 	{ | ||||||
|         $defenses = array(); | 		$defenses = array(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('defenses')->item(0); | 		$element = $this->documentElement->getElementsByTagName('defenses')->item(0); | ||||||
|  |  | ||||||
|         // checks if it has any defenses | 		// checks if it has any defenses | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             foreach( $element->getElementsByTagName('defense') as $defense) | 			foreach( $element->getElementsByTagName('defense') as $defense) | ||||||
|             { | 			{ | ||||||
|                 $defenses[] = $defense->getAttribute('name'); | 				$defenses[] = $defense->getAttribute('name'); | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $defenses; | 		return $defenses; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns list of monster attacks. |  * Returns list of monster attacks. | ||||||
| @@ -515,23 +517,23 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @return array List of attafck effects. |  * @return array List of attafck effects. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function getAttacks() | 	public function getAttacks() | ||||||
|     { | 	{ | ||||||
|         $attacks = array(); | 		$attacks = array(); | ||||||
|  |  | ||||||
|         $element = $this->documentElement->getElementsByTagName('attacks')->item(0); | 		$element = $this->documentElement->getElementsByTagName('attacks')->item(0); | ||||||
|  |  | ||||||
|         // checks if it has any defenses | 		// checks if it has any defenses | ||||||
|         if( isset($element) ) | 		if( isset($element) ) | ||||||
|         { | 		{ | ||||||
|             foreach( $element->getElementsByTagName('attack') as $attack) | 			foreach( $element->getElementsByTagName('attack') as $attack) | ||||||
|             { | 			{ | ||||||
|                 $attacks[] = $attack->getAttribute('name'); | 				$attacks[] = $attack->getAttribute('name'); | ||||||
|             } | 			} | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $attacks; | 		return $attacks; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Magic PHP5 method. |  * Magic PHP5 method. | ||||||
| @@ -543,59 +545,59 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @throws OutOfBoundsException For non-supported properties. |  * @throws OutOfBoundsException For non-supported properties. | ||||||
|  * @throws DOMException On DOM operation error. |  * @throws DOMException On DOM operation error. | ||||||
|  */ |  */ | ||||||
|     public function __get($name) | 	public function __get($name) | ||||||
|     { | 	{ | ||||||
|         switch($name) | 		switch($name) | ||||||
|         { | 		{ | ||||||
|             case 'name': | 			case 'name': | ||||||
|                 return $this->getName(); | 				return $this->getName(); | ||||||
|  |  | ||||||
|             case 'race': | 			case 'race': | ||||||
|                 return $this->getRace(); | 				return $this->getRace(); | ||||||
|  |  | ||||||
|             case 'experience': | 			case 'experience': | ||||||
|                 return $this->getExperience(); | 				return $this->getExperience(); | ||||||
|  |  | ||||||
|             case 'speed': | 			case 'speed': | ||||||
|                 return $this->getSpeed(); | 				return $this->getSpeed(); | ||||||
|  |  | ||||||
|             case 'manaCost': | 			case 'manaCost': | ||||||
|                 return $this->getManaCost(); | 				return $this->getManaCost(); | ||||||
|  |  | ||||||
|             case 'health': | 			case 'health': | ||||||
|                 return $this->getHealth(); | 				return $this->getHealth(); | ||||||
|  |  | ||||||
|             case 'flags': | 			case 'flags': | ||||||
|                 return $this->getFlags(); | 				return $this->getFlags(); | ||||||
|  |  | ||||||
|             case 'voices': | 			case 'voices': | ||||||
|                 return $this->getVoices(); | 				return $this->getVoices(); | ||||||
|  |  | ||||||
|             case 'items': | 			case 'items': | ||||||
|                 return $this->getItems(); | 				return $this->getItems(); | ||||||
|  |  | ||||||
|             case 'immunities': | 			case 'immunities': | ||||||
|                 return $this->getImmunities(); | 				return $this->getImmunities(); | ||||||
|  |  | ||||||
|             case 'defense': | 			case 'defense': | ||||||
|                 return $this->getDefense(); | 				return $this->getDefense(); | ||||||
|  |  | ||||||
|             case 'armor': | 			case 'armor': | ||||||
|                 return $this->getArmor(); | 				return $this->getArmor(); | ||||||
|  |  | ||||||
|             case 'defenses': | 			case 'defenses': | ||||||
|                 return $this->getDefenses(); | 				return $this->getDefenses(); | ||||||
|  |  | ||||||
|             case 'attacks': | 			case 'attacks': | ||||||
|                 return $this->getAttacks(); | 				return $this->getAttacks(); | ||||||
|  |  | ||||||
|             case 'look': | 			case 'look': | ||||||
|                 return $this->getLook(); | 				return $this->getLook(); | ||||||
|  |  | ||||||
|             default: | 			default: | ||||||
|                 throw new OutOfBoundsException(); | 				throw new OutOfBoundsException(); | ||||||
|         } | 		} | ||||||
|     } | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Returns string representation of XML. |  * Returns string representation of XML. | ||||||
| @@ -608,18 +610,18 @@ class OTS_Monster extends DOMDocument | |||||||
|  * @since 0.1.0 |  * @since 0.1.0 | ||||||
|  * @return string String representation of object. |  * @return string String representation of object. | ||||||
|  */ |  */ | ||||||
|     public function __toString() | 	public function __toString() | ||||||
|     { | 	{ | ||||||
|         $ots = POT::getInstance(); | 		$ots = POT::getInstance(); | ||||||
|  |  | ||||||
|         // checks if display driver is loaded | 		// checks if display driver is loaded | ||||||
|         if( $ots->isDataDisplayDriverLoaded() ) | 		if( $ots->isDataDisplayDriverLoaded() ) | ||||||
|         { | 		{ | ||||||
|             return $ots->getDataDisplayDriver()->displayMonster($this); | 			return $ots->getDataDisplayDriver()->displayMonster($this); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         return $this->saveXML(); | 		return $this->saveXML(); | ||||||
|     } | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| /**#@-*/ | /**#@-*/ | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ class OTS_Player extends OTS_Row_DAO | |||||||
|  * @version 0.1.2 |  * @version 0.1.2 | ||||||
|  * @var array |  * @var array | ||||||
|  */ |  */ | ||||||
|     private $data = array('sex' => 0, 'vocation' => 0, 'experience' => 0, 'level' => 1, 'maglevel' => 0, 'health' => 100, 'healthmax' => 100, 'mana' => 100, 'manamax' => 100, 'manaspent' => 0, 'soul' => 0, 'lookbody' => 10, 'lookfeet' => 10, 'lookhead' => 10, 'looklegs' => 10, 'looktype' => 136, 'lookaddons' => 0, 'posx' => 0, 'posy' => 0, 'posz' => 0, 'cap' => 0, 'lastlogin' => 0, 'lastip' => 0, 'save' => true, 'skulltime' => 0, 'skull' => 0, 'balance' => 0, 'lastlogout' => 0, 'blessings' => 0, 'stamina' => 0, 'online' => 0, 'comment' => '', 'created' => 0, 'hidden' => 0); |     private $data = array('group_id' => 1, 'sex' => 0, 'vocation' => 0, 'experience' => 0, 'level' => 1, 'maglevel' => 0, 'health' => 100, 'healthmax' => 100, 'mana' => 100, 'manamax' => 100, 'manaspent' => 0, 'soul' => 0, 'lookbody' => 10, 'lookfeet' => 10, 'lookhead' => 10, 'looklegs' => 10, 'looktype' => 136, 'lookaddons' => 0, 'posx' => 0, 'posy' => 0, 'posz' => 0, 'cap' => 0, 'lastlogin' => 0, 'lastip' => 0, 'save' => true, 'skulltime' => 0, 'skull' => 0, 'balance' => 0, 'lastlogout' => 0, 'blessings' => 0, 'stamina' => 0, 'online' => 0, 'comment' => '', 'created' => 0, 'hide' => 0); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Player skills. |  * Player skills. | ||||||
| @@ -231,7 +231,7 @@ class OTS_Player extends OTS_Row_DAO | |||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			// SELECT query on database | 			// SELECT query on database | ||||||
| 			$this->data = $this->db->query('SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`' . ($this->db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `save`, `conditions`, `' . $__load['skull_time'] . '` as `skulltime`, `' . $__load['skull_type'] . '` as `skull`' . $__load['guild_info'] . ', `town_id`' . $__load['loss_experience'] . $__load['loss_items'] . ', `balance`' . ($__load['blessings'] ? ', `blessings`' : '') . ($__load['direction'] ? ', `direction`' : '') . ($__load['stamina'] ? ', `stamina`' : '') . ($__load['world_id'] ? ', `world_id`' : '') . ($__load['online'] ? ', `online`' : '') . ', `' . ($__load['deletion'] ? 'deletion' : 'deleted') . '`' . ($__load['promotion'] ? ', `promotion`' : '') . ($__load['marriage'] ? ', `marriage`' : '') . ', `comment`, `created`, `hidden` FROM `players` WHERE `id` = ' . (int)$id)->fetch(); | 			$this->data = $this->db->query('SELECT `id`, `name`, `account_id`, `group_id`, `sex`, `vocation`, `experience`, `level`, `maglevel`, `health`, `healthmax`, `mana`, `manamax`, `manaspent`, `soul`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`' . ($this->db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `posx`, `posy`, `posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `save`, `conditions`, `' . $__load['skull_time'] . '` as `skulltime`, `' . $__load['skull_type'] . '` as `skull`' . $__load['guild_info'] . ', `town_id`' . $__load['loss_experience'] . $__load['loss_items'] . ', `balance`' . ($__load['blessings'] ? ', `blessings`' : '') . ($__load['direction'] ? ', `direction`' : '') . ($__load['stamina'] ? ', `stamina`' : '') . ($__load['world_id'] ? ', `world_id`' : '') . ($__load['online'] ? ', `online`' : '') . ', `' . ($__load['deletion'] ? 'deletion' : 'deleted') . '`' . ($__load['promotion'] ? ', `promotion`' : '') . ($__load['marriage'] ? ', `marriage`' : '') . ', `comment`, `created`, `hide` FROM `players` WHERE `id` = ' . (int)$id)->fetch(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|         // loads skills |         // loads skills | ||||||
| @@ -521,17 +521,17 @@ class OTS_Player extends OTS_Row_DAO | |||||||
|  |  | ||||||
|     public function isHidden() |     public function isHidden() | ||||||
|     { |     { | ||||||
|         if( !isset($this->data['hidden']) ) |         if( !isset($this->data['hide']) ) | ||||||
|         { |         { | ||||||
|             throw new E_OTS_NotLoaded(); |             throw new E_OTS_NotLoaded(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $this->data['hidden'] == 1; |         return $this->data['hide'] == 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function setHidden($hidden) |     public function setHidden($hidden) | ||||||
|     { |     { | ||||||
|         $this->data['hidden'] = (int) $hidden; |         $this->data['hide'] = (int) $hidden; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function getMarriage() |     public function getMarriage() | ||||||
| @@ -1229,6 +1229,13 @@ class OTS_Player extends OTS_Row_DAO | |||||||
|         $this->data['direction'] = (int) $direction; |         $this->data['direction'] = (int) $direction; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | 	public function getOutfit(): string | ||||||
|  | 	{ | ||||||
|  | 		$hasLookAddons = $this->db->hasColumn('players', 'lookaddons'); | ||||||
|  |  | ||||||
|  | 		return setting('core.outfit_images_url') . '?id=' . $this->getLookType() . ($hasLookAddons ? '&addons=' . $this->getLookAddons() : '') . '&head=' . $this->getLookHead() . '&body=' . $this->getLookBody() . '&legs=' . $this->getLookLegs() . '&feet=' . $this->getLookFeet(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Body color. |  * Body color. | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -36,6 +36,10 @@ $locale['step_requirements'] = 'Anforderungen'; | |||||||
| $locale['step_requirements_title'] = 'Anforderungen überprüfen'; | $locale['step_requirements_title'] = 'Anforderungen überprüfen'; | ||||||
| $locale['step_requirements_php_version'] = 'PHP Version'; | $locale['step_requirements_php_version'] = 'PHP Version'; | ||||||
| $locale['step_requirements_write_perms'] = 'Schreibberechtigungen'; | $locale['step_requirements_write_perms'] = 'Schreibberechtigungen'; | ||||||
|  | $locale['step_requirements_folder_exists'] = 'Ordner ist vorhanden'; | ||||||
|  | $locale['step_requirements_folder_not_exists_tools_ext'] = 'NPM Package Manager wird verwendet für externe JavaScript/CSS Bibliotheken.' | ||||||
|  | 	. ' Es sollte via Command Line installiert werden: <a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm">https://docs.npmjs.com/downloading-and-installing-node-js-and-npm</a>' | ||||||
|  | 	. ' Nachdem das Tool installiert wurde, folgende Befehl sollte ausgeführt in dem Hauptordner des MyAACs: "npm install".'; | ||||||
| $locale['step_requirements_failed'] = 'Die Installation wird deaktiviert, bis diese Anforderungen erfüllt sind.</b><br/>Für weitere Informationen siehe <b>README</b> Datei.'; | $locale['step_requirements_failed'] = 'Die Installation wird deaktiviert, bis diese Anforderungen erfüllt sind.</b><br/>Für weitere Informationen siehe <b>README</b> Datei.'; | ||||||
| $locale['step_requirements_extension'] = '$EXTENSION$ PHP Erweiterung'; | $locale['step_requirements_extension'] = '$EXTENSION$ PHP Erweiterung'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,6 +36,10 @@ $locale['step_requirements'] = 'Requirements'; | |||||||
| $locale['step_requirements_title'] = 'Requirements check'; | $locale['step_requirements_title'] = 'Requirements check'; | ||||||
| $locale['step_requirements_php_version'] = 'PHP Version'; | $locale['step_requirements_php_version'] = 'PHP Version'; | ||||||
| $locale['step_requirements_write_perms'] = 'Write permissions'; | $locale['step_requirements_write_perms'] = 'Write permissions'; | ||||||
|  | $locale['step_requirements_folder_exists'] = 'Directory exists'; | ||||||
|  | $locale['step_requirements_folder_not_exists_tools_ext'] = 'NPM Package Manager is used for external JavaScript/CSS libraries.' | ||||||
|  | 	. ' You need to install it through Command Line: <a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm">https://docs.npmjs.com/downloading-and-installing-node-js-and-npm</a>' | ||||||
|  | 	. ' When you done with installing that tool, execute: "npm install" in the main MyAAC folder.'; | ||||||
| $locale['step_requirements_failed'] = 'Installation will be disabled until these requirements will be passed.</b><br/>For more informations see <b>README</b> file.'; | $locale['step_requirements_failed'] = 'Installation will be disabled until these requirements will be passed.</b><br/>For more informations see <b>README</b> file.'; | ||||||
| $locale['step_requirements_extension'] = '$EXTENSION$ PHP extension'; | $locale['step_requirements_extension'] = '$EXTENSION$ PHP extension'; | ||||||
| $locale['step_requirements_warning_images_guilds'] = 'Guild logo upload will not work'; | $locale['step_requirements_warning_images_guilds'] = 'Guild logo upload will not work'; | ||||||
| @@ -90,7 +94,7 @@ $locale['step_database_loaded_npcs'] = 'NPCs has been loaded...'; | |||||||
| $locale['step_database_error_npcs'] = 'There were some problems loading your NPCs'; | $locale['step_database_error_npcs'] = 'There were some problems loading your NPCs'; | ||||||
| $locale['step_database_loaded_spells'] = 'Spells has been loaded...'; | $locale['step_database_loaded_spells'] = 'Spells has been loaded...'; | ||||||
| $locale['step_database_loaded_towns'] = 'Towns has been loaded...'; | $locale['step_database_loaded_towns'] = 'Towns has been loaded...'; | ||||||
| $locale['step_database_error_towns'] = 'There were some problems loading your towns. You will need to configure them manually in config.'; | $locale['step_database_error_towns'] = 'There were some problems loading your towns. You will need to configure them manually in Settings.'; | ||||||
| $locale['step_database_created_account'] = 'Created admin account...'; | $locale['step_database_created_account'] = 'Created admin account...'; | ||||||
| $locale['step_database_created_news'] = 'Newses has been created...'; | $locale['step_database_created_news'] = 'Newses has been created...'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,6 +36,10 @@ $locale['step_requirements'] = 'Wymagania'; | |||||||
| $locale['step_requirements_title'] = 'Sprawdzanie wymagań'; | $locale['step_requirements_title'] = 'Sprawdzanie wymagań'; | ||||||
| $locale['step_requirements_php_version'] = 'Wersja PHP'; | $locale['step_requirements_php_version'] = 'Wersja PHP'; | ||||||
| $locale['step_requirements_write_perms'] = 'Uprawnienia do zapisu'; | $locale['step_requirements_write_perms'] = 'Uprawnienia do zapisu'; | ||||||
|  | $locale['step_requirements_folder_exists'] = 'Folder istnieje'; | ||||||
|  | $locale['step_requirements_folder_not_exists_tools_ext'] = 'Manadżer Pakietów NPM jest używany do zewnętrznych bibliotek JavaScript/CSS.' | ||||||
|  | 	. ' Trzeba go zainstalować poprzez wiersz poleceń: <a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm">https://docs.npmjs.com/downloading-and-installing-node-js-and-npm</a>' | ||||||
|  | 	. ' Po instalacji narzędzia, wywołaj następujące polecenie w głownym katalogu MyAAC: "npm install".'; | ||||||
| $locale['step_requirements_failed'] = 'Instalacja zostanie zablokowana dopóki te wymagania nie zostaną spełnione.</b><br/>Po więcej informacji zasięgnij do pliku <b>README</b>.'; | $locale['step_requirements_failed'] = 'Instalacja zostanie zablokowana dopóki te wymagania nie zostaną spełnione.</b><br/>Po więcej informacji zasięgnij do pliku <b>README</b>.'; | ||||||
| $locale['step_requirements_extension'] = 'Rozszerzenie PHP - $EXTENSION$'; | $locale['step_requirements_extension'] = 'Rozszerzenie PHP - $EXTENSION$'; | ||||||
| $locale['step_requirements_warning_images_guilds'] = 'Nie będzie możliwości uploadu obrazków gildii'; | $locale['step_requirements_warning_images_guilds'] = 'Nie będzie możliwości uploadu obrazków gildii'; | ||||||
| @@ -89,7 +93,7 @@ $locale['step_database_loaded_npcs'] = 'Załadowano NPCs...'; | |||||||
| $locale['step_database_error_npcs'] = 'Wystąpił problem podczas ładowania NPCs'; | $locale['step_database_error_npcs'] = 'Wystąpił problem podczas ładowania NPCs'; | ||||||
| $locale['step_database_loaded_spells'] = 'Załadowano czary (spells)...'; | $locale['step_database_loaded_spells'] = 'Załadowano czary (spells)...'; | ||||||
| $locale['step_database_loaded_towns'] = 'Załadowano miasta (towns)...'; | $locale['step_database_loaded_towns'] = 'Załadowano miasta (towns)...'; | ||||||
| $locale['step_database_error_towns'] = 'Wystąpił problem podczas ładowania miast. Trzeba będzie je skonfigurować manualnie.'; | $locale['step_database_error_towns'] = 'Wystąpił problem podczas ładowania miast. Trzeba będzie je skonfigurować manualnie w ustawieniach.'; | ||||||
| $locale['step_database_created_account'] = 'Utworzono konto admina...'; | $locale['step_database_created_account'] = 'Utworzono konto admina...'; | ||||||
| $locale['step_database_created_news'] = 'Utworzono newsy...'; | $locale['step_database_created_news'] = 'Utworzono newsy...'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,6 +7,9 @@ | |||||||
|  * @copyright 2019 MyAAC |  * @copyright 2019 MyAAC | ||||||
|  * @link      https://my-aac.org |  * @link      https://my-aac.org | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | use MyAAC\CsrfToken; | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
|  |  | ||||||
| if(isset($account_logged) && $account_logged->isLoaded()) { | if(isset($account_logged) && $account_logged->isLoaded()) { | ||||||
| @@ -15,13 +18,9 @@ if(isset($account_logged) && $account_logged->isLoaded()) { | |||||||
| 		unsetSession('password'); | 		unsetSession('password'); | ||||||
| 		unsetSession('remember_me'); | 		unsetSession('remember_me'); | ||||||
|  |  | ||||||
|  | 		CsrfToken::generate(); | ||||||
|  |  | ||||||
| 		$logged = false; | 		$logged = false; | ||||||
| 		unset($account_logged); | 		unset($account_logged); | ||||||
|  |  | ||||||
| 		if(isset($_REQUEST['redirect'])) |  | ||||||
| 		{ |  | ||||||
| 			header('Location: ' . urldecode($_REQUEST['redirect'])); |  | ||||||
| 			exit; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -17,6 +17,12 @@ if(fetchDatabaseConfig('database_version', $tmp)) { // we got version | |||||||
| 		$db->revalidateCache(); | 		$db->revalidateCache(); | ||||||
| 		for($i = $tmp + 1; $i <= DATABASE_VERSION; $i++) { | 		for($i = $tmp + 1; $i <= DATABASE_VERSION; $i++) { | ||||||
| 			require SYSTEM . 'migrations/' . $i . '.php'; | 			require SYSTEM . 'migrations/' . $i . '.php'; | ||||||
|  |  | ||||||
|  | 			if (isset($up)) { | ||||||
|  | 				$up(); | ||||||
|  | 				unset($up); | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			updateDatabaseConfig('database_version', $i); | 			updateDatabaseConfig('database_version', $i); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -26,6 +32,12 @@ else { // register first version | |||||||
| 	$db->revalidateCache(); | 	$db->revalidateCache(); | ||||||
| 	for($i = 1; $i <= DATABASE_VERSION; $i++) { | 	for($i = 1; $i <= DATABASE_VERSION; $i++) { | ||||||
| 		require SYSTEM . 'migrations/' . $i . '.php'; | 		require SYSTEM . 'migrations/' . $i . '.php'; | ||||||
|  |  | ||||||
|  | 		if (isset($up)) { | ||||||
|  | 			$up(); | ||||||
|  | 			unset($up); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		updateDatabaseConfig('database_version', $i); | 		updateDatabaseConfig('database_version', $i); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user