<?php
/**
 * SMF Arcade
 *
 * @package SMF Arcade
 * @version 2.57
 * @license https://web-develop.ca/index.php?page=arcade_license_BSD2 BSD 2
 */

if (!defined('SMF'))
	die('Hacking attempt...');

/*	This file handles Arcade and loads required files.

	void Arcade()
		- Loads correct file based on subaction

	void loadArcade([mode = normal])
		- Initializes Arcade
		- Called by Arcade() and Arcade Admin functions

	void arcadeLogin()
		- Shows a login prompt for guests
		- Redirects to arcade with specific action and/or subActions

*/

function Arcade()
{
	global $context, $smcFunc, $scripturl, $txt, $sourcedir, $modSettings, $boardurl, $user_info;

	// Do we have permission?
	isAllowedTo('arcade_view');

	// Load Arcade
	loadArcade('normal');

	// Fatal error if Arcade is disabled
	if (empty($modSettings['arcadeEnabled']))
		fatal_lang_error('arcade_disabled', false);

	// Information for actions (file, function, [permission])
	$subActions = array(
		// ArcadeArena.php
		'arena' => array('ArcadeArena.php', 'ArcadeMatchList'),
		'newMatch' => array('ArcadeArena.php', 'ArcadeNewMatch', 'arcade_create_match'),
		'newMatch2' => array('ArcadeArena.php', 'ArcadeNewMatch2', 'arcade_create_match'),
		'viewMatch' => array('ArcadeArena.php', 'ArcadeViewMatch'),
		// ArcadeList.php
		'list' => array('ArcadeList.php', 'ArcadeList'),
		'suggest' => array('ArcadeList.php', 'ArcadeXMLSuggest'),
		'search' => array('ArcadeList.php', 'ArcadeList'),
		'rate' => array('ArcadeList.php', 'ArcadeRate'),
		'favorite' => array('ArcadeList.php', 'ArcadeFavorite'),
		// ArcadeGame.php
		/* Game Popup in Iframe  */
		'popup' => array('ArcadePopup-smf2.php', 'ArcadePopup'),
		'play' => array('ArcadeGame.php', 'ArcadePlay', 'arcade_play'),
		'highscore' => array('ArcadeGame.php', 'ArcadeHighscore'),
		'highscorexml' => array('ArcadeGame.php', 'ArcadeHighscoreXml'),
		'save' => array('ArcadeGame.php', 'ArcadeSave_Guest'),
		// ArcadeStats.php
		'stats' => array('ArcadeStats.php', 'ArcadeStatistics'),
		'submit' => array('ArcadeGame.php', 'ArcadeSubmit'),
		// Arcade Online
		'online' => array('ArcadeOnline.php', 'ArcadeOnline'),
		// Advanced
		'download' => array('ArcadeDownload.php', 'ArcadeDownload'),
		'report' => array('ArcadeReport.php', 'ArcadeReport'),
		'shout' => array('Subs-ArcadeSkinMainB.php', 'ArcadeShout'),
		// IBP Submit
		'ibpverify' => array('Submit-ibp.php', 'ArcadeVerifyIBP'),
		'ibpsubmit2' => array('ArcadeGame.php', 'ArcadeSubmit'),
		'ibpsubmit3' => array('ArcadeGame.php', 'ArcadeSubmit'),
		// v2 Submit
		'v2Start' => array('Submit-v2game.php', 'ArcadeV2Start'),
		'v2Hash' => array('Submit-v2game.php', 'ArcadeV2Hash'),
		'v2Score' => array('Submit-v2game.php', 'ArcadeV2Score'),
		'v2Submit' => array('ArcadeGame.php', 'ArcadeSubmit'),
		// v3Arcade
		'vbSessionStart' => array('Submit-v3arcade.php', 'ArcadeVbStart'),
		'vbPermRequest' => array('Submit-v3arcade.php', 'ArcadeVbPermRequest'),
		'vbBurn' => array('ArcadeGame.php', 'ArcadeSubmit'),
		// HTML5
		'html5Game' => array('Submit-HTML5.php', 'ArcadeHTML5Game'),
		'html52Game' => array('Submit-HTML52.php', 'ArcadeHTML52Game'),
		'html53Game' => array('Submit-HTML52.php', 'ArcadeHTML52Game'),
	);

	if (empty($modSettings['arcadeArenaEnabled']))
		unset($subActions['arena'], $subActions['newMatch'], $subActions['newMatch2'], $subActions['viewMatch']);

	// Fix for broken games which do not send sa/do=submit
	if (isset($_POST['game']) && isset($_POST['score']) && !isset($_REQUEST['sa']))
		$_REQUEST['sa'] = 'submit';
	// Short urls like index.php?game=1 or index.php/game,1.html
	elseif (isset($_REQUEST['game']) && is_numeric($_REQUEST['game']) && !isset($_REQUEST['sa']))
		$_REQUEST['sa'] = 'play';
	elseif (isset($_REQUEST['match']) && is_numeric($_REQUEST['match']) && !isset($_REQUEST['sa']))
		$_REQUEST['sa'] = 'viewMatch';
	// Let Custom ("php games") do ajax/etc magic
	elseif (isset($_REQUEST['game']) && isset($_REQUEST['xml']) && !isset($_REQUEST['sa']))
		$_REQUEST['sa'] = 'custData';

	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'list';

	$context['curved'] = strpos($modSettings['smfVersion'], '2.1') !== false ? true : $context['curved'];
	$context['arcade_smf_version'] = version_compare((!empty($modSettings['smfVersion']) ? substr($modSettings['smfVersion'], 0, 3) : '2.0'), '2.1', '<') ? 'v2.0' : 'v2.1';
	$context['current_arcade_sa'] = !empty($_REQUEST['sa']) ? $_REQUEST['sa'] : 'list';
	$_SESSION['current_cat'] = !empty($_SESSION['current_cat']) ? $_SESSION['current_cat'] : 'all';
	$_SESSION['arcade_sortby'] = !empty($_SESSION['arcade_sortby']) ? $_SESSION['arcade_sortby'] : 'a2z';
	$sort = ($_SESSION['current_cat'] == 0 || $_SESSION['current_cat'] == 'all') && $_SESSION['arcade_sortby'] == 'a2z' ? '' : ';sortby=reset';
	$smfVersion = version_compare((!empty($modSettings['smfVersion']) ? substr($modSettings['smfVersion'], 0, 3) : '2.0'), '2.1', '<') ? 'v2.0' : 'v2.1';
	list($user_gametype, $javascript, $checkRar, $countGames, $archivetype, $archiveContent, $gametype, $gametypeContent) = array('', '', false, 0, array(), array(), array(), array());


	$context['arcade_tabs']['arcade'] = array(
		'text' => 'arcade',
		'image' => 'arcade.gif',
		'url' => $scripturl . '?action=arcade' . $sort,
		'active' => in_array($context['current_arcade_sa'], array('list', 'online', 'highscore', 'play')) ? true : null,
		'lang' => true
	);

	if (!empty($modSettings['arcadeArenaEnabled']))
		$context['arcade_tabs']['arcade_arena'] = array(
			'text' => 'arcade_arena',
			'image' => 'arcade_arena.gif',
			'url' => $scripturl . '?action=arcade;sa=arena;reload=' . mt_rand(0, 9999) . ';#arenamatch',
			'active' => in_array($context['current_arcade_sa'], array('arena', 'newMatch', 'newMatch2', 'viewMatch')) ? true : null,
			'lang' => true
		);

	$context['arcade_tabs']['arcade_stats'] = array(
		'text' => 'arcade_stats',
		'image' => 'arcade_stats.gif',
		'url' => $scripturl . '?action=arcade;sa=stats',
		'active' => in_array($context['current_arcade_sa'], array('stats')) ? true : null,
		'lang' => true
	);

	if (allowedTo('arcade_admin'))
		$context['arcade_tabs']['arcade_administrator'] = array(
			'text' => 'arcade_administrator',
			'image' => 'arcade_administrator.gif',
			'url' => $scripturl . '?action=admin;area=arcade',
			'lang' => true
		);

	if (!$user_info['is_guest'] && !empty($user_info['arcade_settings']))
	{
		$userArchive = !empty($user_info['arcade_settings']['archive_type']) ? $user_info['arcade_settings']['archive_type'] : -1;
		$userGametype = !empty($user_info['arcade_settings']['arcade_gametype']) ? $user_info['arcade_settings']['arcade_gametype'] : -1;
	}
	elseif (!$user_info['is_guest'])
	{
		loadArcadeSettings($user_info['id']);
		$userArchive = !empty($user_info['arcade_settings']['archive_type']) ? $user_info['arcade_settings']['archive_type'] : -1;
		$userGametype = !empty($user_info['arcade_settings']['arcade_gametype']) ? $user_info['arcade_settings']['arcade_gametype'] : -1;
	}
	else
		list($userArchive, $userGametype) = array(-1, -1);

	if (!empty($modSettings['arcade_gz_user']) && allowedTo('arcade_download_type') && allowedTo('arcade_download') && !empty($modSettings['arcadeEnableDownload']))
	{
		$x = 0;
		$typeArray = explode('|', $txt['arcade_compression']);
		$modSettings['arcade_gz'] = !empty($modSettings['arcade_gz']) ? $modSettings['arcade_gz'] : (class_exists('ZipArchive') ? 0 : 1);
		$modSettings['arcade_gz'] = $userArchive != -1 ? $userArchive : $modSettings['arcade_gz'];
		$selected = $smfVersion == 'v2.1' ? 'class="active"' : 'class="active firstlevel"';
		$paddingLeft = $smfVersion == 'v2.1' ? 'padding-left: 0.375em;' : '';
		$_SESSION['arcade_download_type'] = isset($_SESSION['arcade_download_type']) ? $_SESSION['arcade_download_type'] : $modSettings['arcade_gz'];
		$archivetype = isset($_REQUEST['archive']) ? $_REQUEST['archive'] : '';
		if (!empty($archivetype))
			ArcadeSelectType($typeArray);

		$currentUri = !empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
		$locate = stripos($currentUri, 'index.php?action=arcade');
		$currentLink = $boardurl . '/' . substr($currentUri, $locate);
		foreach(array_reverse($typeArray) as $typex)
			$currentLink = str_replace(';archive=' . $typex, '', $currentLink);
		$currentLink = str_replace('index.php?action=arcade', 'index.php?action=arcade;archive=', $currentLink);

		// check if rar package is available
		if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
		{
			if (!empty($modSettings['arcadeDownloadWinRarDir']) && is_dir($modSettings['arcadeDownloadWinRarDir']))
				@chdir($modSettings['arcadeDownloadWinRarDir']);
			if (is_dir("\Program Files (x86)\WinRAR"))
				@chdir("\Program Files (x86)\WinRAR");
			elseif (is_dir("\Program Files\WinRAR"))
				@chdir("\Program Files\WinRAR");

			$checkRar = (`where WinRAR.exe`);
		}
		else
			$checkRar = (`which rar`);

		foreach ($typeArray as $type)
		{
			if (!$checkRar && $type == 'rar')
				continue;

			if ($smfVersion == 'v2.1')
				$archiveContent[] = array(
					'link' => $scripturl . '?action=arcade;archive=' . $type,
					'text' => trim($type)
				);
			else
				$archiveContent[] = array(
					'link' => $scripturl . '?action=arcade;archive=' . $type,
					'text' => trim($type)
				);
			$x++;
		}

		$archivetype = array(
			'text' => 'arcade_user_archive_type_button',
			'image' => 'arcade_user_archive_type.gif',
			'url' => $scripturl . '?action=arcade;archive=tar.gz',
			'lang' => true,
			'is_last' => true,
    	);
	}

	$request = $smcFunc['db_query']('', '
		SELECT game.id_game, game.member_groups AS game_groups, game.id_cat, cat.member_groups AS cat_groups,
		IFNULL(cat.member_groups, {string:empty_string}) AS cat_groups
		FROM {db_prefix}arcade_games as game
		LEFT JOIN {db_prefix}arcade_categories AS cat ON (cat.id_cat = game.id_cat)
		WHERE id_game > 0',
		array(
			'empty_string' => '',
		)
	);

	while ($row = $smcFunc['db_fetch_assoc']($request))
	{
		$groups = explode(',', $row['game_groups']);
		$cat_groups = explode(',', $row['cat_groups']);
		list($cat_result, $result) = array(array(1), array());
		$result = array_intersect($groups, $user_info['groups']);
		if (!empty($cat_groups) && !empty($row['id_cat']))
			$cat_result = array_intersect($cat_groups, $user_info['groups']);

		if (!empty($result) && !empty($cat_result))
		{
			$countGames = 1;
			break;
		}
		if ($user_info['is_admin'])
		{
			$countGames = 1;
			break;
		}
	}
	$smcFunc['db_free_result']($request);

	if (allowedTo('arcade_gametype_select') && !empty($countGames))
	{
		$typeCheckArray = explode('|', $txt['arcade_select_gametype']);
		$langCheckArray = explode('|', $txt['arcade_select_gametype_english']);
		list($checkSubSystem, $typeArray, $langArray, $x, $y) = array(array(), array('all'), array($langCheckArray[0]), 0, 0);
		foreach ($typeCheckArray as $checkType)
		{
			$result = $smcFunc['db_query']('', '
				SELECT submit_system
				FROM {db_prefix}arcade_games
				WHERE submit_system = {string:subsystem}
				LIMIT 1',
				array(
				'subsystem' => $checkType)
			);

			while ($row = $smcFunc['db_fetch_assoc']($result))
			{
				$typeArray[] = $checkType;
				$langArray[] = $langCheckArray[$y];
			}
			$smcFunc['db_free_result']($result);
			$y++;
		}
		$selected = $smfVersion == 'v2.1' ? ' class="active"' : ' class="active firstlevel"';
		$paddingLeft = $smfVersion == 'v2.1' ? 'padding-left: 0.375em;' : '';
		$gamesavetype = isset($_REQUEST['gametype']) ? $_REQUEST['gametype'] : '';
		$_SESSION['arcade_gametype_select'] = isset($_SESSION['arcade_gametype_select']) ? $_SESSION['arcade_gametype_select'] : !empty($gamesavetype) ? $gamesavetype : 'all';
		$_SESSION['arcade_gametype_select'] = $userGametype != -1 ? $typeArray[$userGametype] : $_SESSION['arcade_gametype_select'];

		if (!empty($gamesavetype))
			ArcadeSelectGameType($typeArray);

		foreach ($typeArray as $type)
		{
			$null = empty($gamesavetype) && empty($_SESSION['arcade_gametype_select']) && $type == 'all' ? true : false;
			if ($smfVersion == 'v2.1')
				$gametypeContent[] = array(
					'link' => $scripturl . '?action=arcade;gametype=' . $typeArray[$x],
					'text' => trim($langArray[$x])
				);
			else
				$gametypeContent[] = array(
					'link' => $scripturl . '?action=arcade;gametype=' . $typeArray[$x],
					'text' => trim($type)
				);

			$x++;
		}

		$gametype = array(
			'text' => 'arcade_user_gametype_button',
			'image' => 'arcade_user_gametype.gif',
			'url' => $scripturl . '?action=arcade;gametype=all',
			'lang' => true,
			'is_last' => true,
    	);

	}

	// the custom select menu for SMF buttons ~ use class for SMF defaults or id for custom
	list($x, $y) = array(0, 0);
	$javascript .= '
	<script type="text/javascript">
		function propertyFromSmfStylesheet(selector, selector2, attribute) {
			var value;
			try {
				[].some.call(document.styleSheets, function (sheet) {
					return [].some.call(sheet.rules, function (rule) {
						if (rule.selectorText && selector2 == "" && rule.selectorText.search(selector) != -1) {
							return [].some.call(rule.style, function (style) {
								if (attribute === style) {
									value = rule.style.getPropertyValue(attribute);
									return true;
								}

								return false;
							});
						}
						else if (rule.selectorText && rule.selectorText.search(selector) != -1 && rule.selectorText.search(selector2) != -1) {
							return [].some.call(rule.style, function (style) {
								if (attribute === style) {
									value = rule.style.getPropertyValue(attribute);
									return true;
								}

								return false;
							});
						}
						return false;
					});
				});
			}
			catch {
			}
			return value;
		}
		function smfArcadeDropDown() {
			// var arcadeBgColor = propertyFromSmfStylesheet(".event", "", "color");
			var arcadeHover, arcadeNoHover;
			var arcadeBgColor = propertyFromSmfStylesheet("button", "", "background-color");
			arcadeBgColor = arcadeBgColor == "undefined" || arcadeBgColor == null ? "gray" : arcadeBgColor;
			arcadeHover = propertyFromSmfStylesheet("buttonlist", ":hover", "color");
			arcadeNoHover = propertyFromSmfStylesheet("buttonlist", "", "color");
			if (arcadeHover == null || arcadeHover == "undefined")
				arcadeHover = propertyFromSmfStylesheet("button", ":hover", "color");
			if (arcadeNoHover == null || arcadeNoHover == "undefined")
				arcadeNoHover = propertyFromSmfStylesheet("button", "", "color");
			arcadeHover = arcadeHover == "undefined" || arcadeHover == null || arcadeHover == arcadeNoHover ? "#CCC" : arcadeHover;
			arcadeNoHover = arcadeNoHover == "undefined" || arcadeNoHover == null ? "#000" : arcadeNoHover;
			var container = document.createElement("div");
			container.style = "display: none;position: absolute;border-radius: 0.6em;min-width: 7em;overflow: auto;box-shadow: 0.5em 0.5em 1.0em 0.5em rgba(0,0,0,0.2);z-index: 1;overflow: hidden;";
			container.style.backgroundColor = "inherit";
			container.id = "archivetype";
			container.onmouseleave = function() {document.getElementById("archivetype").style.display = "none";}
			var container2 = document.createElement("div");
			container2.style = "display: none;background-color: initial;position: absolute;border-radius: 0.6em;min-width: 7em;overflow: auto;box-shadow: 0.5em 0.5em 1.0em 0.5em rgba(0,0,0,0.2);z-index: 1;overflow: hidden;";
			container2.style.backgroundColor = "inherit";
			container2.id = "gametype";
			container2.onmouseleave = function() {document.getElementById("gametype").style.display = "none";}';

	foreach ($archiveContent as $archive)
	{
		$x++;
		$javascript .= '
			var arcadeLink' . $x . ' = document.createElement("a");
			arcadeLink' . $x . '.id = \'arcadeLinkId' . $x . '\';
			arcadeLink' . $x . '.style = "padding-left: 0.7em;margin-left: 0em;left: -0.3em;text-decoration: none;display: block;border-radius: 0.3em;position: relative;width: 100%;";
			arcadeLink' . $x . '.style.color = arcadeNoHover;
			arcadeLink' . $x . '.onmouseenter = function() {document.getElementById("arcadeLinkId' . $x . '").style.color = arcadeHover;};
			arcadeLink' . $x . '.onmouseleave = function() {document.getElementById("arcadeLinkId' . $x . '").style.color = arcadeNoHover;};
			arcadeLink' . $x . '.href = \'' . $archive['link'] . '\';
			arcadeLink' . $x . '.text = \'' . $archive['text'] . '\';
			arcadeLink' . $x . '.setAttribute("target", "_self");
			container.append(arcadeLink' . $x . ');';
	}

	foreach ($gametypeContent as $gametypes)
	{
		$y++;
		$javascript .= '
			var arcadeLinkz' . $y . ' = document.createElement("a");
			arcadeLinkz' . $y . '.id = \'arcadeLinkzId' . $y . '\';
			arcadeLinkz' . $y . '.style = "padding-left: 0.7em;margin-left: 0em;left: -0.3em;text-decoration: none;display: block;border-radius: 0.3em;position: relative;width: 100%;";
			arcadeLinkz' . $y . '.style.color = arcadeNoHover;
			arcadeLinkz' . $y . '.onmouseenter = function() {document.getElementById("arcadeLinkzId' . $y . '").style.color = arcadeHover;};
			arcadeLinkz' . $y . '.onmouseleave = function() {document.getElementById("arcadeLinkzId' . $y . '").style.color = arcadeNoHover;};
			arcadeLinkz' . $y . '.href = \'' . $gametypes['link'] . '\';
			arcadeLinkz' . $y . '.text = \'' . $gametypes['text'] . '\';
			arcadeLinkz' . $y . '.setAttribute("target", "_self");
			container2.append(arcadeLinkz' . $y . ');';
	}

	$javascript .= '
			var archive, archivesClass, archiveHref, countHref;
			var archiveHrefs = [];
			archivesClass = document.getElementsByClassName("button_strip_archivetype");
			archive = archivesClass != null ? archivesClass[0] : document.getElementById("archivetype");
			if (archive == null)
			{
				archiveHrefs = document.getElementsByTagName("A");
				for(countHref=0;countHref<archiveHrefs.length;countHref++)
				{
					if (archiveHrefs[countHref].href.includes("action=arcade;archive=tar.gz"))
					{
						archive = archiveHrefs[countHref];
						break;
					}
				}
			}
			if (archive != null)
			{
				archive.style.position = "relative";
				archive.href = "javascript:void(0)";
				archive.append(container);
				archive.onclick = function() {
					var showMe1 = document.getElementById("archivetype");
					if (showMe1.style.display == "none")
						showMe1.style.display = "block";
					else
						showMe1.style.display = "none";
				}
				archive.onmouseleave = function() {
					document.getElementById("archivetype").style.display = "none";
				}
			}
			var gametype, gametypeClass, gametypeHref, countHref;
			var gametypeHrefs = [];
			gametypeClass = document.getElementsByClassName("button_strip_gametype");
			gametype = gametypeClass != null ? gametypeClass[0] : document.getElementById("gametype");
			if (gametype == null)
			{
				gametypeHrefs = document.getElementsByTagName("A");
				for (countHref = 0;countHref<gametypeHrefs.length;countHref++)
				{
					if (gametypeHrefs[countHref].href.includes("index.php?action=arcade;gametype=all"))
					{
						gametype = gametypeHrefs[countHref];
						break;
					}
				}
			}
			if (gametype != null)
			{
				gametype.style.position = "relative";
				gametype.href = "javascript:void(0)";
				gametype.append(container2);
				gametype.onclick = function() {
					var showMe2 = document.getElementById("gametype");
					if (showMe2.style.display == "none")
						showMe2.style.display = "block";
					else
						showMe2.style.display = "none";
				}
				gametype.onmouseleave = function() {
					document.getElementById("gametype").style.display = "none";
				}
			}
		}
		if (window.addEventListener)
			window.addEventListener("load", smfArcadeDropDown, false);
		else if (window.attachEvent)
			window.attachEvent("onload", smfArcadeDropDown);
		else
			window.onload = smfArcadeDropDown;
	</script>';

	if (!empty($modSettings['arcade_gz_user']) && allowedTo('arcade_download_type') && allowedTo('arcade_download') && !empty($modSettings['arcadeEnableDownload']))
		$context['arcade_tabs']['archivetype'] =  $archivetype;

	if (allowedTo('arcade_gametype_select') && !empty($countGames))
		$context['arcade_tabs']['gametype'] =  $gametype;

	if (!in_array($_REQUEST['sa'], array('highscore', 'comment')) && isset($_SESSION['arcade']['highscore']))
		unset($_SESSION['arcade']['highscore']);

	// Check permission if needed
	if (isset($subActions[$_REQUEST['sa']][2]))
		isAllowedTo($subActions[$_REQUEST['sa']][2]);

	$context['arcade_javascript'] = $javascript;
	require_once($sourcedir . '/' . $subActions[$_REQUEST['sa']][0]);
	!isset($_SESSION['current_cat']) ? $_SESSION['current_cat'] = 'all' : '';
    isset($_REQUEST['category']) ? $_SESSION['current_cat'] = $_REQUEST['category'] : $_REQUEST['category'] = $_SESSION['current_cat'];
	$_REQUEST['category'] = !empty($_REQUEST['current_cat']) ? ArcadeSpecialChars($_REQUEST['current_cat'], 'cat'): $_SESSION['current_cat'];
	$_SESSION['arcade_gametype_select_title'] = $userGametype != -1 && !empty($typeArray) ? strtoupper($typeArray[$userGametype]) . '&nbsp;' . $txt['arcade_game_list'] : $txt['arcade_game_list'];
	arcade_log_online();
	$subActions[$_REQUEST['sa']][1]();
}

