<?php
//anti hack
defined('INSCRIPT') OR die('must be included');
//overview thumbnail caching class. Really fucking crucial to the speed of the site and the strain on the server
class Overview_Cache
{
	function Overview_Cache()
	{
		global $sf, $allowed_picture_exts;
		//get a few arrayed values to be local class values so I can code faster plus it's a little more compact and organized
		$this->folder = $sf['ovc'];		//folder where the caches are stored
		$this->exts = $allowed_picture_exts;	//array containing valid image file extensions
	}
	function path($mid)
	{
		return array(
			'sm' => $this->folder . str_pad($mid, 5, '0', STR_PAD_LEFT) .'sm.png',
			'nm' => $this->folder . str_pad($mid, 5, '0', STR_PAD_LEFT) .'nm.png'
		);
	}
	function is_cached($mid)
	{
		//possible paths
		$paths = $this->path($mid);
		if (is_file($paths['sm']) && is_file($paths['nm']))
			return true;
		else
			return false;
	}
	function update($mid)
	{
		//make sure it is just an numeric string / number
		if (!is_numeric($mid))
			return false;
		//remove the old ones
		$this->remove($mid);
		//recache the image
		$this->cache($mid);
	}
	function remove($mid)
	{
		if (!is_numeric($mid))
			return false;
		//possible paths
		$paths = $this->path($mid);
		//to make the odds of this working as expected higher, make the files about to be deleted 777'd
		chmod($paths['sm'], 0777);
		chmod($paths['nm'], 0777);
		//delete each if exists
		if (is_file($paths['nm']))
			unlink($paths['nm']);
		if (is_file($paths['sm']))
			unlink($paths['sm']);
		return true;
	}
	function cache($mid)
	{
		global $sql, $dbt;
		$this->sql = $sql;
		//protect against stupidness
		if (!is_numeric($mid))
			return false;
		//make the variable db safe
		$mapid = $this->sql->prot($mid);
		//query that will be used to test if the mapid is real and to get the path to the real overview image
		$query = $this->sql->query("select `img` from `{$dbt['maps']}` where `id` = '$mapid' limit 1");
		//check if no rows returned (this means invalid ID or deleted map)
		if ($this->sql->num($query) == 0)
			return false;
		//paths to the new images
		//list($path_small, $path_normal) = $this->path($mid);
		$paths = $this->path($mid);
		$path_small = $paths['sm'];
		$path_normal = $paths['nm'];
		unset($paths);
		//if either already exist, don't do anything
		if (is_file($path_normal) || is_file($path_small))
			$this->remove($mid);
		//get path returned
		list($path) = $this->sql->data($query, 1);
		//save a little tiny bit of ram
		$this->sql->free($query);
		//path to the original overview image. should be very correct
		$path = $_SERVER['DOCUMENT_ROOT'] . '/' . stripslashes(trim($path));
		//make sure it is a valid path
		if (!is_file($path))
			return false;
		//get its file extension (using my custom file extension getting function)
		$file_ext = get_file_extension($path);
		//check if the extension isn't in the list of valid extension
		if (!in_array($file_ext, $this->exts))
			return false;
		//we think it might be an image, try loading the info in it
		$image_info = getimagesize($path);
		//if ($image_info[0] > 2500 || $image_info[1] > 2500)
		//	return false;
		//load the image depending on its type
		if ($image_info[2] == 3){	//to load from a png
			if (!($original_resource = imagecreatefrompng($path))) {
				return false;
			}
		} elseif ($image_info[2] == 2){	//to load from a jpg
			if (!($original_resource = imagecreatefromjpeg($path))) {
				return false;
			}
		} elseif ($image_info[2] == 6){	//meh. this sucks, but it needs to be anyway. load from a ...bmp
			if (!($original_resource = imagecreatefrombmp($path))) {
				return false;
			}
		} else {
			echo '<!--Cannot get info.-->';
			return false;
		}
		//echo "\n\n<!--Map ID: $mid Path: $path-->\n\n";
		//the sizes used for each image
		$size_normal = array(100,75);
		$size_small  = array(30,23);
		##create and save the normal sized image
		//resource for normal size image
		$normal_image_resource = imagecreatetruecolor($size_normal[0], $size_normal[1]);
		//copy the original resource into this new resource resized and in good quality
		if (!@imagecopyresampled(
			$normal_image_resource,
			$original_resource,
			0, 0, 0, 0,
			$size_normal[0],
			$size_normal[1],
			$image_info[0],
			$image_info[1]
		)) {
			imagedestroy($normal_image_resource);
			imagedestroy($original_resource);
			echo '<!--Cannot resize (larger)-->';
			return false;
		}
		//get the image into a variable
		ob_start();
		imagepng($normal_image_resource);
		$image = ob_get_clean();
		//destroy that resource
		imagedestroy($normal_image_resource);
		//put it?
		if (!@file_put_contents($path_normal, $image)){
			imagedestroy($original_resource);
			return false;
		}
		//save ram
		unset($image);
		##create and save the smaller sized image
		//resource for normal size image
		$small_image_resource = imagecreatetruecolor($size_small[0], $size_small[1]);
		//copy the original resource into this new resource resized and in good quality
		if (!@imagecopyresampled(
			$small_image_resource,
			$original_resource,
			0, 0, 0, 0,
			$size_small[0],
			$size_small[1],
			$image_info[0],
			$image_info[1]
		)){
			imagedestroy($small_image_resource);
			imagedestroy($original_resource);
			echo '<!--Cannot resize (smaller)-->';
			return false;
		}

		//get the image into a variable
		ob_start();
		imagepng($small_image_resource);
		$image = ob_get_clean();
		//destroy that resource
		imagedestroy($small_image_resource);
		//put it?
		if (!@file_put_contents($path_small, $image)){
			imagedestroy($original_resource);
			return false;
		}
		//save ram
		unset($image);
		##wrap it up
		//kill resource to main image
		imagedestroy($original_resource);
		//return true so I can know that this script worked
		return true;
	}
}
//screenshot thumbnail caching class. Also really fucking crucial to the speed of the site and the strain on the server
class Screenshot_Cache
{
	function Screenshot_Cache()
	{
		global $sf, $allowed_picture_exts, $sql;
		//get a few arrayed values to be local class values so I can code faster plus it's a little more compact and organized
		$this->folder = $sf['scc'];		//folder where the caches are stored
		$this->exts = $allowed_picture_exts;	//array containing valid image file extensions
		$this->sql = $sql;
	}
	function path($mid, $sid)
	{
		return $this->folder . str_pad($mid, 5, '0', STR_PAD_LEFT) .'-'.$sid.'.png';
	}
	function is_cached($mid, $sid)
	{
		//possible paths
		$path = $this->path($mid, $sid);
		if (is_file($path))
			return true;
		else
			return false;
	}
	function update($mid, $sid)
	{
		//protect against stupidness
		if (!is_numeric($mid) || !is_numeric($sid))
			return false;
		if ($sid != 1 && $sid != 2 && $sid != 3)
			return false;
		//remove the old ones
		$this->remove($mid, $sid);
		//recache the image
		$this->cache($mid, $sid);
	}
	function remove($mid, $sid)
	{
		//protect against stupidness
		if (!is_numeric($mid) || !is_numeric($sid))
			return false;
		if ($sid != 1 && $sid != 2 && $sid != 3)
			return false;
		//possible paths
		$path = $this->path($mid, $sid);
		//to make the odds of this working as expected higher, make the files about to be deleted 777'd
		chmod($path, 0777);
		//delete it if exists
		if (is_file($path))
			unlink($path);
		return true;
	}
	function cache($mid, $sid)
	{
		global $sql, $dbt;
		//protect against stupidness
		if (!is_numeric($mid) || !is_numeric($sid))
			return false;
		if ($sid != 1 && $sid != 2 && $sid != 3)
			return false;
		//make the variable db safe
		$mapid = $this->sql->prot($mid);
		$sid = $this->sql->prot($sid);
		//query that will be used to test if the mapid is real and to get the path to the real screenshot image
		$query = $this->sql->query("select `sc$sid` from `{$dbt['maps']}` where `id` = '$mapid' limit 1");
		//check if no rows returned (this means invalid ID or deleted map)
		if ($this->sql->num($query) == 0)
			return false;
		//paths to the new images
		//$path_normal = $this->folder . $mid . '-'.$sid.'.gif';
		$path_normal = $this->path($mid, $sid);
		//if either already exist, don't do anything
		if (is_file($path_normal))
			//return false;
			$this->remove($mapid, $sid);
		//get path returned
		list($path) = $this->sql->data($query, 1);
		//save a little tiny bit of ram
		$this->sql->free($query);
		//path to the original overview image. should be very correct
		$path = $_SERVER['DOCUMENT_ROOT'] . '/' . stripslashes(trim($path));
		//make sure it is a valid path
		if (!is_file($path))
			return false;
		//get its file extension (using my custom file extension getting function)
		$file_ext = get_file_extension($path);
		//check if the extension isn't in the list of valid extension
		if (!in_array($file_ext, $this->exts))
			return false;
		//we think it might be an image, try loading the info in it
		$image_info = getimagesize($path);
		//if ($image_info[0] > 2500 || $image_info[1] > 2500)
		//	return false;
		//load the image depending on its type
		if ($image_info[2] == 3){	//to load from a png
			if (!($original_resource = imagecreatefrompng($path))) {
				echo '<!--cant load from png-->';
				return false;
			}
		} elseif ($image_info[2] == 2){	//to load from a jpg
			if (!($original_resource = imagecreatefromjpeg($path))) {
				echo '<!--cant load from jpg-->';
				return false;
			}
		} elseif ($image_info[2] == 6){	//meh. this sucks, but it needs to be anyway. load from a ...bmp
			if (!($original_resource = imagecreatefrombmp($path))) {
				echo '<!--cant load from bmp-->';
				return false;
			}
		} else {
			echo '<!--wrong filetype-->';
			return false;
		}
		//echo "\n\n<!--Map ID: $mid Path: $path-->\n\n";
		//the sizes used for each image
		$size_normal = array(100,75);
		##create and save the normal sized image
		//resource for normal size image
		$normal_image_resource = imagecreatetruecolor($size_normal[0], $size_normal[1]);
		//copy the original resource into this new resource resized and in good quality
		if (!imagecopyresampled(
			$normal_image_resource,
			$original_resource,
			0, 0, 0, 0,
			$size_normal[0],
			$size_normal[1],
			$image_info[0],
			$image_info[1]
		)) {
			imagedestroy($normal_image_resource);
			imagedestroy($original_image_resource);
			echo '<!--error resampling-->';
			return false;
		}
		//save it
		if (!imagepng($normal_image_resource, $path_normal)){
			imagedestroy($normal_image_resource);
			imagedestroy($original_image_resource);
			echo '<!--error saving-->';
			return false;
		}
		//destroy that resource
		imagedestroy($normal_image_resource);
		//destroy that resource
		imagedestroy($small_image_resource);
		##wrap it up
		//kill resource to main image
		imagedestroy($original_resource);
		//return true so I can know that this script worked
		return true;
	}

