v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

User:Quietust/wtf23a.php

From Dwarf Fortress Wiki
< User:Quietust
Revision as of 20:44, 14 April 2014 by Quietust (talk | contribs) (make a few tweaks)
Jump to navigation Jump to search
<?php
function readByte ($file)
{
	$x = fread($file, 1);
	$pck = @unpack('Cdata', $x);
	return $pck['data'];
}

function readLong ($file)
{
	$x = fread($file, 4);
	$pck = @unpack('Vdata', $x);
	return $pck['data'];
}

function writeLong ($file, $data)
{
	$x = @pack('V', $data);
	fwrite($file, $x, 4);
}

class rng
{
	var $data = array();
	var $index = 0;

	function init ($data)
	{
		for ($i = 0; $i < 624; $i++)
			$this->data[$i] = $data[$i];
		$this->index = $data[624] / 4;
	}
	function get ($i)
	{
		$x = $this->next();
		if ($x < 0)
			return (int)fmod($x + 4294967296.0, $i);
		return $x % $i;
	}
	function next()
	{
		if ($this->index == 624)
			$this->generate();
		return $this->data[$this->index++];
	}
	function generate()
	{
		for ($i = 0; $i < 624; $i++)
		{
			$y = ($this->data[$i] & 0x80000000) | ($this->data[($i+1) % 624] & 0x7FFFFFFF);
			$this->data[$i] = $this->data[($i + 397) % 624] ^ (($y >> 1) & 0x7FFFFFFF);
			if ($y & 1)
				$this->data[$i] ^= 0x9908b0df;
		}
		$this->index = 0;
	}
}

function _readCrypt ($file)
{
	// read mt state
	$state = array();
	for ($i = 0; $i < 625; $i++)
		$state[$i] = readLong($file);
	if (feof($file))
		return false;

	// read header
	$len = readLong($file);
	$data = range(0, $len - 1);

	$rng = new rng;

	// read data, skipping dummy bytes
	$rng->init($state);
	for ($i = $len - 1; $i >= 0; $i--)
	{
		$data[$i] = readByte($file);
		if ($rng->get(2))
		{
			$rng->get(256);
			readByte($file);
		}
	}

	// decode data
	$rng->init($state);
	for ($i = $len - 1; $i >= 0; $i--)
		$data[$i] -= $rng->get(10);

	// convert to string
	$out = '';
	for ($i = 0; $i < $len; $i++)
		$out .= chr($data[$i] & 0xFF);
	return $out;
}

function _writeCrypt ($file, $data)
{
	// write mt state
	for ($i = 0; $i < 625; $i++)
		writeLong($file, 0);

	// write header
	$len = strlen($data);
	writeLong($file, $len);

	// write data
	// since mt state is null, this is much simpler than above
	for ($i = $len; $i > 0; $i--)
		fwrite($file, $data[$i-1], 1);
}

function compress_file ($in, $out)
{
	while (1)
	{
		$data = fread($in, 20000);
		$comp = gzcompress($data, 9);
		if ($comp === FALSE)
			return false;

		_writeCrypt($out, $comp);
		if (feof($in))
			break;
	}
	return true;
}

function decompress_file ($in, $out)
{
	while (1)
	{
		$block = _readCrypt($in);
		if ($block === FALSE)
			break;
		$decomp = gzuncompress($block);
		if ($decomp === FALSE)
			return false;
		fwrite($out, $decomp);
	}
	return true;
}

function unpack_file ($in, $out)
{
	$numrecords = readLong($in);
	for ($i = 0; $i < $numrecords; $i++)
	{
		$len = readLong($in);
		if ($len < 1)
			return false;
		$str = fread($in, $len);
		if (feof($in))
			return false;
		if ($out)
			fwrite($out, "$str\r\n");
		else	echo "$str\n";
		fread($in, 1);
	}
	return true;
}

function pack_file ($in, $out)
{
	$data = explode("\n", trim(stream_get_contents($in)));
	$numrecords = count($data);
	writeLong($out, $numrecords);
	for ($i = 0; $i < $numrecords; $i++)
	{
		$line = trim($data[$i]);
		$len = strlen($line);
		writeLong($out, $len);
		fwrite($out, $line, $len);
		fwrite($out, chr(0), 1);
	}
	return true;
}

function decompack_file ($in, $out)
{
	$tmp = tmpfile();
	if (!decompress_file($in, $tmp))
		return false;
	rewind($tmp);
	if (!unpack_file($tmp, $out))
		return false;
	fclose($tmp);
	return true;
}

function compack_file ($in, $out)
{
	$tmp = tmpfile();
	if (!pack_file($in, $tmp))
		return false;
	rewind($tmp);
	if (!compress_file($tmp, $out))
		return false;
	fclose($tmp);
	return true;
}

function copy_file ($in, $out)
{
	while (!feof($in))
	{
		$data = fread($in, 1048576);
		fwrite($out, $data);
	}
	return true;
}

function error ($str)
{
	fprintf(STDERR, "ERROR: %s\n", $str);
	exit(2);
}