function template_main()
{
	/*
	** This patch function stops the template error for some games
	** Just leave it empty
	*/
}


function loadArcade($mode = 'normal', $index = '')
{
	global $db_prefix, $scripturl, $txt, $modSettings, $context, $settings, $sourcedir, $user_info, $smcFunc, $boarddir, $arcade_version, $arcade_lang_version;

	if(!function_exists('loadClassFile'))
		require_once($sourcedir . '/Subs-ArcadeClass.php');

    /* Are we using the curve or curve type theme?  */
    file_exists($settings['actual_theme_dir'] . '/images/theme/main_block.png') ? $context['curved'] = true : $context['curved'] = false;


	if (!empty($arcade_version))
		return;

	$arcade_version = $modSettings['arcadeVersion'];
	$_SESSION['arcade_sortby'] = !empty($_SESSION['arcade_sortby']) ? $_SESSION['arcade_sortby'] : '';
	$skinAlt = !empty($modSettings['arcadeSkinAlt']) ? explode('|', $modSettings['arcadeSkinAlt']) : array();
	$context['arcadeSkinAlt'] = !empty($skinAlt) && in_array($settings['theme_id'], $skinAlt) ? true : false;
	$arcade_lang_version = '2.5';
	$context['arcade'] = array();
	$context['arcade_smf_version'] = version_compare((!empty($modSettings['smfVersion']) ? substr($modSettings['smfVersion'], 0, 3) : '2.0'), '2.1', '<') ? 'v2.0' : 'v2.1';
	$user_info['arcade_settings'] = loadMyArcadeSettings($user_info['id']);
	$context['arcade_new_no_cats'] = ArcadeNewGamesNoCat();
	$arcadeSkin = $user_info['arcade_settings']['skin'];
	require_once($sourcedir . '/Subs-ArcadePlus.php');
	require_once($sourcedir . '/Subs-Arcade.php');

	if (($context['arcade']['stats'] = cache_get_data('arcade-stats', 180)) == null)
	{
		$context['arcade']['stats'] = array();
		// How many games?
		$result = $smcFunc['db_query']('', '
			SELECT COUNT(*) AS games
			FROM {db_prefix}arcade_games
			WHERE enabled = 1',
			array()
		);
		$context['arcade']['stats'] += $smcFunc['db_fetch_assoc']($result);
		$smcFunc['db_free_result']($result);

		if (!empty($modSettings['arcadeShowInfoCenter']))
		{
			require_once($sourcedir . '/ArcadeStats.php');
			$context['arcade']['stats']['best_player'] = ArcadeStats_BestPlayers(1);
			$context['arcade']['stats']['longest_champion'] = ArcadeStats_LongestChampions(1, null, 'current');
			$context['arcade']['stats']['most_played'] = ArcadeStats_MostPlayed(1);
		}

		cache_put_data('arcade-stats', $context['arcade']['stats'], 180);
	}

	switch ($arcadeSkin)
	{
		case 2:
			if ($context['arcadeSkinAlt'])
				require_once($sourcedir . '/Subs-ArcadeSkinAltB.php');
			else
				require_once($sourcedir . '/Subs-ArcadeSkinB.php');

			require_once($sourcedir . '/ArcadeStats.php');
			require_once($sourcedir . '/Subs-ArcadeSkinMainB.php');
			$context['html_headers'] .= '<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/arcade-skin-b.js?rc4"></script>';
			if ($mode == 'normal' || $mode == 'arena')
			{
				$context['arcade_defiant']['per_line'] = 4;
				$context['arcade_defiant']['cat_width'] = 20;
				$context['arcade_defiant']['cat_height'] = 20;
				$context['page_title'] = $txt['arcade_game_list'];
				$width = !empty($modSettings['skin_avatar_size_width']) && (int)$modSettings['skin_avatar_size_width'] > 0 ? (int)$modSettings['skin_avatar_size_width'] : 50;
				$height = !empty($modSettings['skin_avatar_size_height']) && (int)$modSettings['skin_avatar_size_height'] > 0 ? (int)$modSettings['skin_avatar_size_height'] : 50;
				$context['arcade_user_avatar'] = (!empty($context['user']['avatar']['href'])) ? ArcadeSizer($context['user']['avatar']['href'], $width, $height) : array($width, $height);
				loadTemplate('ArcadeSkinB');
			}
			$context['nameCharLength'] = !empty($modSettings['arcadeGamesNameLengthB']) ? $modSettings['arcadeGamesNameLengthB'] : 100;
			break;
		case 1:
			require_once($sourcedir . '/Subs-ArcadeSkinA.php');
			if ($mode == 'normal' || $mode == 'arena')
				loadTemplate('ArcadeSkinA');
			$context['nameCharLength'] = !empty($modSettings['arcadeGamesNameLengthA']) ? $modSettings['arcadeGamesNameLengthA'] : 100;
			break;
		default:
			require_once($sourcedir . '/Subs-ArcadeSkinA.php');
			if ($mode == 'normal' || $mode == 'arena')
				loadTemplate('Arcade');
			$context['nameCharLength'] = !empty($modSettings['arcadeGamesNameLength']) ? $modSettings['arcadeGamesNameLength'] : 100;
	}

	// Load language
	loadLanguage('Arcade');
	loadLanguage('ArcadeSkinA');

	// Permission query
	arcadePermissionQuery();

	// Normal mode
	if ($mode == 'normal' || $mode == 'arena')
	{
		if (empty($modSettings['arcadeEnabled']))
			return false;

		$context['games_per_page'] = !empty($user_info['arcade_settings']['games_per_page']) ? $user_info['arcade_settings']['games_per_page'] : $modSettings['gamesPerPage'];
		$context['scores_per_page'] = !empty($user_info['arcade_settings']['scores_per_page']) ? $user_info['arcade_settings']['scores_per_page'] : $modSettings['scoresPerPage'];

		// Arcade javascript & css
		$context['html_headers'] .= '
		<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/arcade.js?v26"></script>
		<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/arcade-html5-save.js?v26"></script>
		<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/arcade-skin-a.js?v26"></script>
		<link href="' . $settings['default_theme_url'] . '/css/arcade-skin-b.css?v26" rel="stylesheet" type="text/css" />
		<script type="text/javascript">var myArcadeWindow;</script>';

		// Add Arcade to link tree
		$context['linktree'][] = array(
			'url' => $scripturl . '?action=arcade',
			'name' => $txt['arcade'],
		);

		// What I can do?
		$context['arcade']['can_play'] = allowedTo('arcade_play');
		$context['arcade']['can_favorite'] = !empty($modSettings['arcadeEnableFavorites']) && !$user_info['is_guest'] ? true : false;
		$context['arcade']['can_rate'] = !empty($modSettings['arcadeEnableRatings']) && !$user_info['is_guest'] ? true : false;
		$context['arcade']['can_submit'] = allowedTo('arcade_submit');
		$context['arcade']['can_comment_own'] = allowedTo('arcade_comment_own');
		$context['arcade']['can_comment_any'] = allowedTo('arcade_comment_any');
		$context['arcade']['can_admin_arcade'] = allowedTo('arcade_admin');
		$context['arcade']['can_create_match'] = allowedTo('arcade_create_match');
		$context['arcade']['can_join_match'] = allowedTo('arcade_join_match');

		// Or can I? (do I have enought posts etc.)
		PostPermissionCheck();

		// Finally load Arcade Settings
		loadArcadeSettings();

		if (!isset($_REQUEST['xml']))
			$context['template_layers'][] = 'Arcade';
		else
			$context['template_layers'] = array();
	}
	elseif ($mode == 'profile')
		loadTemplate('ArcadeProfile', array('arcade'));
	// Admin mode
	elseif ($mode == 'admin')
	{
		loadTemplate('ArcadeAdmin');
		loadLanguage('ArcadeAdmin');
		isAllowedTo('arcade_admin');

		$context['html_headers'] .= '
		<script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/arcade.js?rc4"></script>
		<script type="text/javascript">var myArcadeWindow;</script>';

		// Update games database?
		if (file_exists($boarddir . '/Games.xml'))
		{
			loadClassFile('Class-Package.php');

			$games = new xmlArray(file_get_contents($boarddir . '/Games.xml'));
			$database = $games->path('smf/database');
			$database = $database->to_array();
			$xmlGames = $games->set('smf/game');

			if (!empty($modSettings['arcadeGameDatabaseVersion']) && $modSettings['arcadeGameDatabaseVersion'] > $database['version'])
				fatal_lang_error('arcade_db_mismatch');

			$games = array();

			foreach ($xmlGames as $game)
				$games[] = array(
					$game->fetch('id'),
					$game->fetch('name'),
					$game->fetch('description'),
					$game->fetch('url/info'),
					$game->fetch('url/download'),
				);

			$smcFunc['db_insert']('replace',
				'{db_prefix}arcade_game_info',
				array(
					  'internal_name' => 'string',
					  'game_name' => 'string',
					  'description' => 'string',
					  'info_url' => 'string',
					  'download_url' => 'string',
				),
				$games,
				array('internal_name')
			);

			updateSettings(array(
				'arcadeGameDatabaseVersion' => $database['version'],
				'arcadeGameDatabaseUpdate' => $database['update'],
			));

			@unlink($boarddir . '/Games.xml');
		}

		$context['template_layers'][] = 'ArcadeAdmin';
		$context['page_title'] = $txt['arcade_admin_title'];
	}
}

