summaryrefslogtreecommitdiffstats
path: root/includes/mapoftheday.php
blob: c3fc0e1956a1d2bc467c0f5e46e68dc64203601a (plain)
1
<?php

include_once('maps.php');
include_once('sqlEmbedded.php');
include_once('playerStats.php');
include_once('constants.php');

/**
 * Returns the Map Of The Day with the given type (index).  Generates new maps if necessary.
 */
function mapOfTheDay($type = MapType::Simple)
{
	//TODO del comments
	//echo "[Seeking maptype $type]";
	$map = getMapOfTheDayInternal($type);
	if($map == null)
	{
		//Map doesn't exist, so we generate the maps and try again
		generateNewMapsOfTheDay();
		$map = getMapOfTheDayInternal($type);
	}
	//else echo "[Found $type]";
	return $map;
}

/**
 * Returns the map of the day of the given type, or null if not found.
 * Do not call outside of mapoftheday.php
 */
function getMapOfTheDayInternal($type)
{
	//The ORDER BY and LIMIT probably shouldn't be necessary, since there should only be one active map of each
	//type at a time anyways..
	$sql = "
	SELECT maps.ID, maps.code
	FROM `mapOfTheDay`
	INNER JOIN `maps` ON mapOfTheDay.mapID = maps.ID
	WHERE `mapType` = $type
	AND mapOfTheDay.mapExpireTime > NOW()
	ORDER BY mapOfTheDay.mapDate DESC
	LIMIT 1
	";
	
	$result = mysql_query($sql);
	if (mysql_num_rows($result) == 0)
	{
		return null;
	}
	
	//A map was found, so return it
	$r['code'] = mysql_result($result, 0, 'code');
	$r['map'] = GenerateMapByCode($r['code']);
	$r['id'] = mysql_result($result, 0, 'ID');
	return $r;
}

/**
 * Generates all the new maps for the day.  Includes a critical section so maps aren't generated more
 * than once per day.
 */
function generateNewMapsOfTheDay()
{
	ignore_user_abort(true);
	set_time_limit(0);
	
	$lock = acquireMotdLock();
	try
	{
		//Double check that we still need to generate a new map for today.  Since that was done outside of the lock, it's possible
		//two threads could reach this point at the same time.
		$latestSpecialMap = getMapOfTheDayInternal(MapType::Special);
		$latestWeeklyMap = getMapOfTheDayInternal(MapType::Weekly);
		if($latestSpecialMap != null && $latestWeeklyMap != null)
		{
			releaseMotdLock($lock);
			return;
		}

		//The rest of the code in the try{} can be assumed to only be run once a day
	
		//Generate the maps
		$mapCode = array();
		if($latestSpecialMap == null)
		{
			$mapCode[MapType::Simple] = generateNewMapCode(MapType::Simple);
			$mapCode[MapType::Normal] = generateNewMapCode(MapType::Normal);
			$mapCode[MapType::Complex] = generateNewMapCode(MapType::Complex);
			$mapCode[MapType::Special] = generateNewMapCode(MapType::Special);
		}
		
		//The weekly maps might not need to be generated tonight.  Check if it does first
		if($latestWeeklyMap == null)
		{
			$mapCode[MapType::Weekly] = generateNewMapCode(MapType::Weekly);
		}
		
		//Add the actual maps to the DB
		addNewMapsToDB($mapCode);
		// foreach($mapCode as $type => $code)
		// {
			// if ($type == 4) !!
			// addNewMapToDB($code, $type, $lock);
		// }
		
		//Update the player-statistics
		if($latestSpecialMap == null)
		{
			//Add points for yesterday's maps if we just created the daily maps
			addStatsForYesterdaysMaps();
		}
		if($latestWeeklyMap == null)
		{
			//Add points for the weekly map, which is created at noon rather than midnight
			addStatsForMiddayMaps();
			
			//Note that there could potentially be an issue adding points twice if server goes from noon on Saturday
			//(or whenever we generate the new weekly map) to midnight the next morning without anyone visiting the site.
			//That's probably not going to be an issue on the production site, however...
		}
		
	} catch (Exception $exc) { /* Ignore... :| */ }

	//try/catch above is necessary to make sure an exception doesn't prevent us from releasing the lock!
	releaseMotdLock($lock);
}

/**
 * Generates a single map of the given type, and returns its "map code"
 */
