mirror of
				https://github.com/slawkens/myaac.git
				synced 2025-10-31 16:06:24 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			327 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			327 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Highscores
 | |
|  *
 | |
|  * @package   MyAAC
 | |
|  * @author    Gesior <jerzyskalski@wp.pl>
 | |
|  * @author    Slawkens <slawkens@gmail.com>
 | |
|  * @copyright 2019 MyAAC
 | |
|  * @link      https://my-aac.org
 | |
|  */
 | |
| 
 | |
| use MyAAC\Cache\Cache;
 | |
| use MyAAC\Models\Player;
 | |
| use MyAAC\Models\PlayerDeath;
 | |
| use MyAAC\Models\PlayerKillers;
 | |
| 
 | |
| defined('MYAAC') or die('Direct access not allowed!');
 | |
| $title = 'Highscores';
 | |
| 
 | |
| $settingHighscoresCountryBox = setting('core.highscores_country_box');
 | |
| if(config('account_country') && $settingHighscoresCountryBox) {
 | |
| 	require SYSTEM . 'countries.conf.php';
 | |
| }
 | |
| 
 | |
| $highscoresTTL = setting('core.highscores_cache_ttl');
 | |
| 
 | |
| $list = urldecode($_GET['list'] ?? 'experience');
 | |
| $page = $_GET['page'] ?? 1;
 | |
| $vocation = urldecode($_GET['vocation'] ?? 'all');
 | |
| 
 | |
| if(!is_numeric($page) || $page < 1 || $page > PHP_INT_MAX) {
 | |
| 	$page = 1;
 | |
| }
 | |
| 
 | |
| $query = Player::query();
 | |
| 
 | |
| $configVocations = config('vocations');
 | |
| $configVocationsAmount = config('vocations_amount');
 | |
| 
 | |
| $vocationId = null;
 | |