function arcadeLogin()
{
	global $scripturl, $txt, $user_info, $context, $modSettings;

	$sub_actions = array(
		'arena',
		'newMatch',
		'newMatch2',
		'viewMatch',
		'highscore',
		'play',
	);

	$_REQUEST['sa'] = (!empty($_REQUEST['sa'])) ? trim($_REQUEST['sa']) : '';
	$sa = (!empty($_REQUEST['sa'])) && in_array($_REQUEST['sa'], $sub_actions) ? $_REQUEST['sa'] : '';
	$game = isset($_REQUEST['game']) ? 'game=' . abs((int)$_REQUEST['game']) . ';' : '';
	$match = isset($_REQUEST['match']) ? 'match=' . abs((int)$_REQUEST['match']) . ';' : '';
	$subaction = 'sa=' . $sa . ';' . $match . $game;
	$anchor = in_array($sa, array('play', 'highscore')) && $sa == 'play' ? ';#playgame' : in_array($sa, array('play', 'highscore')) && $sa == 'highscore' ? ';#commentform3' : '';
	$_SESSION['old_url'] = $scripturl . '?action=arcade;' . $subaction;
	$context['arcade_sub'] = (isset($_REQUEST['hs'])) ? 'score' : 'play';
	$context['arcade_smf_version'] = version_compare((!empty($modSettings['smfVersion']) ? substr($modSettings['smfVersion'], 0, 3) : '2.0'), '2.1', '<') ? 'v2.0' : 'v2.1';

	if (empty($match) && empty($game) && empty($sa))
		redirectexit();

	if (!$user_info['is_guest'])
		redirectexit('action=arcade;' . $subaction . $anchor);

	// Create a login token for SMF 2.1.x
	if ($context['arcade_smf_version'] == 'v2.1')
		createToken('login');

	$context['page_title'] = $txt['arcade_login_title'];
	$context['sub_template'] = 'arcade_login';
	$context['linktree'][] = array(
		'url' => $scripturl . '?action=ingressarcade;' . $subaction,
		'name' => $txt['arcade_login_top'],
	);
	loadTemplate('Arcade');
}