function usage ($command = '')
{
	global $argv;
	switch ($command)
	{
	case 'decompress':
		fprintf(STDERR, "Syntax: %s decompress <infile> [outfile]\n", $argv[0]);
		fprintf(STDERR, "Omit [outfile] to decompress the file in-place.\n");
		break;
	case 'compress':
		fprintf(STDERR, "Syntax: %s compress <infile> [outfile]\n", $argv[0]);
		fprintf(STDERR, "Omit [outfile] to compress the file in-place.\n");
		break;
	case 'recompress':
		fprintf(STDERR, "Syntax: %s recompress <file>\n", $argv[0]);
		break;
	case 'unpack':
		fprintf(STDERR, "Syntax: %s unpack <infile> [outfile]\n", $argv[0]);
		fprintf(STDERR, "Omit [outfile] to unpack the file in-place.\n");
		fprintf(STDERR, "Specify an outfile of '-' to print directly to the screen.\n");
		break;
	case 'pack':
		fprintf(STDERR, "Syntax: %s pack <infile> [outfile]\n", $argv[0]);
		fprintf(STDERR, "Omit [outfile] to pack the file in-place.\n");
		break;
	case 'decompack':
		fprintf(STDERR, "Syntax: %s decompack <infile> [outfile]\n", $argv[0]);
		fprintf(STDERR, "Omit [outfile] to decompress and unpack the file in-place.\n");
		fprintf(STDERR, "Specify an outfile of '-' to print directly to the screen.\n");
		break;
	case 'compack':
		fprintf(STDERR, "Syntax: %s compack <infile> [outfile]\n", $argv[0]);
		fprintf(STDERR, "Omit [outfile] to pack and compress the file in-place.\n");
		break;
	default:
		fprintf(STDERR, "Syntax: %s <command> args...\n", $argv[0]);
		fprintf(STDERR, "Valid commands:\n");
		fprintf(STDERR, "  decompress <infile> [outfile] - decrypts and extracts a binary file.\n");
		fprintf(STDERR, "  compress <infile> [outfile] - compresses and encrypts a binary file.\n");
		fprintf(STDERR, "  recompress <file> - recompresses a compressed a binary file in place.\n");
		fprintf(STDERR, "  unpack <infile> [outfile] - converts packed text into plain text.\n");
		fprintf(STDERR, "  pack <infile> [outfile] - converts plain text into packed text.\n");
		fprintf(STDERR, "  decompack <infile> [outfile] - decrypts, extracts, and unpacks text.\n");
		fprintf(STDERR, "  compack <infile> [outfile] - packs, compresses, and encrypts text.\n");
		break;
	}
	exit(1);
}

function operation ($infn, $inmode, $outfn, $outmode, $op1, $op1desc, $op2, $op2desc)
{
	$in_place = ($infn == $outfn);

	$ts = filemtime($infn);
	$infile = fopen($infn, $inmode);
	if (!$infile)
		error("Unable to open input file '$infn'!");

	if ($in_place)
		$outfile = tmpfile();
	else
	{
		if ($outfn)
		{
			$outfile = fopen($outfn, $outmode);
			if (!$outfile)
				error("Unable to create output file '$outfn'!");
		}
		else	$outfile = NULL;
	}

	if (!$op1($infile, $outfile))
		error("Failed to $op1desc '$infn'!");
	fclose($infile);

	if ($in_place)
	{
		$infile = $outfile;
		rewind($infile);
		$outfile = fopen($outfn, $outmode);
		if (!$op2($infile, $outfile))
			error("Failed to $op2desc '$outfn'!");
		fclose($infile);
	}

	if ($outfile)
	{
		fclose($outfile);
		touch($outfn, $ts);
	}
}


if ($argc < 2)
	usage();

switch ($argv[1])
{
case 'decompress':
	if ($argc < 3)
		usage($argv[1]);

	$infn = $argv[2];
	$outfn = ($argc < 4) ? $infn : $argv[3];
	operation($infn, 'rb', $outfn, 'wb', 'decompress_file', 'decompress', 'copy_file', 'copy output back to');
	break;

case 'compress':
	if ($argc < 3)
		usage($argv[1]);

	$infn = $argv[2];
	$outfn = ($argc < 4) ? $infn : $argv[3];
	operation($infn, 'rb', $outfn, 'wb', 'compress_file', 'compress', 'copy_file', 'copy output back to');
	break;

case 'recompress':
	if ($argc < 3)
		usage($argv[1]);

	$fn = $argv[2];
	operation($fn, 'rb', $fn, 'wb', 'decompress_file', 'decompress', 'compress_file', 'recompress');
	break;

case 'unpack':
	if ($argc < 3)
		usage($argv[1]);

	$infn = $argv[2];
	$outfn = ($argc < 4) ? $infn : (($argv[3] == '-') ? '' : $argv[3]);
	operation($infn, 'rb', $outfn, 'w', 'unpack_file', 'unpack', 'copy_file', 'copy output back to');
	break;
case 'pack':
	if ($argc < 3)
		usage($argv[1]);

	$infn = $argv[2];
	$outfn = ($argc < 4) ? $infn : $argv[3];
	operation($infn, 'r', $outfn, 'wb', 'pack_file', 'unpack', 'copy_file', 'copy output back to');
	break;
case 'decompack':
	if ($argc < 3)
		usage($argv[1]);

	$infn = $argv[2];
	$outfn = ($argc < 4) ? $infn : (($argv[3] == '-') ? '' : $argv[3]);
	operation($infn, 'rb', $outfn, 'w', 'decompack_file', 'decompress and unpack', 'copy_file', 'copy output back to');
	break;
case 'compack':
	if ($argc < 3)
		usage($argv[1]);

	$infn = $argv[2];
	$outfn = ($argc < 4) ? $infn : $argv[3];
	operation($infn, 'r', $outfn, 'wb', 'compack_file', 'pack and compress', 'copy_file', 'copy output back to');
	break;
default:
	fprintf(STDERR, "Invalid command '%s'!\n", $mode);
	break;
}
?>