function generateNewMapCode($type)
{
		// If you want to modify the maps created! This is the line
	//GenerateMap($rows, $cols, $rockchance, $numBlocks = -1, $cp = -1, $tp = -1)
	switch ($type) {
		case MapType::Simple:
			$map = GenerateMap(13, 7, 12, rand(7, 10), rand(0, 1), 0);
			break;

		case MapType::Normal:
			$map = GenerateMap(15, 9, 7, rand(11, 13), rand(1, 3) + rand(0, 1), 0);
			break;

		case MapType::Complex:
			$map = getRandomComplexMap();
			break;

		case MapType::Special:
			$map = getRandomSpecialMap();
			break;

		case MapType::Weekly:
			$map = getRandomWeeklyMap();
			break;

		default:
			$map = GenerateMap(rand(13, 18), rand(10, 14), rand(6, 9));
			break;
	}
	
	return GenerateMapCode($map);
}

function addNewMapsToDB($mapCode) {

	
	foreach($mapCode as $code) {
		$codeValuesAry[] = " ('$code')";
	}
	$codeValues = implode(",", $codeValuesAry);
	
	//Insert all the maps at once.
	$sql = "INSERT INTO `maps` (`code`)
			VALUES $codeValues";
	
	//Did we succeed?
	$result = mysql_query($sql);
	if (!$result)
	{
		releaseMotdLock($lock);
		die("Error on inserting maps, offending SQL: $sql");
	}
	
	//Get the ID of the first insert.
	$mapIDI = mysql_insert_id();
	foreach ($mapCode as $type => $code) {
		if($type == MapType::Weekly)
		{
			//Weekly map lasts MAP_EXPIRE_TIME_WEEKLY days.  We also want to offset by 12 hours
			$numHours = 24*MAP_EXPIRE_TIME_WEEKLY + 12;
			$expireTime = "ADDDATE(CURDATE(), INTERVAL $numHours HOUR)";
		}
		else
		{
			//All other maps are assumed to last one day
			$expireTime = 'ADDDATE(CURDATE(), INTERVAL 1 DAY)';
		}
		$mapOfTheDayAry[] = "('$mapIDI', '$type', CURDATE(), $expireTime)";
		$mapIDI++;
	}
	$mapOfTheDayValues = implode(",", $mapOfTheDayAry);
	
	$sql = "INSERT INTO `mapOfTheDay` (`mapID`, `mapType`, `mapDate`, `mapExpireTime`)
			VALUES $mapOfTheDayValues ";
	$result = mysql_query($sql);
	if (!$result)
	{
		releaseMotdLock($lock);
		die("Error on insert into mapOfTheDay SQL: $sql");
	}
}

/**
 * The file locked in order to create serialize map-creations, since our DB doesn't support transactions...
 */
define('FILE_MOTD_LOCK', './motdLockFile');

/**
 * Obtains the mutex used for creating the Map Of The Day, so that race-conditions cannot occur (like two threads
 * creating and inserting the maps into the database at the same time, which has happened
 */
function acquireMotdLock()
{
	$fileHandle = fopen(FILE_MOTD_LOCK, 'a+');
	flock($fileHandle, LOCK_EX);
	return $fileHandle;
}

/**
 * Releases the lock acquired from acquireMotdLock
 */
function releaseMotdLock($fileHandle)
{
	if($fileHandle)
		flock($fileHandle, LOCK_UN);
}

function getRandomComplexMap() {

	$random = weight(0, 0, 0, 0, 0, 0, 0, 1);

	switch ($random) {
		case 0:
			$map = GenerateMap(19, 9, rand(7, 9), rand(14, 16), rand(2, 5), rand(1, 2));
			break;
		case 1: 
			$reversePath[] = 'fo?????????????oS';
			$reversePath[] = 'fo?????????????oS';
			$reversePath[] = 'fo?????????????oS';
			$reversePath[] = 'fo?????????????oS';
			$reversePath[] = 'fo?????????????oS';
			$reversePath[] = 'fo?????????????oS';
			$reversePath[] = 'fo?????????????oS';
			$reversePath[] = 'fo?????????????oS';

			$reversePath = insertPoint($reversePath, 'abc');
			$reversePath = insertPoint($reversePath, 'tu');

			$myparams['checkpoints'] = 3;
			$myparams['teleports'] = 0;
			$myparams['rockchance'] = 7;
			$myparams['walls'] = 12;
			$myparams['name'] = 'Reverse Order';
			$map = GenerateShapedMap($reversePath, $myparams);
			break;
	}
	
	return $map;
}