function arcade_log_online()
{
	global $smcFunc, $user_info, $context;
	$time = time();
	$checkIp = !empty($user_info['ip']) ? trim($user_info['ip']) : !empty($user_info['ip2']) ? trim($user_info['ip2']) : arcade_get_client_ip();
	list($guests, $users, $action, $userIp) = array(0, 0, 0, array());
	$game = isset($_REQUEST['game']) ? (int)$_REQUEST['game'] : 0;
	$sa = !empty($_REQUEST['sa']) ? trim($_REQUEST['sa']) : 'index';

	switch ($sa)
	{
		case 'play':
			$action = 1;
			break;
		case 'highscore':
			$action = 2;
			break;
		case 'arena':
			$action = 3;
			break;
		case 'online':
			$action = 4;
			break;
		case 'viewMatch':
			$action = 5;
			break;
		case 'newMatch':
			$action = 6;
			break;
		case 'newMatch2':
			$action = 6;
			break;
		case 'stats':
			$action = 7;
			break;
		default:
			$action = 0;
	}

	// count guests online for user comparison
	$request = $smcFunc['db_query']('', '
		SELECT online_ip, online_time
		FROM {db_prefix}arcade_guest_data
		WHERE online_ip = {string:ip} AND {int:now} - cast(online_time as signed) < 600',
		array(
			'ip' => (string)$checkIp,
			'now' => $time
		)
	);
	while ($row = $smcFunc['db_fetch_assoc']($request))
		$userIp[] = $row['online_ip'];
	$smcFunc['db_free_result']($request);

	// remove user & guest values that refresh the page or are gone over 10 minutes
	$request = $smcFunc['db_query']('', '
		DELETE FROM {db_prefix}arcade_member_data
		WHERE id_member = {int:member} OR {int:now} - cast(online_time as signed) >= 600',
		array(
			'member' => $user_info['id'],
			'now' => $time
		)
	);

	if (!$user_info['is_guest'])
		$request = $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}arcade_guest_data
			WHERE online_ip = {string:ip} OR {int:now} - cast(online_time as signed) >= 600',
			array(
				'ip' => !in_array($checkIp, $userIp) ? $checkIp : '256.0.0.0',
				'now' => $time
			)
		);

	// insert user or guest into the online log
	if ($user_info['is_guest'] && !empty($checkIp))
	{
		$request = $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}arcade_guest_data
			WHERE online_ip = {string:ip} OR {int:now} - cast(online_time as signed) >= 600',
			array(
				'ip' => $checkIp,
				'now' => $time
			)
		);

		list($time, $show, $ip) = array(time(), '0', $checkIp);

		$smcFunc['db_insert']('replace',
			'{db_prefix}arcade_guest_data',
			array(
				'online_ip' => 'string',
				'online_time' => 'int',
				'show_online' => 'int',
				'current_action' => 'int',
				'current_game' => 'int',
				'temp_name' => 'string',
			),
			array(
				$ip,
				$time,
				$show,
				$action,
				$game,
				!empty($_SESSION['playerName']) ? $_SESSION['playerName'] : '',
			),
			array()
		);
	}
	elseif (!$user_info['is_guest'])
	{
		list($userid, $time, $show, $name, $color) = array($user_info['id'], time(), '0', $user_info['name'], '');

		$request = $smcFunc['db_query']('', '
			SELECT
				mem.id_member, mem.real_name, mem.member_name, mem.show_online,
				mg.online_color, mg.id_group, mg.group_name
			FROM {db_prefix}members AS mem
				LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = 0 THEN mem.id_post_group ELSE mem.id_group END)
			WHERE mem.id_member = {int:member}',
			array(
				'member' => $user_info['id'],
			)
		);

		while ($row = $smcFunc['db_fetch_assoc']($request))
		{
			$color = !empty($row['online_color']) ? $row['online_color'] : '';
			$show = !empty($row['show_online']) ? 1 : 0;
		}
		$smcFunc['db_free_result']($request);

		$smcFunc['db_query']('', '
			DELETE FROM {db_prefix}arcade_member_data
			WHERE id_member = {int:memberid} OR online_ip = {string:ip}',
			array(
				'memberid' => $user_info['id'],
				'ip' => $checkIp
			)
		);

		$smcFunc['db_insert']('insert',
			'{db_prefix}arcade_member_data',
			array(
				'id_member' => 'int',
				'online_ip' => 'string',
				'online_time' => 'int',
				'show_online' => 'int',
				'online_name' => 'string',
				'online_color' => 'string',
				'current_action' => 'int',
				'current_game' => 'int',
			),
			array(
				$userid,
				$checkIp,
				$time,
				$show,
				$name,
				$color,
				$action,
				$game,
			),
			array('id_member')
		);
	}
}