| if($vocation !== 'all') {
 | |
| 	foreach($configVocations as $id => $name) {
 | |
| 		if(strtolower($name) == $vocation) {
 | |
| 			$vocationId = $id;
 | |
| 			$add_vocs = [$id];
 | |
| 
 | |
| 			if ($id !== 0) {
 | |
| 				$i = $id + $configVocationsAmount;
 | |
| 				while (isset($configVocations[$i])) {
 | |
| 					$add_vocs[] = $i;
 | |
| 					$i += $configVocationsAmount;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			$query->whereIn('players.vocation', $add_vocs);
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| $skill = POT::SKILL__LEVEL;
 | |
| if(is_numeric($list))
 | |
| {
 | |
| 	$list = (int) $list;
 | |
| 	if($list >= POT::SKILL_FIRST && $list <= POT::SKILL__LAST)
 | |
| 		$skill = $list;
 | |
| }
 | |
| else
 | |
| {
 | |
| 	switch($list)
 | |
| 	{
 | |
| 		case 'fist':
 | |
| 			$skill = POT::SKILL_FIST;
 | |
| 			break;
 | |
| 
 | |
| 		case 'club':
 | |
| 			$skill = POT::SKILL_CLUB;
 | |
| 			break;
 | |
| 
 | |
| 		case 'sword':
 | |
| 			$skill = POT::SKILL_SWORD;
 | |
| 			break;
 | |
| 
 | |
| 		case 'axe':
 | |
| 			$skill = POT::SKILL_AXE;
 | |
| 			break;
 | |
| 
 | |
| 		case 'distance':
 | |
| 			$skill = POT::SKILL_DIST;
 | |
| 			break;
 | |
| 
 | |
| 		case 'shield':
 | |
| 			$skill = POT::SKILL_SHIELD;
 | |
| 			break;
 | |
| 
 | |
| 		case 'fishing':
 | |
| 			$skill = POT::SKILL_FISH;
 | |
| 			break;
 | |
| 
 | |
| 		case 'level':
 | |
| 		case 'experience':
 | |
| 			$skill = POT::SKILL_LEVEL;
 | |
| 			break;
 | |
| 
 | |
| 		case 'magic':
 | |
| 			$skill = POT::SKILL__MAGLEVEL;
 | |
| 			break;
 | |
| 
 | |
| 		case 'frags':
 | |
| 			if(setting('core.highscores_frags'))
 | |
| 				$skill = SKILL_FRAGS;
 | |
| 			break;
 | |
| 
 | |
| 		case 'balance':
 | |
| 			if(setting('core.highscores_balance'))
 | |
| 				$skill = SKILL_BALANCE;
 | |
| 			break;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| $promotion = '';
 | |
| if($db->hasColumn('players', 'promotion'))
 | |
| 	$promotion = ',players.promotion';
 | |
| 
 | |
| $outfit_addons = false;
 | |
| $outfit = ', lookbody, lookfeet, lookhead, looklegs, looktype';
 | |
| if($db->hasColumn('players', 'lookaddons')) {
 | |
| 	$outfit .= ', lookaddons';
 | |
| 	$outfit_addons = true;
 | |
| }
 | |
| 
 | |
| $configHighscoresPerPage = setting('core.highscores_per_page');
 | |
| $limit = $configHighscoresPerPage + 1;
 | |
| 
 | |
| $highscores = [];
 | |
| $needReCache = true;
 | |
| $cacheKey = 'highscores_' . $skill . '_' . $vocation . '_' . $page . '_' . $configHighscoresPerPage;
 | |
| 
 | |
| $cache = Cache::getInstance();
 | |
| if ($cache->enabled() && $highscoresTTL > 0) {
 | |
| 	$tmp = '';
 | |
| 	if ($cache->fetch($cacheKey, $tmp)) {
 | |
| 		$data = unserialize($tmp);
 | |
| 		$totalResults = $data['totalResults'];
 | |
| 		$highscores = $data['highscores'];
 | |
| 		$updatedAt = $data['updatedAt'];
 | |
| 		$needReCache = false;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| $offset = ($page - 1) * $configHighscoresPerPage;
 | |
| $query->withOnlineStatus()
 | |
| 	->whereNotIn('players.id', setting('core.highscores_ids_hidden'))
 | |
| 	->notDeleted()
 | |
| 	->where('players.group_id', '<', setting('core.highscores_groups_hidden'));
 | |
| 
 | |
| $totalResultsQuery = clone $query;
 | |
| 
 | |
| $query
 | |
| 	->join('accounts', 'accounts.id', '=', 'players.account_id')
 | |
| 	->limit($limit)
 | |
| 	->offset($offset)
 | |
| 	->selectRaw('accounts.country, players.id, players.name, players.account_id, players.level, players.vocation' . $outfit . $promotion)
 | |
| 	->orderByDesc('value');
 | |
| 
 | |
| if (empty($highscores)) {
 | |
| 	if ($skill >= POT::SKILL_FIRST && $skill <= POT::SKILL_LAST) { // skills
 | |
| 		if ($db->hasColumn('players', 'skill_fist')) {// tfs 1.0
 | |
| 			$skill_ids = array(
 | |
| 				POT::SKILL_FIST => 'skill_fist',
 | |
| 				POT::SKILL_CLUB => 'skill_club',
 | |
| 				POT::SKILL_SWORD => 'skill_sword',
 | |
| 				POT::SKILL_AXE => 'skill_axe',
 | |
| 				POT::SKILL_DIST => 'skill_dist',
 | |
| 				POT::SKILL_SHIELD => 'skill_shielding',
 | |
| 				POT::SKILL_FISH => 'skill_fishing',
 | |
| 			);
 | |
| 
 | |
| 			$query->addSelect($skill_ids[$skill] . ' as value');
 | |
| 		} else {
 | |
| 			$query
 | |
| 				->join('player_skills', 'player_skills.player_id', '=', 'players.id')
 | |
| 				->where('skillid', $skill)
 | |
| 				->addSelect('player_skills.value as value');
 | |
| 		}
 | |
| 	} else if ($skill == SKILL_FRAGS) // frags
 | |
| 	{
 | |
| 		if ($db->hasTable('player_killers')) {
 | |
| 			$query->addSelect(['value' => PlayerKillers::whereColumn('player_killers.player_id', 'players.id')->selectRaw('COUNT(*)')]);
 | |
| 		} else {
 | |
| 			$query->addSelect(['value' => PlayerDeath::unjustified()->whereColumn('player_deaths.killed_by', 'players.name')->selectRaw('COUNT(*)')]);
 | |
| 		}
 | |
| 	} else if ($skill == SKILL_BALANCE) // balance
 | |
| 	{
 | |
| 		$query
 | |
| 			->addSelect('players.balance as value');
 | |
| 	} else {
 | |
| 		if ($skill == POT::SKILL__MAGLEVEL) {
 | |
| 			$query
 | |
| 				->addSelect('players.maglevel as value', 'players.maglevel')
 | |
| 				->orderBy('manaspent');
 | |
| 		} else { // level
 | |
| 			$query
 | |
| 				->addSelect('players.level as value', 'players.experience')
 | |
| 				->orderBy('experience');
 | |
| 			$list = 'experience';
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	$highscores = $query->get()->map(function($row) {
 | |
| 		$tmp = $row->toArray();
 | |
| 		$tmp['online'] = $row->online_status;
 | |
| 		$tmp['vocation'] = $row->vocation_name;
 | |
| 		$tmp['outfit_url'] = $row->outfit_url; // @phpstan-ignore-line
 | |
| 		unset($tmp['online_table']);
 | |
| 
 | |
| 		return $tmp;
 | |
| 	})->toArray();
 | |
| 
 | |
| 	$updatedAt = time();
 | |
| 	$totalResults = $totalResultsQuery->count();
 | |
| }
 | |
| 
 | |
| if ($highscoresTTL > 0 && $cache->enabled() && $needReCache) {
 | |
| 	$cache->set($cacheKey, serialize(
 | |
| 		[
 | |
| 			'totalResults' => $totalResults,
 | |
| 			'highscores' => $highscores,
 | |
| 			'updatedAt' => $updatedAt,
 | |
| 		]
 | |
| 	), $highscoresTTL * 60);
 | |
| }
 | |
| 
 | |
| $show_link_to_next_page = false;
 | |
| $i = 0;
 | |
| 
 | |
| foreach($highscores as $id => &$player)
 | |
| {
 | |
| 	if(++$i <= $configHighscoresPerPage)
 | |
| 	{
 | |
| 		if($skill == POT::SKILL__MAGIC)
 | |
| 			$player['value'] = $player['maglevel'];
 | |
| 		else if($skill == POT::SKILL__LEVEL) {
 | |
| 			$player['value'] = $player['level'];
 | |
| 			$player['experience'] = number_format($player['experience']);
 | |
| 		}
 | |
| 
 | |
| 		$player['link'] = getPlayerLink($player['name'], false);
 | |
| 		$player['flag'] = getFlagImage($player['country']);
 | |
| 		$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="" />';
 | |
| 
 | |
| 		if ($skill != POT::SKILL__LEVEL) {
 | |
| 			if (isset($lastValue) && $lastValue == $player['value']) {
 | |
| 				$player['rank'] = $lastRank;
 | |
| 			}
 | |
| 			else {
 | |
| 				$player['rank'] = $offset + $i;
 | |
| 			}
 | |
| 
 | |
| 			$lastRank = $player['rank'] ;
 | |
| 			$lastValue = $player['value'];
 | |
| 		}
 | |
| 		else {
 | |
| 			$player['rank'] = $offset + $i;
 | |
| 		}
 | |
| 	}
 | |
| 	else {
 | |
| 		unset($highscores[$id]);
 | |
| 		$show_link_to_next_page = true;
 | |
| 		break;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //link to previous page if actual page is not first
 | |
| $linkPreviousPage = '';
 | |
| if($page > 1) {
 | |
| 	$linkPreviousPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($page - 1);
 | |
| }
 | |
| 
 | |
| //link to next page if any result will be on next page
 | |
| $linkNextPage = '';
 | |
| if($show_link_to_next_page) {
 | |
| 	$linkNextPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($page + 1);
 | |
| }
 | |
| 
 | |
| $baseLink = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/';
 | |
| 
 | |
| $types = array(
 | |
| 	'experience' => 'Experience',
 | |
| 	'magic' => 'Magic',
 | |
| 	'shield' => 'Shielding',
 | |
| 	'distance' => 'Distance',
 | |
| 	'club' => 'Club',
 | |
| 	'sword' => 'Sword',
 | |
| 	'axe' => 'Axe',
 | |
| 	'fist' => 'Fist',
 | |
| 	'fishing' => 'Fishing',
 | |
| );
 | |
| 
 | |
| if(setting('core.highscores_frags')) {
 | |
| 	$types['frags'] = 'Frags';
 | |
| }
 | |
| if(setting('core.highscores_balance'))
 | |
| 	$types['balance'] = 'Balance';
 | |
| 
 | |
| if ($highscoresTTL > 0 && $cache->enabled()) {
 | |
| 	echo '<small>*Note: Highscores are updated every' . ($highscoresTTL > 1 ? ' ' . $highscoresTTL : '') . ' minute' . ($highscoresTTL > 1 ? 's' : '') . '.</small><br/><br/>';
 | |
| }
 | |
| 
 | |
| /** @var Twig\Environment $twig */
 | |
| $twig->display('highscores.html.twig', [
 | |
| 	'highscores' => $highscores,
 | |
| 	'list' => $list,
 | |
| 	'skill' => $skill,
 | |
| 	'skillName' => ($skill == SKILL_FRAGS ? 'Frags' : ($skill == SKILL_BALANCE ? 'Balance' : getSkillName($skill))),
 | |
| 	'levelName' => ($skill != SKILL_FRAGS && $skill != SKILL_BALANCE ? 'Level' : ($skill == SKILL_BALANCE ? 'Balance' : 'Frags')),
 | |
| 	'vocation' => $vocation !== 'all' ? $vocation :  null,
 | |
| 	'vocationId' => $vocationId,
 | |
| 	'types' => $types,
 | |
| 	'linkPreviousPage' => $linkPreviousPage,
 | |
| 	'linkNextPage' => $linkNextPage,
 | |
| 	'totalResults' => $totalResults,
 | |
| 	'page' => $page,
 | |
| 	'baseLink' => $baseLink,
 | |
| 	'updatedAt' => $updatedAt,
 | |
| ]);
 | 