function getRandomSpecialMap() {

	//This can be used to add additional weight to certain maps that we like.
	$random = weight(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

	$shape = array();
	$params = array();

	switch ($random) {

		//=====================================
		case 0:
			//Thirty
			$map = GenerateMap(
					18, 14, 20, //width, height, rocks
					weight(30), //Walls
					weight(1), //Checkpoints
					weight(1), //Teleports
					'Thirty'
			);
			break;
		//=====================================
		case 1:
			//Simple
			$map = GenerateMap(
					18, 9, 7, //width, height, rocks
					weight(15, 16, 17), //Walls
					weight(0), //Checkpoints
					weight(0), //Teleports
					'Finite'
			);
			break;
		//=====================================
		case 2:
			//ABC's
			$map = GenerateMap(
					19, 11, 12, //width, height, rocks
					weight(20, 21, 22, 22, 23), //Walls
					weight(3), //Checkpoints
					weight(0), //Teleports
					"ABC's "
			);
			break;
		//=====================================
		case 3:
			//Tele Madness
			$map = GenerateMap(
					17, 12, 10, //width, height, rocks
					weight(17, 18), //Walls
					weight(1), //Checkpoints
					weight(5), //Teleports
					'Teleport Madness'
			);
			break;
		//=====================================
		case 4:
			//Rocky Maze
			$map = GenerateMap(
					19, 15, 5, //width, height, rocks
					weight(16, 17, 18), //Walls
					weight(1, 2, 2, 2, 3, 3), //Checkpoints
					weight(0), //Teleports
					'Rocky Maze'
			);
			break;
		//=====================================
		case 5:
			//Side to Side
			$map = GenerateMap(
					26, 6, 12, //width, height, rocks
					weight(17, 18, 19), //Walls
					weight(2, 2, 2, 3, 3), //Checkpoints
					weight(3, 3, 3, 4), //Teleports
					'Side to Side'
			);
			break;

		//=====================================
		case 6:
			//Ultimate's Random map:
			//Create shape
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			$shape[] = "??????????????????";
			//Insert points
			$shape = insertPoint($shape, "sfabcr", $target = '?');
			$shape = insertPoint($shape, weight("tu", "d", "tu", "", ""), $target = '?');
			//Set params
			$params['rockchance'] = 10;
			$params['walls'] = weight(21, 20, 22, 20, 21);
			$params['name'] = 'Ultimate Random';
			//Put it all together.
			$map = GenerateShapedMap($shape, $params);

			break;
		//=====================================
		//=====================================
		case 7:
			//Dual map
			$dualmapa[] = "s???????????????????f";
			$dualmapa[] = "s???????????????????f";
			$dualmapa[] = "s???????????????????f";
			$dualmapa[] = "s???????????????????f";
			$dualmapa[] = "s???????????????????f";
			$dualmapa[] = "s???????????????????f";
			$dualmapa[] = "oqqqqqqqqqqqqqqqqqqqo";
			$dualmapb[] = "s???????????????????f";
			$dualmapb[] = "s???????????????????f";
			$dualmapb[] = "s???????????????????f";
			$dualmapb[] = "s???????????????????f";
			$dualmapb[] = "s???????????????????f";
			$dualmapb[] = "s???????????????????f";

			$dualmapa = insertPoint($dualmapa, 'abc');
			$dualmapb = insertPoint($dualmapb, 'abc');
			$dualmap = array_merge($dualmapa, $dualmapb);
			$dualmap = insertPoint($dualmap, 'tu');

			$myparams['checkpoints'] = 3;
			$myparams['teleports'] = 1;
			$myparams['rockchance'] = 9;
			$myparams['walls'] = weight(20, 20, 21, 21, 22, 23);
			$myparams['name'] = 'Seeing Double';
			$map = GenerateShapedMap($dualmap, $myparams);
			break;
		//=====================================
		//=====================================
		case 8:
			//Centralized
			$myshape[] = "ooooooooooooooooooo";
			$myshape[] = "o?????????????????o";
			$myshape[] = "o?????????????????o";
			$myshape[] = "o?????????????????o";
			$myshape[] = "o???????fos???????o";
			$myshape[] = "o?????????????????o";
			$myshape[] = "o?????????????????o";
			$myshape[] = "o?????????????????o";
			$myshape[] = "ooooooooooooooooooo";

			$myshape = insertPoint($myshape, "abc", $target = '?');
			$myshape = insertPoint($myshape, weight("tu", "d", "tud", ""), $target = '?');
			$myparams['rockchance'] = 7;
			$myparams['walls'] = weight(17, 18, 19, 18, 17);
			$myparams['name'] = 'Centralized';
			$map = GenerateShapedMap($myshape, $myparams);
			break;
		//=====================================
		//=====================================
		case 9:
			//Dualing paths
			$dualingPaths[] = 'so??????????????xf';
			$dualingPaths[] = 'so??????????????xf';
			$dualingPaths[] = 'so??????????????xf';
			$dualingPaths[] = 'so??????????????xf';
			$dualingPaths[] = 'Xo??????????????ox';
			$dualingPaths[] = 'fX??????????????oS';
			$dualingPaths[] = 'fX??????????????oS';
			$dualingPaths[] = 'fX??????????????oS';
			$dualingPaths[] = 'fX??????????????oS';

			$dualingPaths = insertPoint($dualingPaths, 'abc');
			$dualingPaths = insertPoint($dualingPaths, weight('xx', 'xxx', 'xxxx').weight('XX', 'XXX', 'XXXX'));

			$myparams['checkpoints'] = 3;
			$myparams['teleports'] = 0;
			$myparams['rockchance'] = 9;
			$myparams['walls'] = 13;
			$myparams['name'] = 'Dualing paths';

			$map = GenerateShapedMap($dualingPaths, $myparams);
			break;
		//=====================================
		//=====================================
		case 10:
			//Unlimited
			$unlimited[] = 'so?o?o?o?o?o?o?of';
			$unlimited[] = 's???????????????f';
			$unlimited[] = 'so?????????????of';
			$unlimited[] = 's???????????????f';
			$unlimited[] = 'so?????????????of';
			$unlimited[] = 's???????????????f';
			$unlimited[] = 'so?????????????of';
			$unlimited[] = 's???????????????f';
			$unlimited[] = 'so?o?o?o?o?o?o?of';

			$unlimited = insertPoint($unlimited, 'abc');
			$unlimited = insertPoint($unlimited, weight('tu', 'dtu'));

			$myparams['checkpoints'] = 3;
			$myparams['teleports'] = 1;
			$myparams['rockchance'] = 9;
			$myparams['walls'] = 999;
			$myparams['name'] = 'Unlimited';

			$map = GenerateShapedMap($unlimited, $myparams);
			break;
		//=====================================
		
		
	}
	return $map;
}

function getRandomWeeklyMap() {
	$ultraComplex[] = "sooooooooooooooooooooooor";
	$ultraComplex[] = "ro?????????????????????of";
	$ultraComplex[] = "so?????????????????????or";
	$ultraComplex[] = "ro?????????????????????of";
	$ultraComplex[] = "so?????????????????????or";
	$ultraComplex[] = "ro?????????????????????of";
	$ultraComplex[] = "so?????????????????????or";
	$ultraComplex[] = "ro?????????????????????of";
	$ultraComplex[] = "so?????????????????????or";
	$ultraComplex[] = "ro?????????????????????of";
	$ultraComplex[] = "so?????????????????????or";
	$ultraComplex[] = "ro?????????????????????of";
	$ultraComplex[] = "so?????????????????????or";
	$ultraComplex[] = "ro?????????????????????of";
	$ultraComplex[] = "sooooooooooooooooooooooor";

	$ultraComplex = insertPoint($ultraComplex, 'abcde');
	$ultraComplex = insertPoint($ultraComplex, weight('a', 'b', 'c', 'd', 'e'));
	$ultraComplex = insertPoint($ultraComplex, weight('a', 'b', 'c', 'd', 'e', 'u', 'n', 'j', 'h', 'n'));
	$ultraComplex = insertPoint($ultraComplex, weight('a', 'b', 'c', 'd', 'e', 'u', 'n', 'j', 'h', 'n'));
	$ultraComplex = insertPoint($ultraComplex, 'tumnghij');

	$myparams['checkpoints'] = 5;
	$myparams['teleports'] = 3;
	$myparams['rockchance'] = 12;
	$myparams['walls'] = 50;
	$myparams['name'] = 'Ultra Complex';
	$map = GenerateShapedMap($ultraComplex, $myparams);
	
	return $map;
}

?>