	//wtf? stfu! blow me. sux my coxors bright house!
	function remote_scrn_cache($mid, $sid) {
		//resize
		global $sql, $dbt;
		//protect against stupidness
		if (!is_numeric($mid) || !is_numeric($sid))
			return false;
		if ($sid != 1 && $sid != 2 && $sid != 3)
			return false;
		//make the variable db safe
		$mapid = $this->sql->prot($mid);
		$sid = $this->sql->prot($sid);
		//query that will be used to test if the mapid is real and to get the path to the real screenshot image
		$query = $this->sql->query("select `sc$sid` from `{$dbt['maps']}` where `id` = '$mapid' limit 1");
		//check if no rows returned (this means invalid ID or deleted map)
		if ($this->sql->num($query) == 0)
			return false;
		//paths to the new images
		//$path_normal = $this->folder . $mid . '-'.$sid.'.gif';
		$path_normal = $this->path($mid, $sid);
		//if either already exist, don't do anything
		if (is_file($path_normal))
			//return false;
			$this->remove($mapid, $sid);
		//get path returned
		list($path) = $this->sql->data($query, 1);
		//save a little tiny bit of ram
		$this->sql->free($query);
		//path to the original overview image. should be very correct
		$path = $_SERVER['DOCUMENT_ROOT'] . '/' . stripslashes(trim($path));
		//make sure it is a valid path
		if (!is_file($path))
			return false;
		//get its file extension (using my custom file extension getting function)
		$file_ext = get_file_extension($path);
		//check if the extension isn't in the list of valid extension
		if (!in_array($file_ext, $this->exts))
			return false;
		//we think it might be an image, try loading the info in it
		$image_info = getimagesize($path);
		//if ($image_info[0] > 2500 || $image_info[1] > 2500)
		//	return false;
		//load the image depending on its type
		if ($image_info[2] == 3){	//to load from a png
			if (!($original_resource = imagecreatefrompng($path))) {
				echo '<!--cant load from png-->';
				return false;
			}
		} elseif ($image_info[2] == 2){	//to load from a jpg
			if (!($original_resource = imagecreatefromjpeg($path))) {
				echo '<!--cant load from jpg-->';
				return false;
			}
		} elseif ($image_info[2] == 6){	//meh. this sucks, but it needs to be anyway. load from a ...bmp
			if (!($original_resource = imagecreatefrombmp($path))) {
				echo '<!--cant load from bmp-->';
				return false;
			}
		} else {
			echo '<!--wrong filetype-->';
			return false;
		}
		//echo "\n\n<!--Map ID: $mid Path: $path-->\n\n";
		//the sizes used for each image
		$size_normal = array(100,75);
		##create and save the normal sized image
		//resource for normal size image
		$normal_image_resource = imagecreatetruecolor($size_normal[0], $size_normal[1]);
		//copy the original resource into this new resource resized and in good quality
		if (!imagecopyresampled(
			$normal_image_resource,
			$original_resource,
			0, 0, 0, 0,
			$size_normal[0],
			$size_normal[1],
			$image_info[0],
			$image_info[1]
		)) {
			imagedestroy($normal_image_resource);
			imagedestroy($original_image_resource);
			echo '<!--error resampling-->';
			return false;
		}

		ob_start();
		imagepng($normal_image_resource, null);
		$image = base64_encode(ob_get_clean());
		//save ram
		imagedestroy($normal_image_resource);
		imagedestroy($original_image_resource);
		//we need a secret pw to prevent bots and evil people from flooding the server with shit
		$pw = md5(date('fdyh').'sexfuckyeah!');
		//grab url
		$result = trim(file_get_contents(
			"http://jrgp.us:70/tms_mirrors/cache.php?pw=$pw&r=nscr&gen=$image&m=$mid&s=$sid"));
		//decide wtf happens next..
		if ($result != '0' && strlen(get_file_extension($result)) == 3) {
			return $result;
		} else {
			echo '<p>result was '.$result.'</p>';
			return false;
		}
	}
}
//custom size of the overview thumbnail
class Overview_Cache_Custom_Size {
	//start off by getting some stuff localized
	function Overview_Cache_Custom_Size() {
		global $sf, $allowed_picture_exts;
		$this->folder = $sf['ovc'].'c_size/'; //folder to store thumbs
		$this->exts = $allowed_picture_exts; //allowed file extensions
		$this->max_age = 864000; //ten days (in seconds)
		$this->output_type = 'png';
	}
	//kill ALL cached files. returns false or the number of ones deleted
	function purge_all() {
		$caches = glob($this->folder.'*');
		//stats
		$killed_files = 0;
		$failed_deleting_files = 0;
		//kill them
		foreach($caches as $f) {
			@unlink($f) ? $killed_files++ : $failed_deleting_files++;
			unset($f);
		}
		//determine what to return
		if ($failed_deleting_files > 0)
			return false;
		else
			return empty($killed_files) ? true : $killed_files;
	}
	//kill specific one
	function purge_specific($map_id) {
		if (!ctype_digit($map_id))		//gotta be an integer
			return false;
		$possible_files = glob($this->folder.$map_id.'_*');
		//stats
		$killed_files = 0;
		$failed_deleting_files = 0;
		//kill them
		foreach($possible_files as $f) {
			@unlink($f) ? $killed_files++ : $failed_deleting_files++;
			unset($f);
		}
		//determine what to return
		if ($failed_deleting_files > 0)
			return false;
		else
			return empty($killed_files) ? true : $killed_files;
	}
	//kill old ones
	function purge_old() {
		$caches = glob($this->folder.'*');
		$to_kill = array();
		if (count($caches) == 0) //nothing to remove?
			return true;
		//stat
		$failed = 0;
		$killed = 0;
		foreach ($caches as $f) { //kill 'em all
			//decide which time to use, the former being better and the latter being more accurate
			$time_differ = ($t = @fileatime($f)) ? $t : filemtime($f);
			unset($t); //kill that temp variable
			$time_diff = time() - $time_differ; //old enough to remove?
			if ($time_diff >= $this->max_age) {
				@unlink($f) ? $killed++ : $failed++;
			}
			unset($time_diff, $f);
		}
		//determine what to return
		if ($failed > 0)
			return false;
		else
			return empty($killed) ? true : $killed;
	}
	//cache a new map's overview's custom thumbnail
	//returns true on success and false on failure
	function cache($map_id, $width, $height) {
		global $sql, $dbt;
		//wtf snafu?
		if ($width == 100 && $height == 75) {
			Overview_Cache::update($map_id);
			return true;
		}
		$get_info = $sql->query("
			select
				`img`
			from
				`{$dbt['maps']}`
			where
				`id` = '".$sql->prot($map_id)."'
			limit 1");
		if ($sql->num($get_info) == 0) {
			$sql->free($get_info);
			return false;
		}
		//assuming it all goes okay, this will be final path to thumb
		$final_path = $this->path($map_id, $width, $height);
		if (is_file($final_path)) {
			$this->purge_specific($map_id);
		}
		list($original_image_path) = $sql->data($get_info, 1);
		$sql->free($get_info);
		$original_image_path = trim(stripslashes($original_image_path));
		if (!is_file($original_image_path))
			return false;
		//load current image
		if (!($image_info = @getimagesize($original_image_path))) {
			echo'cannot get image info';
			return false;
		}
		switch (get_file_extension($original_image_path)) {
			case 'png':
				if (!($original_image_rsc = @imagecreatefrompng($original_image_path)))
					{echo'cannot load from png'; return false;}
			break;
			case 'jpg':
			case 'jpeg':
				if (!($original_image_rsc = @imagecreatefromjpeg($original_image_path)))
					{echo'cannot load from jpg'; return false;}
			break;
			case 'bmp': // (this function does not exist normally)
				if (!($original_image_rsc = @imagecreatefrombmp($original_image_path)))
					{echo'cannot load from bmp'; return false;}
			break;
			default:
				return false;
			break;
		}
		//create new image placeholder to hold the new image
		if (!($new_image_rsc = @imagecreatetruecolor($width, $height))) {
			imagedestroy($original_image_rsc);
			return false;
		}
		//resample over
		if (!@imagecopyresampled(
				$new_image_rsc,$original_image_rsc,
				0,0,0,0,
				$width,$height,
				$image_info[0],$image_info[1]
			)){
			echo 'cannot resample image';
			imagedestroy($original_image_rsc);
			imagedestroy($new_image_rsc);
			return false;
		}
		//destroy original resource
		imagedestroy($original_image_rsc);
		//put new
		switch($this->output_type) {
			case 'png':
				if (!@imagepng($new_image_rsc, $final_path, 9)) {
					imagedestroy($new_image_rsc);
					return false;
				}
			break;
			case 'jpg':
			case 'jpeg':
				if (!@imagejpeg($new_image_rsc, $final_path)) {
					imagedestroy($new_image_rsc);
					return false;
				}
			break;
		}
		//we're done
		imagedestroy($new_image_rsc);
		return true;
	}
	//gets path for a resized thumb
	function path($map_id, $width, $height) {
		$final_path = $this->folder.$map_id.'_'.$width.'x'.$height.'.'.$this->output_type;
		return $final_path;
	}
	//see if path above exists
	function check_path($map_id, $width, $height) {
		if (is_file($this->path($map_id, $width, $height)))
			return true;
		else
			return false;
	}
}