justsomeguy Posted June 30, 2010 Share Posted June 30, 2010 If you want to parse the files, then you need to understand the format of them. The first thing most people try is just to open the file in a text editor and see what the data is. If it's binary data, then you need to find a specification for the format that the data is in, or find someone who knows. Link to comment Share on other sites More sharing options...
Mesden Posted June 30, 2010 Author Share Posted June 30, 2010 Ha! Found something in PHP http://kuukkeli.ath.cx/ooaemkee/SC2Replay/upload_file.php Link to comment Share on other sites More sharing options...
Mesden Posted June 30, 2010 Author Share Posted June 30, 2010 Ha! Found something in PHP http://kuukkeli.ath.cx/ooaemkee/SC2Replay/upload_file.php It says this:Command-line accessGet a local copy of the phpsc2replay repository with this command:hg clone https://phpsc2replay.googlecode.com/hg/ phpsc2replayWhere would I type this command? What is it referring to..? Link to comment Share on other sites More sharing options...
boen_robot Posted June 30, 2010 Share Posted June 30, 2010 That's a version control command. You'd need to have the client, and type it there... or not.Look at the "browser" link above, on that very same page. Link to comment Share on other sites More sharing options...
Mesden Posted June 30, 2010 Author Share Posted June 30, 2010 Yup! Got the entire coding for the Parser. Just not quite sure what to do with it. I just keep getting parse errors... NetBeans doesn't see the problem though...Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /hsphere/local/home/aaron21/sc2x.net/mpqfile.php on line 31 <?php/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.*/define("MPQ_HASH_TABLE_OFFSET", 0);define("MPQ_HASH_NAME_A", 1);define("MPQ_HASH_NAME_B", 2);define("MPQ_HASH_FILE_KEY", 3);define("MPQ_HASH_ENTRY_EMPTY", (0xFFFF << 16) | 0xFFFF);define("MPQ_HASH_ENTRY_DELETED", (0xFFFF << 16) | 0xFFFE);define("MPQ_NOT_PARSED", 2);define("MPQ_PARSE_OK", 1);define("MPQ_ERR_NOTMPQFILE", -1);class MPQFile { private $filename; private $fp; private $hashtable,$blocktable; private $hashTableSize, $blocKTableSize; private $headerOffset; private $init; private $verMajor; private $build; private $sectorSize; private $debug; private $debugNewline; private $gameLen; public static $cryptTable; function __construct($filename, $autoparse = true, $debug = 0) { $this->filename = $filename; $this->hashtable = NULL; $this->blocktable = NULL; $this->hashTableSize = 0; $this->blockTableSize = 0; $this->headerOffset = 0; $this->init = false; $this->verMajor = 0; $this->build = 0; $this->gameLen = 0; $this->sectorSize = 0; $this->debug = $debug; $this->debugNewline = "<br />\n"; if (!self::$cryptTable) self::initCryptTable(); if (file_exists($this->filename)) { $this->fp = fopen($this->filename, 'rb'); if ($this->debug && $this->fp === false) $this->debug("Error opening file $filename for reading"); } if ($autoparse) $this->parseHeader(); } function __destruct() { if ($this->fp !== FALSE) fclose($this->fp); } private function debug($message) { echo $message.($this->debugNewline); } function setDebugNewline($str) { $this->debugNewline = $str; } function setDebug($bool) { $this->debug = $bool; } function parseHeader() { if ($this->fp === FALSE) { return false; if ($this->debug) $this->debug("Invalid file pointer"); } $fp = $this->fp; $headerParsed = false; $headerOffset = 0; while (!$headerParsed) { $magic = unpack("c4",fread($fp,4)); // MPQ 1Bh or 1Ah if (($magic[1] != 0x4D) || ($magic[2] != 0x50) || ($magic[3] != 0x51)) { $this->init = MPQ_ERR_NOTMPQFILE; return false; } if ($magic[4] == 27) { // user data block (1Bh) if ($this->debug) $this->debug(sprintf("Found user data block at %08X",ftell($fp))); $uDataMaxSize = $this->readUInt32(); $headerOffset = $this->readUInt32(); $this->headerOffset = $headerOffset; $uDataSize = $this->readUInt32(); fseek($fp,24,SEEK_CUR); // skip Starcraft II replay 0x1B 0x32 0x01 0x00 $verMajor = $this->readUInt16(); $this->verMajor = $verMajor; $build = $this->readUInt32(true); $this->build = $build; $build2 = $this->readUInt32(true); fseek($fp,2,SEEK_CUR); // skip 02 00 $gameLen = $this->readUInt16(true) / 2; $this->gameLen = $gameLen; fseek($fp,$headerOffset); } else if ($magic[4] == 26) { // header (1Ah) if ($this->debug) $this->debug(sprintf("Found header at %08X",ftell($fp))); $headerSize = $this->readUInt32(); $archiveSize = $this->readUInt32(); $formatVersion = $this->readUInt16(); $sectorSizeShift = $this->readByte(); $sectorSize = 512 * pow(2,$sectorSizeShift); $this->sectorSize = $sectorSize; fseek($fp, 1, SEEK_CUR); $hashTableOffset = $this->readUInt32() + $headerOffset; $blockTableOffset = $this->readUInt32() + $headerOffset; $hashTableEntries = $this->readUInt32(); $this->hashTableSize = $hashTableEntries; $blockTableEntries = $this->readUInt32(); $this->blockTableSize = $blockTableEntries; $headerParsed = true; } else { if ($this->debug) $this->debug("Could not find MPQ header"); return false; } } // read and decode the hash table fseek($this->fp, $hashTableOffset); $hashSize = $hashTableEntries * 4; // hash table size in 4-byte chunks $tmp = array(); for ($i = 0;$i < $hashSize;$i++) $tmp[$i] = $this->readUInt32(); $hashTable = self::decryptStuff($tmp,self::hashStuff("(hash table)", MPQ_HASH_FILE_KEY)); if ($this->debug) { $this->debug("DEBUG: Hash table"); $this->debug("HashA, HashB, Language+platform, Fileblockindex"); $tmpnewline = $this->debugNewline; $this->debugNewline = ""; for ($i = 0;$i < $hashTableEntries;$i++) { $filehashA = $hashTable[$i*4]; $filehashB = $hashTable[$i*4 +1]; $lanplat = $hashTable[$i*4 +2]; $blockindex = $hashTable[$i*4 +3]; $this->debug(sprintf("<pre>%08X %08X %08X %08X</pre>",$filehashA, $filehashB, $lanplat, $blockindex)); } $this->debugNewline = $tmpnewline; } // read and decode the block table fseek($this->fp, $blockTableOffset); $blockSize = $blockTableEntries * 4; // block table size in 4-byte chunks $tmp = array(); for ($i = 0;$i < $blockSize;$i++) $tmp[$i] = $this->readUInt32(); $blockTable = self::decryptStuff($tmp,self::hashStuff("(block table)", MPQ_HASH_FILE_KEY)); $this->hashtable = $hashTable; $this->blocktable = $blockTable; if ($this->debug) { $this->debug("DEBUG: Block table"); $this->debug("Offset, Blocksize, Filesize, flags"); $tmpnewline = $this->debugNewline; $this->debugNewline = ""; for ($i = 0;$i < $blockTableEntries;$i++) { $blockIndex = $i * 4; $blockOffset = $this->blocktable[$blockIndex] + $this->headerOffset; $blockSize = $this->blocktable[$blockIndex + 1]; $fileSize = $this->blocktable[$blockIndex + 2]; $flags = $this->blocktable[$blockIndex + 3]; $this->debug(sprintf("<pre>%08X %8d %8d %08X</pre>",$blockOffset, $blockSize, $fileSize, $flags)); } $this->debugNewline = $tmpnewline; } $this->init = MPQFILE_PARSE_OK; return true; } // read little endian 32-bit integer private function readUInt32($bigendian = false) { if ($this->fp === FALSE) return false; $t = unpack(($bigendian === true)?"N":"V",fread($this->fp,4)); return $t[1]; } private function readUInt16($bigendian = false) { if ($this->fp === FALSE) return false; $t = unpack(($bigendian === true)?"n":"v",fread($this->fp,2)); return $t[1]; } private function readByte() { if ($this->fp === FALSE) return false; $t = unpack("C",fread($this->fp,1)); return $t[1]; } // read a byte from string and remove the read byte private function readSByte(&$string) { $t = unpack("C",substr($string,0,1)); $string = substr($string,1,strlen($string) -1); return $t[1]; } function getFileSize($filename) { if ($this->init !== MPQFILE_PARSE_OK) { if ($this->debug) $this->debug("Tried to use getFileSize without initializing"); return false; } $hashA = self::hashStuff($filename, MPQ_HASH_NAME_A); $hashB = self::hashStuff($filename, MPQ_HASH_NAME_; $hashStart = self::hashStuff($filename, MPQ_HASH_TABLE_OFFSET) & ($this->hashTableSize - 1); $tmp = $hashStart; do { if (($this->hashtable[$tmp*4 + 3] == MPQ_HASH_ENTRY_DELETED) || ($this->hashtable[$tmp*4 + 3] == MPQ_HASH_ENTRY_EMPTY)) return false; if (($this->hashtable[$tmp*4] == $hashA) && ($this->hashtable[$tmp*4 + 1] == $hashB)) { // found file $blockIndex = ($this->hashtable[($tmp *4) + 3]) *4; $fileSize = $this->blocktable[$blockIndex + 2]; return $fileSize; } $tmp = ($tmp + 1) % $this->hashTableSize; } while ($tmp != $hashStart); if ($this->debug) $this->debug("Did not find file $filename in archive"); return false; } function readFile($filename) { if ($this->init !== MPQFILE_PARSE_OK) { if ($this->debug) $this->debug("Tried to use getFile without initializing"); return false; } $hashA = self::hashStuff($filename, MPQ_HASH_NAME_A); $hashB = self::hashStuff($filename, MPQ_HASH_NAME_; $hashStart = self::hashStuff($filename, MPQ_HASH_TABLE_OFFSET) & ($this->hashTableSize - 1); $tmp = $hashStart; $blockSize = -1; do { if (($this->hashtable[$tmp*4 + 3] == MPQ_HASH_ENTRY_DELETED) || ($this->hashtable[$tmp*4 + 3] == MPQ_HASH_ENTRY_EMPTY)) return false; if (($this->hashtable[$tmp*4] == $hashA) && ($this->hashtable[$tmp*4 + 1] == $hashB)) { // found file $blockIndex = ($this->hashtable[($tmp *4) + 3]) *4; $blockOffset = $this->blocktable[$blockIndex] + $this->headerOffset; $blockSize = $this->blocktable[$blockIndex + 1]; $fileSize = $this->blocktable[$blockIndex + 2]; $flags = $this->blocktable[$blockIndex + 3]; break; } $tmp = ($tmp + 1) % $this->hashTableSize; } while ($tmp != $hashStart); if ($blockSize == -1) { if ($this->debug) $this->debug("Did not find file $filename in archive"); return false; } $flag_file = $flags & 0x80000000; $flag_checksums = $flags & 0x04000000; $flag_deleted = $flags & 0x02000000; $flag_singleunit = $flags & 0x01000000; $flag_hEncrypted = $flags & 0x00020000; $flag_encrypted = $flags & 0x00010000; $flag_compressed = $flags & 0x00000200; $flag_imploded = $flags & 0x00000100; if ($this->debug) $this->debug(sprintf("Found file $filename with flags %08X, block offset %08X, block size %d and file size %d", $flags, $blockOffset,$blockSize,$fileSize)); if (!$flag_file) return false; fseek($this->fp,$blockOffset); if ($flag_checksums) { for ($i = $fileSize;$i > 0;$i -= $this->sectorSize) { $sectors[] = $this->readUInt32(); $blockSize -= 4; } $sectors[] = $this->readUInt32(); $blockSize -= 4; } else { $sectors[] = 0; $sectors[] = $blockSize; } $c = count($sectors) - 1; $totDur = 0; for ($i = 0;$i < $c;$i++) { $sectorLen = $sectors[$i + 1] - $sectors[$i]; fseek($this->fp,$blockOffset + $sectors[$i],SEEK_SET); $sectorData = fread($this->fp,$sectorLen); if ($flag_compressed && (($flag_singleunit && ($blockSize < $fileSize)) || ($flag_checksums && ($sectorLen < $this->sectorSize)))) { $compressionType = $this->readSByte($sectorData); switch ($compressionType) { case 2: $output .= self::deflate_decompress($sectorData); break; default: if ($this->debug) $this->debug(sprintf("Unknown compression type: %d",$compressionType)); return false; } } else $output .= $sectorData; } if (strlen($output) != $fileSize) { if ($this->debug) $this->debug(sprintf("Decrypted/uncompressed file size(%d) does not match original file size(%d)", strlen($output),$fileSize)); return false; } return $output; } function parseReplay() { if ($this->init !== MPQFILE_PARSE_OK) { if ($this->debug) $this->debug("Tried to use parseReplay without initializing"); return false; } if (class_exists("SC2Replay") || (include 'sc2replay.php')) { $tmp = new SC2Replay(); if ($this->debug) $tmp->setDebug($this->debug); $tmp->parseReplay($this); return $tmp; } else { if ($this->debug) $this->debug("Unable to find or load class SC2Replay"); return false; } } function getState() { return $this->init; } function getBuild() { return $this->build; } function getVersion() { return $this->verMajor; } function getGameLength() { return $this->gameLen; } static function deflate_decompress($string) { if (function_exists("gzinflate")){ $tmp = gzinflate(substr($string,2,strlen($string) - 2)); return $tmp; } if ($this->debug) $this->debug("Function 'gzinflate' does not exist, is gzlib installed as a module?"); return false; } static function initCryptTable() { if (!self::$cryptTable) self::$cryptTable = array(); $seed = 0x00100001; $index1 = 0; $index2 = 0; for ($index1 = 0; $index1 < 0x100; $index1++) { for ($index2 = $index1, $i = 0; $i < 5; $i++, $index2 += 0x100) { $seed = (uPlus($seed * 125,3)) % 0x2AAAAB; $temp1 = ($seed & 0xFFFF) << 0x10; $seed = (uPlus($seed * 125,3)) % 0x2AAAAB; $temp2 = ($seed & 0xFFFF); self::$cryptTable[$index2] = ($temp1 | $temp2); } } } static function hashStuff($string, $hashType) { $seed1 = 0x7FED7FED; $seed2 = ((0xEEEE << 16) | 0xEEEE); $strLen = strlen($string); for ($i = 0;$i < $strLen;$i++) { $next = ord(strtoupper(substr($string, $i, 1))); $seed1 = self::$cryptTable[($hashType << 8) + $next] ^ (uPlus($seed1,$seed2)); $seed2 = uPlus(uPlus(uPlus(uPlus($next,$seed1),$seed2),$seed2 << 5),3); } return $seed1; } static function decryptStuff($data, $key) { $seed = ((0xEEEE << 16) | 0xEEEE); $datalen = count($data); for($i = 0;$i < $datalen;$i++) { $seed = uPlus($seed,self::$cryptTable[0x400 + ($key & 0xFF)]); $ch = $data[$i] ^ (uPlus($key,$seed)); $data[$i] = $ch & ((0xFFFF << 16) | 0xFFFF); $key = (uPlus(((~$key) << 0x15), 0x11111111)) | (rShift($key,0x0B)); $seed = uPlus(uPlus(uPlus($ch,$seed),($seed << 5)),3); } return $data; }}function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec);}// function that adds up two integers without allowing them to overflow to floatsfunction uPlus($o1, $o2) { $o1h = ($o1 >> 16) & 0xFFFF; $o1l = $o1 & 0xFFFF; $o2h = ($o2 >> 16) & 0xFFFF; $o2l = $o2 & 0xFFFF; $ol = $o1l + $o2l; $oh = $o1h + $o2h; if ($ol > 0xFFFF) { $oh += (($ol >> 16) & 0xFFFF); } Â Link to comment Share on other sites More sharing options...
justsomeguy Posted June 30, 2010 Share Posted June 30, 2010 Is your server running PHP5? Link to comment Share on other sites More sharing options...
Mesden Posted July 1, 2010 Author Share Posted July 1, 2010 Is your server running PHP5?Yep, it is now, and the PHP5 fixed one of the problems, but created another. Now my PHP Includes are no longer working.<? include '/topbar.php' ?>What I did previously was create a seperate file on my server called topbar.php. This would contain the Links in the Navigation Bar at the top of the page so rather than having to update the links on every page with that navigation bar, I could just use an include and change them all at once.Well now that I upgraded to PHP5, that include command doesn't seem to work anymore. Any ideas? Thought I had it fixed but I guess not. Link to comment Share on other sites More sharing options...
boen_robot Posted July 1, 2010 Share Posted July 1, 2010 You're using the short notation. AFAIK, on many servers, it's disabled by default. Try to change those to: <?php include '/topbar.php' ?> Link to comment Share on other sites More sharing options...
Mesden Posted July 1, 2010 Author Share Posted July 1, 2010 Yeah I E-mailed my web host and they said something similar, only to take out the '/'.(ie. <?php include 'topbar.php' ?> Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.