mirror of
				https://github.com/slawkens/myaac.git
				synced 2025-10-31 16:06:24 +01:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
			v1.0
			...
			feature/do
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 8d76e4e670 | ||
|   | 5e14521f08 | ||
|   | 335a0d1cff | ||
|   | 5735d487d9 | ||
|   | d7e1ca747e | ||
|   | 5a9490138b | ||
|   | 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 | ||||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -23,6 +23,7 @@ releases | |||||||
| tmp | tmp | ||||||
|  |  | ||||||
| config.local.php | config.local.php | ||||||
|  | !docker/config.local.php | ||||||
|  |  | ||||||
| # all custom templates | # all custom templates | ||||||
| templates/* | templates/* | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,47 +1,5 @@ | |||||||
| # Changelog | # Changelog | ||||||
|  |  | ||||||
| ## [1.0 - 12.01.2025] |  | ||||||
|  |  | ||||||
| First stable release in the v1.0 series. |  | ||||||
|  |  | ||||||
| Minimum PHP 8.1 is required. |  | ||||||
|  |  | ||||||
| Changes since RC.2: |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
| * feature: migrations up/down. Allows to downgrade/upgrade database to specified version (https://github.com/slawkens/myaac/commit/3f6ff3a3326b0475d28d11ffd7fff51f362d799f) |  | ||||||
| * new hooks for news management (https://github.com/slawkens/myaac/commit/011a85d8ae34283ded6999882833f9d4797028ec, https://github.com/slawkens/myaac/commit/36bd3eb846e829b45313e10f7568dc4e95841143) |  | ||||||
| * None Vocation to highscores (can be changed to RookStayer in Admin Panel) (https://github.com/slawkens/myaac/commit/a4a248099521bb5b8b2aa5bd592138debd2f19d5) |  | ||||||
| * support for button_color (green, red, blue) (https://github.com/slawkens/myaac/commit/d8b6b749ee62e88b6af4a05d3d7557f90b94d94e) |  | ||||||
| * add $whoopsHandler as variable, can be used by plugins (https://github.com/slawkens/myaac/commit/b0c8cf2ecda23045d725aaf43cfb3852ed766a4b) |  | ||||||
| * PlayerModel->outfit_url attribute (https://github.com/slawkens/myaac/commit/3b5be1a8db5dceecaa388e2925a5536d13b38881) |  | ||||||
| * support for selecting plugin themes in Admin menus.php (https://github.com/slawkens/myaac/commit/77a2c1cec343ffe4be5c2c2503ee81bc32a14ca1) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| * schema: Change character set to utf8mb4 (support for Emojis in Menus/Pages/News/Forum etc.) (https://github.com/slawkens/myaac/commit/27c44f1bdfb6234cf0c9d5b4b491123bb205b08f) |  | ||||||
| * prefer get_browser_real_ip() over REMOTE_ADDR (https://github.com/slawkens/myaac/commit/941846605c00cee83168d2f916410b8ba8d4b7b9) |  | ||||||
| * automatically set selected current one on highscores filters (https://github.com/slawkens/myaac/commit/e96227fbe41ae281783b2d49edb169a603601813) |  | ||||||
| * rewrite towns loading code, removed OTBM loader (was too slow) (https://github.com/slawkens/myaac/commit/c980a0914632e7b27f718464f669a200707d217e) |  | ||||||
| * allow OTS_Player to be passed as object to getPlayerLink (https://github.com/slawkens/myaac/commit/84d37c5a8f2c4535a41c8aa8264752969d3f3a3d) |  | ||||||
| * do not clear menus by default on install (https://github.com/slawkens/myaac/commit/12d8faa3eda5e798f97b71e941c035187daad96e) |  | ||||||
| * display warning in admin panel - plugins - if zip extension is not installed (https://github.com/slawkens/myaac/commit/e3ffe5d9e11d78ab064a370d8541bac351c9bcd9) |  | ||||||
| * set default_socket_timeout for ipinfo.io checkup to 5 seconds (https://github.com/slawkens/myaac/commit/783d96fc6568a607d3198b832fed3a0dd06c4ebb) |  | ||||||
| * refactor getTopPlayers function (support for balance) (https://github.com/slawkens/myaac/commit/c769962e39fe8dfb72ecd5be1864e145696be794) |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| * XSS in forum (https://github.com/slawkens/myaac/commit/c2b7286d20d4b579171540f7a774e8a0995d5e8f, https://github.com/slawkens/myaac/commit/8fb643596f9586005976e7bdb484a541a9d8715e) |  | ||||||
| * price deducted when changing sex (https://github.com/slawkens/myaac/commit/16671ea40b72dcf74037c359ad572f9eb825edf9) |  | ||||||
| * move_thread by unauthorized user (https://github.com/slawkens/myaac/commit/d6c40c836a53cb1710f911f77f45f28b54ea1b54, thanks @anyeor) |  | ||||||
| * TFS 1.4.2 where conditions is NULL (https://github.com/slawkens/myaac/commit/b8396d4c8482e951da538b13f2296123732c4545) |  | ||||||
| * do not show forum new thread show button if not logged in (https://github.com/slawkens/myaac/commit/507402171ba3b6e7ee184bd7fa73e0d55e0cad7a, @anyeor) |  | ||||||
| * login if limiter is disabled (https://github.com/slawkens/myaac/commit/a0f1971583f0f790013e2145fb5ac573c59fbdef) |  | ||||||
| * fixes to installMenus function (https://github.com/slawkens/myaac/commit/a2fadc5945fe0a5e39f740827f6ffbda1bb501e2) |  | ||||||
| * many PHP exceptions in different places |  | ||||||
| * fixes to tibiacom menus ActiveSubmenuItem |  | ||||||
|  |  | ||||||
| ### Removed |  | ||||||
| * bugtracker SQL table code as the page has been removed/moved to plugins (https://github.com/slawkens/myaac/commit/5782772b901b05fb814bc718d062f6e2cd71df8c) |  | ||||||
|  |  | ||||||
| ## [1.0-RC.2 - 25.10.2024] | ## [1.0-RC.2 - 25.10.2024] | ||||||
|  |  | ||||||
| Still waiting for your reports about bugs found in this release. We are very close to stable release. | Still waiting for your reports about bugs found in this release. We are very close to stable release. | ||||||
| @@ -158,4 +116,4 @@ Minimum PHP version for this release is 8.1. | |||||||
| * change_password email to be more informal | * change_password email to be more informal | ||||||
|  |  | ||||||
| ### Fixed | ### Fixed | ||||||
| * hundreds of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here | * hundrets of bug fixes, mostly patched from 0.8, so it makes no sense writing them again here | ||||||
|   | |||||||
| @@ -10,7 +10,6 @@ | |||||||
|  |  | ||||||
| use MyAAC\Cache\Cache; | use MyAAC\Cache\Cache; | ||||||
| use MyAAC\Models\Menu; | use MyAAC\Models\Menu; | ||||||
| use MyAAC\Plugins; |  | ||||||
|  |  | ||||||
| defined('MYAAC') or die('Direct access not allowed!'); | defined('MYAAC') or die('Direct access not allowed!'); | ||||||
| $title = 'Menus'; | $title = 'Menus'; | ||||||
| @@ -22,8 +21,6 @@ if (!hasFlag(FLAG_CONTENT_MENUS) && !superAdmin()) { | |||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| $pluginThemes = Plugins::getThemes(); |  | ||||||
|  |  | ||||||
| if (isset($_POST['template'])) { | if (isset($_POST['template'])) { | ||||||
| 	$template = $_POST['template']; | 	$template = $_POST['template']; | ||||||
|  |  | ||||||
| @@ -67,16 +64,9 @@ if (isset($_POST['template'])) { | |||||||
| 		success('Saved at ' . date('H:i')); | 		success('Saved at ' . date('H:i')); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	$path = TEMPLATES . $template; | 	$file = TEMPLATES . $template . '/config.php'; | ||||||
|  | 	if (file_exists($file)) { | ||||||
| 	if (isset($pluginThemes[$template])) { | 		require_once $file; | ||||||
| 		$path = BASE . $pluginThemes[$template]; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	$path .= '/config.php'; |  | ||||||
|  |  | ||||||
| 	if (file_exists($path)) { |  | ||||||
| 		require_once $path; |  | ||||||
| 	} else { | 	} else { | ||||||
| 		echo 'Cannot find template config.php file.'; | 		echo 'Cannot find template config.php file.'; | ||||||
| 		return; | 		return; | ||||||
| @@ -179,13 +169,8 @@ if (isset($_POST['template'])) { | |||||||
| } else { | } else { | ||||||
| 	$templates = Menu::select('template')->distinct()->get()->toArray(); | 	$templates = Menu::select('template')->distinct()->get()->toArray(); | ||||||
| 	foreach ($templates as $key => $value) { | 	foreach ($templates as $key => $value) { | ||||||
| 		$path = TEMPLATES . $value['template']; | 		$file = TEMPLATES . $value['template'] . '/config.php'; | ||||||
|  | 		if (!file_exists($file)) { | ||||||
| 		if (isset($pluginThemes[$value['template']])) { |  | ||||||
| 			$path = BASE . $pluginThemes[$value['template']]; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (!file_exists($path . '/config.php')) { |  | ||||||
| 			unset($templates[$key]); | 			unset($templates[$key]); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ | |||||||
| if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); | if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.'); | ||||||
|  |  | ||||||
| const MYAAC = true; | const MYAAC = true; | ||||||
| const MYAAC_VERSION = '1.0'; | const MYAAC_VERSION = '1.0-RC.2'; | ||||||
| const DATABASE_VERSION = 42; | 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')); | ||||||
|   | |||||||
							
								
								
									
										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 ; | ||||||
| @@ -134,7 +134,7 @@ if(setting('core.anonymous_usage_statistics')) { | |||||||
| 		if(fetchDatabaseConfig('last_usage_report', $value)) { | 		if(fetchDatabaseConfig('last_usage_report', $value)) { | ||||||
| 			$should_report = time() > (int)$value + $report_time; | 			$should_report = time() > (int)$value + $report_time; | ||||||
| 			if($cache->enabled()) { | 			if($cache->enabled()) { | ||||||
| 				$cache->set('last_usage_report', $value, 60 * 60); | 				$cache->set('last_usage_report', $value); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| @@ -148,7 +148,7 @@ if(setting('core.anonymous_usage_statistics')) { | |||||||
|  |  | ||||||
| 		updateDatabaseConfig('last_usage_report', time()); | 		updateDatabaseConfig('last_usage_report', time()); | ||||||
| 		if($cache->enabled()) { | 		if($cache->enabled()) { | ||||||
| 			$cache->set('last_usage_report', time(), 60 * 60); | 			$cache->set('last_usage_report', time()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| SET @myaac_database_version = 42; | SET @myaac_database_version = 41; | ||||||
|  |  | ||||||
| CREATE TABLE `myaac_account_actions` | CREATE TABLE `myaac_account_actions` | ||||||
| ( | ( | ||||||
| @@ -91,7 +91,7 @@ CREATE TABLE `myaac_forum` | |||||||
| 	`post_date` int(20) NOT NULL default '0', | 	`post_date` int(20) NOT NULL default '0', | ||||||
| 	`last_edit_aid` int(20) NOT NULL default '0', | 	`last_edit_aid` int(20) NOT NULL default '0', | ||||||
| 	`edit_date` int(20) NOT NULL default '0', | 	`edit_date` int(20) NOT NULL default '0', | ||||||
| 	`post_ip` varchar(45) NOT NULL default '0.0.0.0', | 	`post_ip` varchar(32) NOT NULL default '0.0.0.0', | ||||||
| 	`sticked` tinyint(1) NOT NULL DEFAULT '0', | 	`sticked` tinyint(1) NOT NULL DEFAULT '0', | ||||||
| 	`closed` tinyint(1) NOT NULL DEFAULT '0', | 	`closed` tinyint(1) NOT NULL DEFAULT '0', | ||||||
| 	PRIMARY KEY (`id`), | 	PRIMARY KEY (`id`), | ||||||
|   | |||||||
| @@ -195,7 +195,7 @@ if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		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/> | ||||||
|   | |||||||
| @@ -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, | ||||||
|   | |||||||
| @@ -41,6 +41,9 @@ if(!$error) { | |||||||
| 	$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; | 	$configToSave['database_auto_migrate'] = true; | ||||||
|  | 	if (isset($config['install_ignore_ip_check'])) { | ||||||
|  | 		$configToSave['install_ignore_ip_check'] = $config['install_ignore_ip_check']; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if(!$error) { | 	if(!$error) { | ||||||
| 		$content = ''; | 		$content = ''; | ||||||
| @@ -77,7 +80,7 @@ if(!$error) { | |||||||
| 			$_SESSION['config_content'] = $content; | 			$_SESSION['config_content'] = $content; | ||||||
| 			unset($_SESSION['saved']); | 			unset($_SESSION['saved']); | ||||||
|  |  | ||||||
| 			$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.php</b>', $locale['step_database_error_file']); | 					$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/> | 			error($locale['step_database_error_file'] . '<br/> | ||||||
| 				<textarea cols="70" rows="10">' . $content . '</textarea>'); | 				<textarea cols="70" rows="10">' . $content . '</textarea>'); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -12,6 +12,10 @@ server { | |||||||
| 		deny all; | 		deny all; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	location /vendor { | ||||||
|  | 		deny all; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	# block .htaccess, CHANGELOG.md, composer.json etc. | 	# block .htaccess, CHANGELOG.md, composer.json etc. | ||||||
| 	# this is to prevent finding software versions | 	# this is to prevent finding software versions | ||||||
| 	location ~\.(ht|md|json|dist)$ { | 	location ~\.(ht|md|json|dist)$ { | ||||||
|   | |||||||
| @@ -9,16 +9,16 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Exceptions\SensitiveException; | use MyAAC\Exceptions\SensitiveException; | ||||||
| use Whoops\Handler\PlainTextHandler; |  | ||||||
| use Whoops\Handler\PrettyPageHandler; |  | ||||||
| use Whoops\Run; |  | ||||||
|  |  | ||||||
| if (class_exists(Run::class)) { | if (class_exists(\Whoops\Run::class)) { | ||||||
| 	$whoops = new Run; | 	$whoops = new \Whoops\Run; | ||||||
|  | 	if(IS_CLI) { | ||||||
|  | 		$whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	$whoopsHandler = IS_CLI ? (new PlainTextHandler()) : (new PrettyPageHandler()); |  | ||||||
|  |  | ||||||
| 	$whoops->pushHandler($whoopsHandler); |  | ||||||
| 	$whoops->register(); | 	$whoops->register(); | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -589,12 +589,24 @@ function template_form() | |||||||
| { | { | ||||||
| 	global $template_name; | 	global $template_name; | ||||||
|  |  | ||||||
| 	$templates = Cache::remember('templates', 5 * 60, function() { | 	$cache = Cache::getInstance(); | ||||||
| 		return get_templates(); | 	if($cache->enabled()) | ||||||
| 	}); | 	{ | ||||||
|  | 		$tmp = ''; | ||||||
|  | 		if($cache->fetch('templates', $tmp)) { | ||||||
|  | 			$templates = unserialize($tmp); | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			$templates = get_templates(); | ||||||
|  | 			$cache->set('templates', serialize($templates), 30); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 		$templates = get_templates(); | ||||||
|  |  | ||||||
| 	$options = ''; | 	$options = ''; | ||||||
| 	foreach($templates as $value) | 	foreach($templates as $key => $value) | ||||||
| 		$options .= '<option ' . ($template_name == $value ? 'SELECTED' : '') . '>' . $value . '</option>'; | 		$options .= '<option ' . ($template_name == $value ? 'SELECTED' : '') . '>' . $value . '</option>'; | ||||||
|  |  | ||||||
| 	global $twig; | 	global $twig; | ||||||
| @@ -1090,16 +1102,20 @@ function csrfProtect(): void | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| function getTopPlayers($limit = 5, $skill = 'level') { | function getTopPlayers($limit = 5) { | ||||||
| 	global $db; | 	global $db; | ||||||
|  |  | ||||||
| 	if ($skill === 'level') { | 	$cache = Cache::getInstance(); | ||||||
| 		$skill = 'experience'; | 	if($cache->enabled()) { | ||||||
|  | 		$tmp = ''; | ||||||
|  | 		if($cache->fetch('top_' . $limit . '_level', $tmp)) { | ||||||
|  | 			$players = unserialize($tmp); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return Cache::remember("top_{$limit}_{$skill}", 2 * 60, function () use ($db, $limit, $skill) { | 	if (!isset($players)) { | ||||||
| 		$columns = [ | 		$columns = [ | ||||||
| 			'id', 'name', 'level', 'vocation', 'experience', 'balance', | 			'id', 'name', 'level', 'vocation', 'experience', | ||||||
| 			'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet' | 			'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet' | ||||||
| 		]; | 		]; | ||||||
|  |  | ||||||
| @@ -1111,27 +1127,32 @@ function getTopPlayers($limit = 5, $skill = 'level') { | |||||||
| 			$columns[] = 'online'; | 			$columns[] = 'online'; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return Player::query() | 		$players = Player::query() | ||||||
| 			->select($columns) | 			->select($columns) | ||||||
| 			->withOnlineStatus() | 			->withOnlineStatus() | ||||||
| 			->notDeleted() | 			->notDeleted() | ||||||
| 			->where('group_id', '<', setting('core.highscores_groups_hidden')) | 			->where('group_id', '<', setting('core.highscores_groups_hidden')) | ||||||
| 			->whereNotIn('id', setting('core.highscores_ids_hidden')) | 			->whereNotIn('id', setting('core.highscores_ids_hidden')) | ||||||
| 			->where('account_id', '!=', 1) | 			->where('account_id', '!=', 1) | ||||||
| 			->orderByDesc($skill) | 			->orderByDesc('experience') | ||||||
| 			->limit($limit) | 			->limit($limit) | ||||||
| 			->get() | 			->get() | ||||||
| 			->map(function ($e, $i) { | 			->map(function ($e, $i) { | ||||||
| 				$row = $e->toArray(); | 				$row = $e->toArray(); | ||||||
| 				$row['online'] = $e->online_status; | 				$row['online'] = $e->online_status; | ||||||
| 				$row['rank'] = $i + 1; | 				$row['rank'] = $i + 1; | ||||||
| 				$row['outfit_url'] = $e->outfit_url; |  | ||||||
|  |  | ||||||
| 				unset($row['online_table']); | 				unset($row['online_table']); | ||||||
|  |  | ||||||
| 				return $row; | 				return $row; | ||||||
| 			})->toArray(); | 			})->toArray(); | ||||||
| 	}); |  | ||||||
|  | 		if($cache->enabled()) { | ||||||
|  | 			$cache->set('top_' . $limit . '_level', serialize($players), 120); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return $players; | ||||||
| } | } | ||||||
|  |  | ||||||
| function deleteDirectory($dir, $ignore = array(), $contentOnly = false) { | function deleteDirectory($dir, $ignore = array(), $contentOnly = false) { | ||||||
|   | |||||||
| @@ -96,8 +96,8 @@ if($config_lua_reload) { | |||||||
|  |  | ||||||
| 	// cache config | 	// cache config | ||||||
| 	if($cache->enabled()) { | 	if($cache->enabled()) { | ||||||
| 		$cache->set('config_lua', serialize($config['lua']), 2 * 60); | 		$cache->set('config_lua', serialize($config['lua']), 120); | ||||||
| 		$cache->set('server_path', $config['server_path'], 10 * 60); | 		$cache->set('server_path', $config['server_path']); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| unset($tmp); | unset($tmp); | ||||||
|   | |||||||
| @@ -1752,6 +1752,11 @@ class OTS_Player extends OTS_Row_DAO | |||||||
|  */ |  */ | ||||||
|     public function getConditions() |     public function getConditions() | ||||||
|     { |     { | ||||||
|  |         if( !isset($this->data['conditions']) ) | ||||||
|  |         { | ||||||
|  |             throw new E_OTS_NotLoaded(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         return $this->data['conditions']; |         return $this->data['conditions']; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| // the size of ipv6 can be maximal 45 chars | // the size of ipv6 can be maximal 45 chars | ||||||
|  |  | ||||||
| $up = function () use ($db) { | $up = function () use ($db) { | ||||||
| 	$db->modifyColumn(TABLE_PREFIX . 'visitors', 'ip', 'VARCHAR(45) NOT NULL'); | 	$db->modifyColumn(TABLE_PREFIX . 'visitors', 'ip', 'VARCHAR(15) NOT NULL'); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| $down = function () { | $down = function () { | ||||||
|   | |||||||
| @@ -1,15 +0,0 @@ | |||||||
| <?php |  | ||||||
| /** |  | ||||||
|  * @var OTS_DB_MySQL $db |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| // 2025-09-01 |  | ||||||
| // resize forum.post_ip to support ipv6 |  | ||||||
| $up = function () use ($db) { |  | ||||||
| 	$db->modifyColumn(TABLE_PREFIX . 'forum', 'post_ip', "varchar(45) NOT NULL default '0.0.0.0'"); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| $down = function () { |  | ||||||
| 	// there is no downgrade for this |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| @@ -66,7 +66,7 @@ else | |||||||
| 							$new_sex_str = $config['genders'][$new_sex]; | 							$new_sex_str = $config['genders'][$new_sex]; | ||||||
|  |  | ||||||
| 						$player->save(); | 						$player->save(); | ||||||
| 						$account_logged->setCustomField(setting('core.donate_column'), $points - setting('core.account_change_character_sex_price')); | 						$account_logged->setCustomField(setting('core.donate_column'), $points - setting('core.account_change_character_name_price')); | ||||||
| 						$account_logged->logAction('Changed sex on character <b>' . $player->getName() . '</b> from <b>' . $old_sex_str . '</b> to <b>' . $new_sex_str . '</b>.'); | 						$account_logged->logAction('Changed sex on character <b>' . $player->getName() . '</b> from <b>' . $old_sex_str . '</b> to <b>' . $new_sex_str . '</b>.'); | ||||||
| 						$twig->display('success.html.twig', array( | 						$twig->display('success.html.twig', array( | ||||||
| 							'title' => 'Character Sex Changed', | 							'title' => 'Character Sex Changed', | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ if(Forum::canPost($account_logged)) | |||||||
| 	$thread = $db->query("SELECT `author_guid`, `author_aid`, `first_post`, `post_topic`, `post_date`, `post_text`, `post_smile`, `post_html`, `id`, `section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `id` = ".$post_id." LIMIT 1")->fetch(); | 	$thread = $db->query("SELECT `author_guid`, `author_aid`, `first_post`, `post_topic`, `post_date`, `post_text`, `post_smile`, `post_html`, `id`, `section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `id` = ".$post_id." LIMIT 1")->fetch(); | ||||||
| 	if(isset($thread['id'])) { | 	if(isset($thread['id'])) { | ||||||
| 		$first_post = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread['first_post']." LIMIT 1")->fetch(); | 		$first_post = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread['first_post']." LIMIT 1")->fetch(); | ||||||
| 		echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread['first_post']) . '">'.htmlspecialchars($first_post['post_topic']).'</a> >> <b>Edit post</b>'; | 		echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread['first_post']) . '">'.$first_post['post_topic'].'</a> >> <b>Edit post</b>'; | ||||||
|  |  | ||||||
| 		if(Forum::hasAccess($thread['section'] && ($account_logged->getId() == $thread['author_aid'] || Forum::isModerator()))) { | 		if(Forum::hasAccess($thread['section'] && ($account_logged->getId() == $thread['author_aid'] || Forum::isModerator()))) { | ||||||
| 			$char_id = $post_topic = $text = $smile = $html = null; | 			$char_id = $post_topic = $text = $smile = $html = null; | ||||||
|   | |||||||
| @@ -25,7 +25,6 @@ if(!$logged) { | |||||||
|  |  | ||||||
| if(!Forum::isModerator()) { | if(!Forum::isModerator()) { | ||||||
| 	echo 'You are not logged in or you are not moderator.'; | 	echo 'You are not logged in or you are not moderator.'; | ||||||
| 	return; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| $save = isset($_REQUEST['save']) && (int)$_REQUEST['save'] == 1; | $save = isset($_REQUEST['save']) && (int)$_REQUEST['save'] == 1; | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ if(Forum::canPost($account_logged)) { | |||||||
| 	$thread = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".$thread_id." LIMIT 1")->fetch(); | 	$thread = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".$thread_id." LIMIT 1")->fetch(); | ||||||
|  |  | ||||||
| 	if(isset($thread['id']) && Forum::hasAccess($thread['section'])) { | 	if(isset($thread['id']) && Forum::hasAccess($thread['section'])) { | ||||||
| 		echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread_id) . '">'.htmlspecialchars($thread['post_topic']).'</a> >> <b>Post new reply</b><br /><h3>'.htmlspecialchars($thread['post_topic']).'</h3>'; | 		echo '<a href="' . getLink('forum') . '">Boards</a> >> <a href="' . getForumBoardLink($thread['section']) . '">'.$sections[$thread['section']]['name'].'</a> >> <a href="' . getForumThreadLink($thread_id) . '">'.$thread['post_topic'].'</a> >> <b>Post new reply</b><br /><h3>'.$thread['post_topic'].'</h3>'; | ||||||
|  |  | ||||||
| 		$quote = isset($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : NULL; | 		$quote = isset($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : NULL; | ||||||
| 		$text = isset($_REQUEST['text']) ? stripslashes(trim($_REQUEST['text'])) : NULL; | 		$text = isset($_REQUEST['text']) ? stripslashes(trim($_REQUEST['text'])) : NULL; | ||||||
|   | |||||||
| @@ -95,23 +95,7 @@ if(Forum::canPost($account_logged)) { | |||||||
| 				if (count($errors) == 0) { | 				if (count($errors) == 0) { | ||||||
| 					$saved = true; | 					$saved = true; | ||||||
|  |  | ||||||
| 					$db->insert(FORUM_TABLE_PREFIX . 'forum', [ | 					$db->query("INSERT INTO `" . FORUM_TABLE_PREFIX . "forum` (`first_post` ,`last_post` ,`section` ,`replies` ,`views` ,`author_aid` ,`author_guid` ,`post_text` ,`post_topic` ,`post_smile`, `post_html` ,`post_date` ,`last_edit_aid` ,`edit_date`, `post_ip`) VALUES ('0', '" . time() . "', '" . (int)$section_id . "', '0', '0', '" . $account_logged->getId() . "', '" . $char_id . "', " . $db->quote($text) . ", " . $db->quote($post_topic) . ", '" . $smile . "', '" . $html . "', '" . time() . "', '0', '0', '" . get_browser_real_ip() . "')"); | ||||||
| 						'first_post' => 0, |  | ||||||
| 						'last_post' => time(), |  | ||||||
| 						'section' => $section_id, |  | ||||||
| 						'replies' => 0, |  | ||||||
| 						'views' => 0, |  | ||||||
| 						'author_aid' => $account_logged->getId(), |  | ||||||
| 						'author_guid' => $char_id, |  | ||||||
| 						'post_text' => $text, |  | ||||||
| 						'post_topic' => $post_topic, |  | ||||||
| 						'post_smile' => $smile, |  | ||||||
| 						'post_html' => $html, |  | ||||||
| 						'post_date' => time(), |  | ||||||
| 						'last_edit_aid' => 0, |  | ||||||
| 						'edit_date' => 0, |  | ||||||
| 						'post_ip' => get_browser_real_ip(), |  | ||||||
| 					]); |  | ||||||
|  |  | ||||||
| 					$thread_id = $db->lastInsertId(); | 					$thread_id = $db->lastInsertId(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ if(isset($last_threads[0])) { | |||||||
| 		echo '<tr bgcolor="' . getStyle($number_of_rows++) . '"><td>'; | 		echo '<tr bgcolor="' . getStyle($number_of_rows++) . '"><td>'; | ||||||
| 		if(Forum::isModerator()) { | 		if(Forum::isModerator()) { | ||||||
| 			echo '<a href="' . getLink('forum') . '?action=move_thread&id='.$thread['id'].'"\')"><span style="color:darkgreen">[MOVE]</span></a>'; | 			echo '<a href="' . getLink('forum') . '?action=move_thread&id='.$thread['id'].'"\')"><span style="color:darkgreen">[MOVE]</span></a>'; | ||||||
| 			echo '<a href="' . getLink('forum') . '?action=remove_post&id='.$thread['id'].'" onclick="return confirm(\'Are you sure you want remove thread > '.htmlspecialchars($thread['post_topic']).' <?\')"><span style="color: red">[REMOVE]</span></a>  '; | 			echo '<a href="' . getLink('forum') . '?action=remove_post&id='.$thread['id'].'" onclick="return confirm(\'Are you sure you want remove thread > '.$thread['post_topic'].' <?\')"><span style="color: red">[REMOVE]</span></a>  '; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		$player->load($thread['player_id']); | 		$player->load($thread['player_id']); | ||||||
| @@ -79,7 +79,7 @@ if(isset($last_threads[0])) { | |||||||
| 		$player_account = $player->getAccount(); | 		$player_account = $player->getAccount(); | ||||||
| 		$canEditForum = $player_account->hasFlag(FLAG_CONTENT_FORUM) || $player_account->isAdmin(); | 		$canEditForum = $player_account->hasFlag(FLAG_CONTENT_FORUM) || $player_account->isAdmin(); | ||||||
|  |  | ||||||
| 		echo '<a href="' . getForumThreadLink($thread['id']) . '">'.htmlspecialchars($thread['post_topic']). '</a><br /><small>'.($canEditForum ? substr(strip_tags($thread['post_text']), 0, 50) : htmlspecialchars(substr($thread['post_text'], 0, 50))).'...</small></td><td>' . getPlayerLink($thread['name']) . '</td><td>'.(int) $thread['replies'].'</td><td>'.(int) $thread['views'].'</td><td>'; | 		echo '<a href="' . getForumThreadLink($thread['id']) . '">'.($canEditForum ? $thread['post_topic'] : htmlspecialchars($thread['post_topic'])) . '</a><br /><small>'.($canEditForum ? substr(strip_tags($thread['post_text']), 0, 50) : htmlspecialchars(substr($thread['post_text'], 0, 50))).'...</small></td><td>' . getPlayerLink($thread['name']) . '</td><td>'.(int) $thread['replies'].'</td><td>'.(int) $thread['views'].'</td><td>'; | ||||||
| 		if($thread['last_post'] > 0) { | 		if($thread['last_post'] > 0) { | ||||||
| 			$last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['id']." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch(); | 			$last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['id']." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch(); | ||||||
| 			if(isset($last_post['name'])) | 			if(isset($last_post['name'])) | ||||||
|   | |||||||
| @@ -207,7 +207,6 @@ if (empty($highscores)) { | |||||||
| 		$tmp = $row->toArray(); | 		$tmp = $row->toArray(); | ||||||
| 		$tmp['online'] = $row->online_status; | 		$tmp['online'] = $row->online_status; | ||||||
| 		$tmp['vocation'] = $row->vocation_name; | 		$tmp['vocation'] = $row->vocation_name; | ||||||
| 		$tmp['outfit_url'] = $row->outfit_url; // @phpstan-ignore-line |  | ||||||
| 		unset($tmp['online_table']); | 		unset($tmp['online_table']); | ||||||
|  |  | ||||||
| 		return $tmp; | 		return $tmp; | ||||||
| @@ -241,7 +240,7 @@ foreach($highscores as $id => &$player) | |||||||
| 		$player['link'] = getPlayerLink($player['name'], false); | 		$player['link'] = getPlayerLink($player['name'], false); | ||||||
| 		$player['flag'] = getFlagImage($player['country']); | 		$player['flag'] = getFlagImage($player['country']); | ||||||
| 		if($settingHighscoresOutfit) { | 		if($settingHighscoresOutfit) { | ||||||
| 			$player['outfit'] = '<img style="position:absolute;margin-top:' . (in_array($player['looktype'], setting('core.outfit_images_wrong_looktypes')) ? '-15px;margin-left:5px' : '-45px;margin-left:-25px') . ';" src="' . $player['outfit_url'] . '" alt="" />'; | 			$player['outfit'] = '<img style="position:absolute;margin-top:' . (in_array($player['looktype'], setting('core.outfit_images_wrong_looktypes')) ? '-15px;margin-left:5px' : '-45px;margin-left:-25px') . ';" src="' . setting('core.outfit_images_url') . '?id=' . $player['looktype'] . ($outfit_addons ? '&addons=' . $player['lookaddons'] : '') . '&head=' . $player['lookhead'] . '&body=' . $player['lookbody'] . '&legs=' . $player['looklegs'] . '&feet=' . $player['lookfeet'] . '" alt="" />'; | ||||||
| 		} | 		} | ||||||
| 		$player['rank'] = $offset + $i; | 		$player['rank'] = $offset + $i; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -11,14 +11,8 @@ | |||||||
|  *  - for number: min, max, step |  *  - for number: min, max, step | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| use MyAAC\Cache; |  | ||||||
| use MyAAC\Settings; | use MyAAC\Settings; | ||||||
|  |  | ||||||
| $templates = Cache::remember('templates', 5 * 60, function () { |  | ||||||
| 	return get_templates(); |  | ||||||
| }); |  | ||||||
| $defaultTemplate = in_array('kathrine', $templates) ? 'kathrine' : $templates[0]; |  | ||||||
|  |  | ||||||
| return [ | return [ | ||||||
| 	'name' => 'MyAAC', | 	'name' => 'MyAAC', | ||||||
| 	'settings' => [ | 	'settings' => [ | ||||||
| @@ -94,7 +88,7 @@ return [ | |||||||
| 			'type' => 'options', | 			'type' => 'options', | ||||||
| 			'options' => '$templates', | 			'options' => '$templates', | ||||||
| 			'desc' => 'Name of the template used by website', | 			'desc' => 'Name of the template used by website', | ||||||
| 			'default' => $defaultTemplate, | 			'default' => 'kathrine', | ||||||
| 		], | 		], | ||||||
| 		'template_allow_change' => [ | 		'template_allow_change' => [ | ||||||
| 			'name' => 'Template Allow Change', | 			'name' => 'Template Allow Change', | ||||||
|   | |||||||
| @@ -82,9 +82,7 @@ class DataLoader | |||||||
| 		self::$startTime = microtime(true); | 		self::$startTime = microtime(true); | ||||||
|  |  | ||||||
| 		$cache = Cache::getInstance(); | 		$cache = Cache::getInstance(); | ||||||
| 		if ($cache->enabled()) { |  | ||||||
| 		$cache->delete('towns'); // will be reloaded after next page load | 		$cache->delete('towns'); // will be reloaded after next page load | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		global $db; | 		global $db; | ||||||
| 		if ($db->hasTable('towns') && Town::count() > 0) { | 		if ($db->hasTable('towns') && Town::count() > 0) { | ||||||
|   | |||||||
| @@ -8,13 +8,6 @@ use Illuminate\Database\Eloquent\Relations\HasOne; | |||||||
|  * @property int $level |  * @property int $level | ||||||
|  * @property int $vocation |  * @property int $vocation | ||||||
|  * @property int $online |  * @property int $online | ||||||
|  * @property int $looktype |  | ||||||
|  * @property int $lookhead |  | ||||||
|  * @property int $lookbody |  | ||||||
|  * @property int $looklegs |  | ||||||
|  * @property int $lookfeet |  | ||||||
|  * @property int $lookaddons |  | ||||||
|  * @property string $outfit_url |  | ||||||
|  * @property hasOne $onlineTable |  * @property hasOne $onlineTable | ||||||
|  */ |  */ | ||||||
| class Player extends Model { | class Player extends Model { | ||||||
| @@ -87,10 +80,6 @@ class Player extends Model { | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public function getOutfitUrlAttribute() { |  | ||||||
| 		return setting('core.outfit_images_url') . '?id=' . $this->looktype . (!empty($this->lookaddons) ? '&addons=' . $this->lookaddons : '') . '&head=' . $this->lookhead . '&body=' . $this->lookbody . '&legs=' . $this->looklegs . '&feet=' . $this->lookfeet; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	public function getOnlineStatusAttribute() | 	public function getOnlineStatusAttribute() | ||||||
| 	{ | 	{ | ||||||
| 		global $db; | 		global $db; | ||||||
|   | |||||||
| @@ -95,7 +95,7 @@ else { | |||||||
| 		unset($file); | 		unset($file); | ||||||
|  |  | ||||||
| 		if ($cache->enabled()) { | 		if ($cache->enabled()) { | ||||||
| 			$cache->set('template_ini_' . $template_name, serialize($template_ini), 10 * 60); | 			$cache->set('template_ini_' . $template_name, serialize($template_ini)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -138,19 +138,29 @@ if($twig_loader) { | |||||||
| 	$twig_loader->prependPath(BASE . $template_path); | 	$twig_loader->prependPath(BASE . $template_path); | ||||||
| } | } | ||||||
|  |  | ||||||
| function get_template_menus(): array | function get_template_menus() { | ||||||
| { |  | ||||||
| 	global $template_name; | 	global $template_name; | ||||||
|  |  | ||||||
| 	$result = Cache::remember('template_menus', 10 * 60, function () use ($template_name) { | 	$cache = Cache::getInstance(); | ||||||
|  | 	if ($cache->enabled()) { | ||||||
|  | 		$tmp = ''; | ||||||
|  | 		if ($cache->fetch('template_menus', $tmp)) { | ||||||
|  | 			$result = unserialize($tmp); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!isset($result)) { | ||||||
|  |  | ||||||
| 		$result = Menu::select(['name', 'link', 'blank', 'color', 'category']) | 		$result = Menu::select(['name', 'link', 'blank', 'color', 'category']) | ||||||
| 			->where('template', $template_name) | 			->where('template', $template_name) | ||||||
| 			->orderBy('category') | 			->orderBy('category') | ||||||
| 			->orderBy('ordering') | 			->orderBy('ordering') | ||||||
| 			->get(); | 			->get(); | ||||||
|  |  | ||||||
| 		return $result->toArray(); | 		if ($cache->enabled()) { | ||||||
| 	}); | 			$cache->set('template_menus', serialize($result->toArray()), 600); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	$menus = array(); | 	$menus = array(); | ||||||
| 	foreach($result as $menu) { | 	foreach($result as $menu) { | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ | |||||||
| <table width="100%"> | <table width="100%"> | ||||||
| 	<tr bgcolor="{{ config.vdarkborder }}"> | 	<tr bgcolor="{{ config.vdarkborder }}"> | ||||||
| 		<td colspan="2"> | 		<td colspan="2"> | ||||||
| 			<span style="color: white"><b>Last 5 posts from thread: {{ topic }}</b></span> | 			<span style="color: white"><b>Last 5 posts from thread: {{ topic|raw }}</b></span> | ||||||
| 		</td> | 		</td> | ||||||
| 	</tr> | 	</tr> | ||||||
| 	{% set i = 0 %} | 	{% set i = 0 %} | ||||||
|   | |||||||
| @@ -10,9 +10,13 @@ | |||||||
| 	<input type="hidden" name="step" id="step" value="database" /> | 	<input type="hidden" name="step" id="step" value="database" /> | ||||||
|  |  | ||||||
| 	{% for value in ['server_path'] %} | 	{% for value in ['server_path'] %} | ||||||
|  | 		{% if value == 'server_path' and config.server_path is not null %} | ||||||
|  | 			{% set server_path = { 'var_server_path': config.server_path } %} | ||||||
|  | 			{% set session = session | merge (server_path) %} | ||||||
|  | 		{% endif %} | ||||||
| 	<div class="form-group mb-2"> | 	<div class="form-group mb-2"> | ||||||
| 		<label for="vars_{{ value }}">{{ locale['step_config_' ~ value]  }}</label> | 		<label for="vars_{{ value }}">{{ locale['step_config_' ~ value]  }}</label> | ||||||
| 		<input class="form-control" type="{% if value == 'mail_admin' %}email{% else %}text{% endif %}" name="vars[{{ value }}]" id="vars_{{ value }}"{% if session['var_' ~ value] is not null %} value="{{ session['var_' ~ value] }}"{% endif %}/> | 		<input class="form-control" type="text" name="vars[{{ value }}]" id="vars_{{ value }}"{% if session['var_' ~ value] is not null %} value="{{ session['var_' ~ value] }}"{% endif %}/> | ||||||
| 		<small class="form-text text-muted">{{ locale['step_config_' ~ value ~ '_desc'] }}</small> | 		<small class="form-text text-muted">{{ locale['step_config_' ~ value ~ '_desc'] }}</small> | ||||||
| 	</div> | 	</div> | ||||||
| 	{% endfor %} | 	{% endfor %} | ||||||
|   | |||||||
| @@ -348,7 +348,7 @@ foreach($config['menu_categories'] as $id => $cat) { | |||||||
| 			} | 			} | ||||||
| 			$link_color = '#' . (strlen($menu['color']) == 0 ? $default_menu_color : $menu['color']); | 			$link_color = '#' . (strlen($menu['color']) == 0 ? $default_menu_color : $menu['color']); | ||||||
| 			?> | 			?> | ||||||
| 			<a href='<?php echo $menu['link_full']; ?>'<?= $menu['target_blank']?>> | 			<a href='<?php echo $menu['link_full']; ?>'<?php echo $menu['blank'] ? ' target="_blank"' : ''?>> | ||||||
| 				<div id='submenu_<?php echo str_replace('/', '_', $menu['link']); ?>' class='Submenuitem' onMouseOver='MouseOverSubmenuItem(this)' onMouseOut='MouseOutSubmenuItem(this)' style="color: <?php echo $link_color; ?>;"> | 				<div id='submenu_<?php echo str_replace('/', '_', $menu['link']); ?>' class='Submenuitem' onMouseOver='MouseOverSubmenuItem(this)' onMouseOut='MouseOutSubmenuItem(this)' style="color: <?php echo $link_color; ?>;"> | ||||||
| 					<div class='LeftChain' style='background-image:url(<?php echo $template_path; ?>/images/general/chain.gif);'></div> | 					<div class='LeftChain' style='background-image:url(<?php echo $template_path; ?>/images/general/chain.gif);'></div> | ||||||
| 					<div id='ActiveSubmenuItemIcon_<?php echo str_replace('/', '_', $menu['link']); ?>' class='ActiveSubmenuItemIcon' style='background-image:url(<?php echo $template_path; ?>/images/menu/icon-activesubmenu.gif);'></div> | 					<div id='ActiveSubmenuItemIcon_<?php echo str_replace('/', '_', $menu['link']); ?>' class='ActiveSubmenuItemIcon' style='background-image:url(<?php echo $template_path; ?>/images/menu/icon-activesubmenu.gif);'></div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user