1
0
mirror of https://github.com/Rogiel/php-mpq synced 2025-12-06 08:23:05 +00:00

Improves testing and documentation

This commit is contained in:
2016-01-07 01:54:34 -02:00
parent e02bd6da17
commit aeb01ce902
28 changed files with 1377 additions and 28 deletions

View File

@@ -29,14 +29,30 @@
namespace Rogiel\MPQ\Compression;
use Rogiel\MPQ\Exception\Compression\InvalidInputDataException;
class BZIPCompression implements Compression {
/**
* {@inheritdoc}
*/
public function compress($data, $length) {
return bzcompress(substr($data, 0, $length));
$output = @bzcompress(substr($data, 0, $length));
if(!is_string($output)) {
throw new InvalidInputDataException('The compression input data is invalid.', $output);
}
return $output;
}
/**
* {@inheritdoc}
*/
public function decompress($data, $length) {
return bzdecompress(substr($data, 0, $length));
$output = @bzdecompress(substr($data, 0, $length));
if(!is_string($output)) {
throw new InvalidInputDataException('The decompression input data is invalid.', $output);
}
return $output;
}
}

View File

@@ -29,9 +29,30 @@
namespace Rogiel\MPQ\Compression;
use Rogiel\MPQ\Exception\Compression\InvalidInputDataException;
interface Compression {
/**
* Compresses a block of data
*
* @param $data string the block of data to be compressed
* @param $length integer the length of the block to be compressed
* @return string the compressed data
*
* @throws InvalidInputDataException if the uncompressed data is invalid and cannot be compressed
*/
public function compress($data, $length);
/**
* Decompresses a block of data
*
* @param $data string the block of data to be decompressed
* @param $length integer the length of the block to be decompressed
* @return string the decompressed data
*
* @throws InvalidInputDataException if the compressed data is invalid and cannot be decompressed
*/
public function decompress($data, $length);
}

View File

@@ -29,14 +29,30 @@
namespace Rogiel\MPQ\Compression;
use Rogiel\MPQ\Exception\Compression\InvalidInputDataException;
class DeflateCompression implements Compression {
/**
* {@inheritdoc}
*/
public function compress($data, $length) {
return gzdeflate(substr($data, 0, $length));
$output = @gzdeflate(substr($data, 0, $length));
if(!is_string($output)) {
throw new InvalidInputDataException('The compression input data is invalid.', $output);
}
return $output;
}
/**
* {@inheritdoc}
*/
public function decompress($data, $length) {
return gzinflate($data, $length);
$output = @gzinflate(substr($data, 0, $length), $length);
if(!is_string($output)) {
throw new InvalidInputDataException('The decompression input data is invalid.', $output);
}
return $output;
}
}

View File

