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

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

define('MAP_EXPIRE_TIME_NORMAL', 1); //Days that non-weekly maps should last.  Changing this won't
                                     //really work without changes to generateNewMapsOfTheDay()..
define('MAP_EXPIRE_TIME_WEEKLY', 2); //Days that a weekly map should last

/**
 * Returns the Map Of The Day with the given type (index).  Generates new maps if necessary.
 */
function mapOfTheDay($type = 1)
{
	$map = getMapOfTheDayInternal($type);
	if($map == null)
	{
		//Map doesn't exist, so we generate the maps and try again
		generateNewMapsOfTheDay();
		$map = getMapOfTheDayInternal($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)
{
	if ($type <= 4)
		$expire = MAP_EXPIRE_TIME_NORMAL;
	else if ($type <= 8)
		$expire = MAP_EXPIRE_TIME_WEEKLY;

	$sql = "
	SELECT maps.ID, maps.code
	FROM `mapOfTheDay`, `maps`
	WHERE `mapType` = $type
	AND DATEDIFF(CURDATE(), mapOfTheDay.mapDate) < $expire
	AND mapID = maps.ID
	";
	
	$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);
	$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(4);
		$latestWeeklyMap = getMapOfTheDayInternal(5);
		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[1] = generateNewMapCode(1);
			$mapCode[2] = generateNewMapCode(2);
			$mapCode[3] = generateNewMapCode(3);
			$mapCode[4] = generateNewMapCode(4);
		}
		
		//The weekly maps might not need to be generated tonight.  Check if it does first
		if($latestWeeklyMap == null)
		{
			$mapCode[5] = generateNewMapCode(5);
		}
		
		//Add the actual maps to the DB
		foreach($mapCode as $type => $code)
		{
			addNewMapToDB($code, $type, $lock);
		}
		
		//Update the player-statistics
		//TODO: Since we could now be calling this more than once a day, we probably need to update this... sigh.
		addStatsForYesterdaysMaps();
		
	} 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 1:  //Easy
			$map = GenerateMap(13, 7, 12, rand(7, 10), rand(0, 1), 0);
			break;

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

		case 3:  //Hard
			$map = getRandomComplexMap();
			break;

		case 4:  //Full random map
			$map = getRandomSpecialMap();
			break;

		case 5:
			$map = getRandomWeeklyMap();
			break;

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

/**
 * Adds the given map to the database as today's map of the day
 */
function addNewMapToDB($code, $type, $lock)
{
	$sql = "INSERT INTO `maps` (`code`)
			VALUES ('$code')";

	$result = mysql_query($sql);
	if (!$result)
	{
		releaseMotdLock($lock);
		die("Error on inserting map");
	}
	
	$mapID = mysql_insert_id();

	$sql = "INSERT INTO `mapOfTheDay` (`mapID`, `mapType`, `mapDate`)
			VALUES ('$mapID', '$type', CURDATE()) ";
	$result = mysql_query($sql);
	if (!$result)
	{
		releaseMotdLock($lock);
		die("Error on insert into mapOfTheDay");
	}
}


/**
 * 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);
}

//Select from yesterday
function getYesterdaysMap() {
	$sql = "
	select `ID`, `code` from `maps`
	WHERE ( 
		DAY(dateCreated) = DAY(NOW()) - 1 
		AND 
		MONTH(dateCreated) = MONTH(NOW()) 
		AND
		YEAR(dateCreated) = YEAR(NOW())
	)
	";
	$result = mysql_query($sql);
	//No map for today?
	if (mysql_num_rows($result) == 0) {
		return -1;
	}
	$r['code'] = mysql_result($result, 0, 'code');
	$r['id'] = mysql_result($result, 0, 'ID');
	return $r;
}

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: //Thursday
			//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: //Friday
			//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:
			$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[] = '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() {

// TEST MAP...
	$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;
}

?>