function loadMyArcadeSettings($memID = 0)
{
	global $smcFunc, $user_info, $modSettings;

	$modSettings['arcadeSkin'] = !empty($modSettings['arcadeSkin']) ? (int)$modSettings['arcadeSkin'] : 0;
	$modSettings['arcadeList'] = !empty($modSettings['arcadeList']) ? (int)$modSettings['arcadeList'] : 0;
	if ($memID == 0 || $user_info['is_guest'])
		return array('skin' => !empty($_SESSION['isPortalMobile']) ? 1 : $modSettings['arcadeSkin'], 'list' => !empty($_SESSION['isPortalMobile']) ? 2 : $modSettings['arcadeList']);

	// Default
	$arcadeSettings = array();

	$request = $smcFunc['db_query']('', '
			SELECT id_member, arena_invite, arena_match_end, arena_new_round, champion_email, champion_pm,
			games_per_page, archive_type, arcade_gametype, new_champion_any, new_champion_own, scores_per_page, skin, list
			FROM {db_prefix}arcade_members
			WHERE id_member = {int:member}
			LIMIT 1',
			array(
				'member' => $memID,
			)
		);

	while ($row = $smcFunc['db_fetch_assoc']($request))
	{
		$arcadeSettings = array(
			'id_member' => $row['id_member'],
			'arena_invite' => !empty($row['arena_invite']) ? $row['arena_invite'] : 0,
			'arena_match_end' => !empty($row['arena_match_end']) ? $row['arena_match_end'] : 0,
			'arena_new_round' => !empty($row['arena_new_round']) ? $row['arena_new_round'] : 0,
			'champion_email' => !empty($row['champion_email']) ? $row['champion_email'] : 0,
			'champion_pm' => !empty($row['champion_pm']) ? $row['champion_pm'] : 0,
			'games_per_page' => !empty($row['games_per_page']) ? $row['games_per_page'] : (!empty($modSettings['gamesPerPage']) ? $modSettings['gamesPerPage'] : 28),
			'archive_type' => isset($row['archive_type']) && !empty($modSettings['arcade_gz_user']) ? $row['archive_type'] : (!empty($modSettings['arcade_gz']) ? $modSettings['arcade_gz'] : 1),
			'arcade_gametype' => !empty($row['arcade_gametype']) ? $row['arcade_gametype'] : 0,
			'new_champion_any' => !empty($row['new_champion_any']) ? $row['new_champion_any'] : 0,
			'new_champion_own' => !empty($row['new_champion_own']) ? $row['new_champion_own'] : 0,
			'scores_per_page' => !empty($row['scores_per_page']) ? $row['scores_per_page'] : (!empty($modSettings['scoresPerPage']) ? $modSettings['scoresPerPage'] : 50),
			'skin' => !empty($row['skin']) && allowedTo('arcade_skin') ? $row['skin'] - 1 : $modSettings['arcadeSkin'],
			'list' => !empty($row['list']) && allowedTo('arcade_list') ? $row['list'] - 1 : $modSettings['arcadeList'],
		);
	}
	$smcFunc['db_free_result']($request);

	if (empty($arcadeSettings))
		return array(
			'id_member' => $memID,
			'arena_invite' => 0,
			'arena_match_end' => 0,
			'arena_new_round' => 0,
			'champion_email' => 0,
			'champion_pm' => 0,
			'games_per_page' => !empty($modSettings['gamesPerPage']) ? $modSettings['gamesPerPage'] : 28,
			'archive_type' => !empty($modSettings['arcade_gz']) ? $modSettings['arcade_gz'] : 2,
			'new_champion_any' => 0,
			'new_champion_own' => 0,
			'scores_per_page' => !empty($modSettings['scoresPerPage']) ? $modSettings['scoresPerPage'] : 50,
			'skin' => !empty($_SESSION['isPortalMobile']) ? 1 : $modSettings['arcadeSkin'],
			'list' => !empty($_SESSION['isPortalMobile']) ? 2 : $modSettings['arcadeList'],
		);

	$arcadeSettings['skin'] = !empty($_SESSION['isPortalMobile']) ? 1 : $arcadeSettings['skin'];
	$arcadeSettings['list'] = !empty($_SESSION['isPortalMobile']) ? 2 : $arcadeSettings['list'];
	return $arcadeSettings;
}

function ArcadeNewGamesNoCat($categories = array())
{
	global $smcFunc;

	$categories = is_array($categories) ? $categories : array($categories);
	$count = 0;
	$request = $smcFunc['db_query']('', '
		SELECT game.id_game, game.game_name, game.id_cat, game.enabled
		FROM {db_prefix}arcade_games AS game
		WHERE id_game > 0
		ORDER BY game.id_game DESC',
		array(
			'empty' => ''
		)
	);

	while ($row = $smcFunc['db_fetch_assoc']($request))
	{
		if (in_array($row['id_cat'], $categories) && !empty($row['enabled']))
			$count++;
		elseif (empty($row['id_cat']) && !empty($row['enabled']))
			$count++;
	}
	$smcFunc['db_free_result']($request);

	return $count;
}

?>