@@ -29,56 +29,96 @@
namespace Rogiel\MPQ\Encryption;
use Rogiel\MPQ\Exception\Encryption\InvalidBlockSizeException;
use Rogiel\MPQ\Exception\Encryption\InvalidKeyException;
use Rogiel\MPQ\Util\CryptoUtils;
class DefaultEncryption implements Encryption {
/**
* The encryption/decryption key
*
* @var string
*/
private $key;
/**
* The encryption/decryption seed
*
* @var string
*/
private $seed;
/**
* DefaultEncryption constructor.
* @param $key string the encryption key. The key must have exactly 10 bytes
*/
public function __construct($key) {
$this->key = $key;
$this->seed = ((0xEEEE << 16) | 0xEEEE);
CryptoUtils::initTable();
$this->reset($key);
}
/**
* {@inheritdoc}
*/
public function reset($key) {
if(strlen($key) != 10) {
throw new InvalidKeyException(sprintf('The key is expected to have 10 bytes, %i given.', strlen($key)));
}
$this->key = $key;
$this->seed = ((0xEEEE << 16) | 0xEEEE);
}
/**
* {@inheritdoc}
*/
public function decrypt($string, $length) {
if($length % 4 != 0) {
throw new InvalidBlockSizeException(sprintf('The block size is invalid. Input expected to be a multiple of 4, %s given', $length));
}
$data = $this->createBlockArray($string, $length);
$datalen = $length / 4;
for($i = 0;$i < $datalen;$i++) {
$blocks = $length / 4;
for($block = 0;$block < $blocks; $block++) {
$this->seed = CryptoUtils::uPlus($this->seed,CryptoUtils::$cryptTable[0x400 + ($this->key & 0xFF)]);
$ch = $data[$i] ^ (CryptoUtils::uPlus($this->key,$this->seed));
$ch = $data[$block] ^ (CryptoUtils::uPlus($this->key,$this->seed));
$this->key = (CryptoUtils::uPlus(((~$this->key) << 0x15), 0x11111111)) | (CryptoUtils::rShift($this->key,0x0B));
$this->seed = CryptoUtils::uPlus(CryptoUtils::uPlus(CryptoUtils::uPlus($ch,$this->seed),($this->seed << 5)),3);
$data[$i] = $ch & ((0xFFFF << 16) | 0xFFFF);
$data[$block] = $ch & ((0xFFFF << 16) | 0xFFFF);
}
return $this->createDataStream($data, $length / 4);
return $this->createDataStream($data, $length);
}
public function encrypt($data, $length) {
$key = clone $this->key;
$seed = ((0xEEEE << 16) | 0xEEEE);
$datalen = $length;
for($i = 0;$i < $datalen;$i++) {
$seed = CryptoUtils::uPlus($seed,CryptoUtils::$cryptTable[0x400 + ($key & 0xFF)]);
$ch = $data[$i] ^ (CryptoUtils::uPlus($key,$seed));
$key = (CryptoUtils::uPlus(((~$key) << 0x15), 0x11111111)) | (CryptoUtils::rShift($key,0x0B));
$seed = CryptoUtils::uPlus(CryptoUtils::uPlus(CryptoUtils::uPlus($data[$i],$seed),($seed << 5)),3);
$data[$i] = $ch & ((0xFFFF << 16) | 0xFFFF);
/**
* {@inheritdoc}
*/
public function encrypt($string, $length) {
if($length % 4 != 0) {
throw new InvalidBlockSizeException(sprintf('The block size is invalid. Input expected to be a multiple of 4, %s given', $length));
}
return $data;
$data = $this->createBlockArray($string, $length);
$blocks = $length / 4;
for($block = 0;$block < $blocks; $block++) {
$this->seed = CryptoUtils::uPlus($this->seed,CryptoUtils::$cryptTable[0x400 + ($this->key & 0xFF)]);
$ch = $data[$block] ^ (CryptoUtils::uPlus($this->key,$this->seed));
$this->key = (CryptoUtils::uPlus(((~$this->key) << 0x15), 0x11111111)) | (CryptoUtils::rShift($this->key,0x0B));
$this->seed = CryptoUtils::uPlus(CryptoUtils::uPlus(CryptoUtils::uPlus($data[$block],$this->seed),($this->seed << 5)),3);
$data[$block] = $ch & ((0xFFFF << 16) | 0xFFFF);
}
return $this->createDataStream($data, $length);
}
/**
* {@inheritdoc}
*/
public function getBlockSize() {
return 4;
}

View File

@@ -28,14 +28,47 @@
namespace Rogiel\MPQ\Encryption;
use Rogiel\MPQ\Exception\Encryption\InvalidBlockSizeException;
use Rogiel\MPQ\Exception\Encryption\InvalidKeyException;
interface Encryption {
/**
* Resets the encryption context
*
* @param $key string the new encryption key
*
* @throws InvalidKeyException if the given key is invalid
*/
public function reset($key);
/**
* Encrypts a block of data
*
* @param $data string the data block
* @param $length integer the data block size
* @return string the encrypted block
*
* @throws InvalidBlockSizeException if the block size is incorrect
*/
public function encrypt($data, $length);
/**
* Decrypts a block of data
*
* @param $data string the data block
* @param $length integer the data block size
* @return string the decrypted block
*
* @throws InvalidBlockSizeException if the block size is incorrect
*/
public function decrypt($data, $length);
/**
* Gets the cipher block size
*
* @return integer
*/
public function getBlockSize();
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright (c) 2016, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Rogiel\MPQ\Exception\Compression;
use Rogiel\MPQ\Exception\MPQException;
class CompressionException extends MPQException {
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright (c) 2016, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Rogiel\MPQ\Exception\Compression;
class InvalidInputDataException extends CompressionException {
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright (c) 2016, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Rogiel\MPQ\Exception\Encryption;
use Rogiel\MPQ\Exception\MPQException;
class EncryptionException extends MPQException {
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright (c) 2016, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Rogiel\MPQ\Exception\Encryption;
class InvalidBlockSizeException extends EncryptionException {
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright (c) 2016, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Rogiel\MPQ\Exception\Encryption;
class InvalidKeyException extends EncryptionException {
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright (c) 2016, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Rogiel\MPQ\Exception\Hashing;
use Rogiel\MPQ\Exception\MPQException;
class HashingException extends MPQException {
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright (c) 2016, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Rogiel\MPQ\Exception;
class MPQException extends \Exception {
}

View File

@@ -62,9 +62,6 @@ class Hash {
$hash->name1 = $parser->readUInt32();
$hash->name2 = $parser->readUInt32();
$hash->locale = $parser->readUInt16();
// echo $hash->locale;
// die();
$hash->platform = $parser->readUInt16();
$hash->blockIndex = $parser->readUInt32();