mirror of
https://github.com/Rogiel/star-map
synced 2025-12-06 07:12:51 +00:00
Initial commit
This commit is contained in:
51
README.md
Normal file
51
README.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Star Map
|
||||||
|
|
||||||
|
This library allows you to read StarCraft II map files from PHP.
|
||||||
|
|
||||||
|
A object-oriented API is provided to browse through the metadata and the minimap image.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
* Read .SC2Map files from all public game versions
|
||||||
|
* **Minimap**: Allows to read the embeded minimap image
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The recommended way of installing this library is using Composer.
|
||||||
|
|
||||||
|
composer require "rogiel/star-map"
|
||||||
|
|
||||||
|
This library uses [php-mpq](https://github.com/Rogiel/php-mpq) to parse and extract compressed information inside the map file.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Rogiel\StarMap\Map;
|
||||||
|
|
||||||
|
// Parse the map
|
||||||
|
$map = new Map('Ruins of Seras.SC2Map');
|
||||||
|
|
||||||
|
// Get the map name in multiple locales
|
||||||
|
$documentHeader = $map->getDocumentHeader();
|
||||||
|
|
||||||
|
echo sprintf('Map name (English): %s', $documentHeader->getName()).PHP_EOL; // english is default
|
||||||
|
echo sprintf('Map name (French): %s', $documentHeader->getName('frFR')).PHP_EOL;
|
||||||
|
|
||||||
|
// Get the map size
|
||||||
|
$mapInfo = $map->getMapInfo();
|
||||||
|
$x = $mapInfo->getWidth();
|
||||||
|
$y = $mapInfo->getHeight();
|
||||||
|
echo sprintf('Map size: %sx%s', $x, $y).PHP_EOL;
|
||||||
|
|
||||||
|
// Export Minimap image as a PNG
|
||||||
|
$map->getMinimap()->toPNG('Minimap.png');
|
||||||
|
```
|
||||||
|
|
||||||
|
The output to the snippet above is the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
Map name (English): Ruins of Seras
|
||||||
|
Map name (French): Ruines de Seras
|
||||||
|
Map size: 224x192
|
||||||
|
```
|
||||||
|
|
||||||
|
Have fun!
|
||||||
30
composer.json
Normal file
30
composer.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "rogiel/star-map",
|
||||||
|
"type": "library",
|
||||||
|
"description": "A StarCraft II map parser in PHP",
|
||||||
|
"keywords": ["StarCraft II", "Map parsing", "Gaming", "Blizzard"],
|
||||||
|
"homepage": "https://rogiel.com/portfolio/star-map",
|
||||||
|
"license": "BSD-2.0",
|
||||||
|
"authors": [{
|
||||||
|
"name": "Rogiel Sulzbach",
|
||||||
|
"email": "rogiel@rogiel.com",
|
||||||
|
"homepage": "https://rogiel.com"
|
||||||
|
}],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Rogiel\\StarMap\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Rogiel\\StarMap\\Tests\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.5",
|
||||||
|
"rogiel/mpq": "^0.2.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
105
src/Entity/DocumentHeader.php
Normal file
105
src/Entity/DocumentHeader.php
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PixForce
|
||||||
|
*
|
||||||
|
* @link http://www.pixforce.com.br/
|
||||||
|
* @copyright Copyright (c) 2016 PixForce (http://www.pixforce.com.br)
|
||||||
|
* @license Proprietary
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Rogiel\StarMap\Entity;
|
||||||
|
|
||||||
|
use Rogiel\MPQ\Stream\Parser\BinaryStreamParser;
|
||||||
|
|
||||||
|
class DocumentHeader {
|
||||||
|
|
||||||
|
const DEFAULT_LOCALE = 'enUS';
|
||||||
|
|
||||||
|
private $name = array();
|
||||||
|
private $shortDescription = array();
|
||||||
|
private $longDescription = array();
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public function __construct(BinaryStreamParser $parser) {
|
||||||
|
$parser->readBytes(44);
|
||||||
|
|
||||||
|
$numDeps = $parser->readByte();
|
||||||
|
$parser->readBytes(3);
|
||||||
|
while ($numDeps > 0) {
|
||||||
|
while ($parser->readByte() !== 0);
|
||||||
|
$numDeps--;
|
||||||
|
}
|
||||||
|
$numAttribs = $parser->readUInt32();
|
||||||
|
$attribs = array();
|
||||||
|
while ($numAttribs > 0) {
|
||||||
|
$keyLen = $parser->readUInt16();
|
||||||
|
$key = $parser->readBytes($keyLen);
|
||||||
|
$locale = hex2bin(dechex($parser->readUInt32()));
|
||||||
|
$valueLen = $parser->readUInt16();
|
||||||
|
$value = $parser->readBytes($valueLen);
|
||||||
|
$attribs[$key][$locale] = $value;
|
||||||
|
$numAttribs--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($attribs['DocInfo/Name'])) {
|
||||||
|
$this->name = $attribs['DocInfo/Name'];
|
||||||
|
}
|
||||||
|
if(isset($attribs['DocInfo/DescShort'])) {
|
||||||
|
$this->shortDescription = $attribs['DocInfo/DescShort'];
|
||||||
|
}
|
||||||
|
if(isset($attribs['DocInfo/DescLong'])) {
|
||||||
|
$this->longDescription = $attribs['DocInfo/DescLong'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function hasLocale($locale) {
|
||||||
|
return $this->getName($locale) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getLocales() {
|
||||||
|
return array_keys($this->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getName($locale = DocumentHeader::DEFAULT_LOCALE) {
|
||||||
|
if(isset($this->name[$locale])) {
|
||||||
|
return $this->name[$locale];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getShortDescription($locale = DocumentHeader::DEFAULT_LOCALE) {
|
||||||
|
if(isset($this->shortDescription[$locale])) {
|
||||||
|
return $this->shortDescription[$locale];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getLongDescription($locale = DocumentHeader::DEFAULT_LOCALE) {
|
||||||
|
if(isset($this->longDescription[$locale])) {
|
||||||
|
return $this->longDescription[$locale];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
527
src/Entity/MapInfo.php
Normal file
527
src/Entity/MapInfo.php
Normal file
@@ -0,0 +1,527 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PixForce
|
||||||
|
*
|
||||||
|
* @link http://www.pixforce.com.br/
|
||||||
|
* @copyright Copyright (c) 2016 PixForce (http://www.pixforce.com.br)
|
||||||
|
* @license Proprietary
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Rogiel\StarMap\Entity;
|
||||||
|
|
||||||
|
use Rogiel\MPQ\Stream\Parser\BinaryStreamParser;
|
||||||
|
use Rogiel\StarMap\Exception\MapException;
|
||||||
|
|
||||||
|
class MapInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The map info file format version
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $version;
|
||||||
|
private $unknown1;
|
||||||
|
private $unknown2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full map width
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full map height
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Small map preview type: 0 = None, 1 = Minimap, 2 = Custom
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $smallPreviewType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Optional) Small map preview path; relative to root of map archive
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $smallPreviewPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Large map preview type: 0 = None, 1 = Minimap, 2 = Custom
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $largePreviewType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Optional) Large map preview path; relative to root of map archive
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $largePreviewPath;
|
||||||
|
|
||||||
|
private $unknown3;
|
||||||
|
private $unknown4;
|
||||||
|
private $unknown5;
|
||||||
|
private $unknown6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of fog of war used on the map
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $fogType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tile set used on the map
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $tileSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The left bounds for the camera. This value is 7 less than the value shown in the editor.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $cameraLeft;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bottom bounds for the camera. This value is 4 less than the value shown in the editor.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $cameraBottom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The right bounds for the camera. This value is 7 more than the value shown in the editor.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $cameraRight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The top bounds for the camera. This value is 4 more than the value shown in the editor.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $cameraTop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The map base height (what is that?). This value is 4096*Base Height in the editor (giving a decimal value).
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $baseHeight;
|
||||||
|
|
||||||
|
// MIGHT NOT BE ACCURATE AFTER THIS
|
||||||
|
/**
|
||||||
|
* Load screen type: 0 = default, 1 = custom
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $loadScreenType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Optional) Load screen image path; relative to root of map archive
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $loadScreenPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unknown string, usually empty
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $unknown7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load screen image scaling strategy: 0 = normal, 1 = aspect scaling, 2 = stretch the image.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $loadScreenScaling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The text position on the loading screen. One of:
|
||||||
|
* 0xffffffff = (Default)
|
||||||
|
* 0 = Top Left
|
||||||
|
* 1 = Top
|
||||||
|
* 2 = Top Right
|
||||||
|
* 3 = Left
|
||||||
|
* 4 = Center
|
||||||
|
* 5 = Right
|
||||||
|
* 6 = Bottom Left
|
||||||
|
* 7 = Bottom
|
||||||
|
* 8 = Bottom Right
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $textPosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loading screen text position offset x
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $textPositionOffsetX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loading screen text position offset y
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $textPositionOffsetY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loading screen text size x
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $textPositionSizeX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loading screen text size y
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $textPositionSizeY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit array of flags with the following options (possibly incomplete)
|
||||||
|
*
|
||||||
|
* 0x00000001 = Disable Replay Recording
|
||||||
|
* 0x00000002 = Wait for Key (Loading Screen)
|
||||||
|
* 0x00000004 = Disable Trigger Preloading
|
||||||
|
* 0x00000008 = Enable Story Mode Preloading
|
||||||
|
* 0x00000010 = Use Horizontal Field of View
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $dataFlags;
|
||||||
|
|
||||||
|
private $unknown8;
|
||||||
|
private $unknown9;
|
||||||
|
private $unknown10;
|
||||||
|
private $unknown11;
|
||||||
|
|
||||||
|
public function __construct(BinaryStreamParser $parser) {
|
||||||
|
$magic = $parser->readBytes(4);
|
||||||
|
if($magic !== 'IpaM') {
|
||||||
|
throw new MapException('Invalid MapInfo magic header');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->version = $parser->readUInt32();
|
||||||
|
if ($this->version >= 0x18) {
|
||||||
|
$this->unknown1 = $parser->readUInt32();
|
||||||
|
$this->unknown2 = $parser->readUInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->width = $parser->readUInt32();
|
||||||
|
$this->height = $parser->readUInt32();
|
||||||
|
|
||||||
|
$this->smallPreviewType = $parser->readUInt32();
|
||||||
|
if ($this->smallPreviewType == 2) {
|
||||||
|
$this->smallPreviewPath = $parser->readCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->largePreviewType = $parser->readUInt32();
|
||||||
|
if ($this->largePreviewType == 2) {
|
||||||
|
$this->largePreviewPath = $parser->readCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->version >= 0x1f) {
|
||||||
|
$this->unknown3 = $parser->readCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->version >= 0x26) {
|
||||||
|
$this->unknown4 = $parser->readCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->version >= 0x1f) {
|
||||||
|
$this->unknown5 = $parser->readUInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->unknown6 = $parser->readUInt32();
|
||||||
|
$this->fogType = $parser->readCString();
|
||||||
|
$this->tileSet = $parser->readCString();
|
||||||
|
$this->cameraLeft = $parser->readUInt32();
|
||||||
|
$this->cameraBottom = $parser->readUInt32();
|
||||||
|
$this->cameraRight = $parser->readUInt32();
|
||||||
|
$this->cameraTop = $parser->readUInt32();
|
||||||
|
$this->baseHeight = $parser->readUInt32() / 4096;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$this->loadScreenType = $parser->readUInt32();
|
||||||
|
$this->loadScreenPath = $parser->readCString();
|
||||||
|
$this->unknown7 = $parser->readBytes($parser->readUInt16());
|
||||||
|
$this->loadScreenScaling = $parser->readUInt32();
|
||||||
|
$this->textPosition = $parser->readUInt32();
|
||||||
|
$this->textPositionOffsetX = $parser->readUInt32();
|
||||||
|
$this->textPositionOffsetY = $parser->readUInt32();
|
||||||
|
$this->textPositionSizeX = $parser->readUInt32();
|
||||||
|
$this->textPositionSizeY = $parser->readUInt32();
|
||||||
|
$this->dataFlags = $parser->readUInt32();
|
||||||
|
$this->unknown8 = $parser->readUInt32();
|
||||||
|
|
||||||
|
if ($this->version >= 0x19) {
|
||||||
|
$this->unknown9 = $parser->readBytes(8);
|
||||||
|
}
|
||||||
|
if ($this->version >= 0x1f) {
|
||||||
|
$this->unknown10 = $parser->readBytes(9);
|
||||||
|
}
|
||||||
|
if ($this->version >= 0x20) {
|
||||||
|
$this->unknown11 = $parser->readBytes(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// there are more fields, but the implementation of them have been ommited
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getVersion() {
|
||||||
|
return $this->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getUnknown1() {
|
||||||
|
return $this->unknown1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getUnknown2() {
|
||||||
|
return $this->unknown2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getWidth() {
|
||||||
|
return $this->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getHeight() {
|
||||||
|
return $this->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getSmallPreviewType() {
|
||||||
|
return $this->smallPreviewType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSmallPreviewPath() {
|
||||||
|
return $this->smallPreviewPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLargePreviewType() {
|
||||||
|
return $this->largePreviewType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLargePreviewPath() {
|
||||||
|
return $this->largePreviewPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUnknown3() {
|
||||||
|
return $this->unknown3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUnknown4() {
|
||||||
|
return $this->unknown4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getUnknown5() {
|
||||||
|
return $this->unknown5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getUnknown6() {
|
||||||
|
return $this->unknown6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFogType() {
|
||||||
|
return $this->fogType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTileSet() {
|
||||||
|
return $this->tileSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCameraLeft() {
|
||||||
|
return $this->cameraLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCameraBottom() {
|
||||||
|
return $this->cameraBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCameraRight() {
|
||||||
|
return $this->cameraRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCameraTop() {
|
||||||
|
return $this->cameraTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getBaseHeight() {
|
||||||
|
return $this->baseHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLoadScreenType() {
|
||||||
|
return $this->loadScreenType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLoadScreenPath() {
|
||||||
|
return $this->loadScreenPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUnknown7() {
|
||||||
|
return $this->unknown7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLoadScreenScaling() {
|
||||||
|
return $this->loadScreenScaling;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTextPosition() {
|
||||||
|
return $this->textPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTextPositionOffsetX() {
|
||||||
|
return $this->textPositionOffsetX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTextPositionOffsetY() {
|
||||||
|
return $this->textPositionOffsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTextPositionSizeX() {
|
||||||
|
return $this->textPositionSizeX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTextPositionSizeY() {
|
||||||
|
return $this->textPositionSizeY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getDataFlags() {
|
||||||
|
return $this->dataFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getUnknown8() {
|
||||||
|
return $this->unknown8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUnknown9() {
|
||||||
|
return $this->unknown9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUnknown10() {
|
||||||
|
return $this->unknown10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUnknown11() {
|
||||||
|
return $this->unknown11;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
99
src/Entity/Minimap.php
Normal file
99
src/Entity/Minimap.php
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PixForce
|
||||||
|
*
|
||||||
|
* @link http://www.pixforce.com.br/
|
||||||
|
* @copyright Copyright (c) 2016 PixForce (http://www.pixforce.com.br)
|
||||||
|
* @license Proprietary
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Rogiel\StarMap\Entity;
|
||||||
|
|
||||||
|
use Rogiel\MPQ\Stream\Block\BlockStream;
|
||||||
|
use Rogiel\MPQ\Stream\Parser\BinaryStreamParser;
|
||||||
|
use Rogiel\MPQ\Stream\Stream;
|
||||||
|
use Rogiel\StarMap\Exception\MapException;
|
||||||
|
|
||||||
|
class Minimap {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var resource
|
||||||
|
*/
|
||||||
|
private $resource;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public function __construct(Stream $stream) {
|
||||||
|
$buffer = '';
|
||||||
|
while (($read = $stream->readBytes(10240))) {
|
||||||
|
$buffer .= $read;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->resource = self::createImageResourceFromTGA($buffer);
|
||||||
|
$buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
function __destruct() {
|
||||||
|
imagedestroy($this->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filename
|
||||||
|
* @param int $compressionLevel
|
||||||
|
* @param int $filters see imagepng documentation for details on this field
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function toPNG($filename, $compressionLevel = 0, $filters = 0) {
|
||||||
|
return imagepng($this->resource, $filename, $compressionLevel, $filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filename
|
||||||
|
* @param int $quality
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function toJPG($filename, $quality = 75) {
|
||||||
|
return imagejpeg($this->resource, $filename, $quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $data
|
||||||
|
* @param int $return_array
|
||||||
|
*
|
||||||
|
* @return array|resource
|
||||||
|
*/
|
||||||
|
private static function createImageResourceFromTGA($data, $return_array = 0) {
|
||||||
|
$pointer = 18;
|
||||||
|
$x = 0;
|
||||||
|
$y = 0;
|
||||||
|
$w = base_convert(bin2hex(strrev(substr($data, 12, 2))), 16, 10);
|
||||||
|
$h = base_convert(bin2hex(strrev(substr($data, 14, 2))), 16, 10);
|
||||||
|
$img = imagecreatetruecolor($w, $h);
|
||||||
|
|
||||||
|
while ($pointer < strlen($data)) {
|
||||||
|
imagesetpixel($img, $x, $y, base_convert(bin2hex(strrev(substr($data, $pointer, 3))), 16, 10));
|
||||||
|
$x++;
|
||||||
|
|
||||||
|
if ($x == $w) {
|
||||||
|
$y++;
|
||||||
|
$x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pointer += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($return_array)
|
||||||
|
return array($img, $w, $h);
|
||||||
|
else
|
||||||
|
return $img;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
34
src/Exception/MapException.php
Normal file
34
src/Exception/MapException.php
Normal 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\StarMap\Exception;
|
||||||
|
|
||||||
|
|
||||||
|
class MapException extends \Exception {
|
||||||
|
|
||||||
|
}
|
||||||
132
src/Map.php
Normal file
132
src/Map.php
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PixForce
|
||||||
|
*
|
||||||
|
* @link http://www.pixforce.com.br/
|
||||||
|
* @copyright Copyright (c) 2016 PixForce (http://www.pixforce.com.br)
|
||||||
|
* @license Proprietary
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Rogiel\StarMap;
|
||||||
|
|
||||||
|
use Rogiel\MPQ\MPQFile;
|
||||||
|
use Rogiel\MPQ\Stream\Parser\BinaryStreamParser;
|
||||||
|
use Rogiel\StarMap\Entity\DocumentHeader;
|
||||||
|
use Rogiel\StarMap\Entity\MapInfo;
|
||||||
|
use Rogiel\StarMap\Entity\Minimap;
|
||||||
|
use Rogiel\StarMap\Exception\MapException;
|
||||||
|
|
||||||
|
class Map {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MPQFile
|
||||||
|
*/
|
||||||
|
private $file;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The processed MapInfo file
|
||||||
|
*
|
||||||
|
* @var MapInfo
|
||||||
|
*/
|
||||||
|
private $mapInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The processed DocumentHeader file
|
||||||
|
*
|
||||||
|
* @var DocumentHeader
|
||||||
|
*/
|
||||||
|
private $documentHeader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The processed Minimap file
|
||||||
|
*
|
||||||
|
* @var Minimap
|
||||||
|
*/
|
||||||
|
private $minimap;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map constructor.
|
||||||
|
* @param $file string|MPQFile the map file name or MPQFile instance
|
||||||
|
* @throws MapException if the file given is not a string or a mpq file
|
||||||
|
*/
|
||||||
|
public function __construct($file) {
|
||||||
|
if(is_string($file)) {
|
||||||
|
$file = MPQFile::parseFile($file);
|
||||||
|
}
|
||||||
|
if(!$file instanceof MPQFile) {
|
||||||
|
throw new MapException("Invalid map file given");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->file = $file;
|
||||||
|
$this->file->parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MapInfo parsed structure
|
||||||
|
*
|
||||||
|
* @return MapInfo
|
||||||
|
* @throws MapException
|
||||||
|
*/
|
||||||
|
public function getMapInfo() {
|
||||||
|
if($this->mapInfo != NULL) {
|
||||||
|
return $this->mapInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream = $this->file->openStream('MapInfo');
|
||||||
|
if($stream == NULL) {
|
||||||
|
throw new MapException("MapInfo file not found on map MPQ file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$parser = new BinaryStreamParser($stream);
|
||||||
|
$this->mapInfo = new MapInfo($parser);
|
||||||
|
return $this->mapInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MapInfo parsed structure
|
||||||
|
*
|
||||||
|
* @return DocumentHeader
|
||||||
|
* @throws MapException
|
||||||
|
*/
|
||||||
|
public function getDocumentHeader($locale = 'enUS') {
|
||||||
|
if($this->documentHeader != NULL) {
|
||||||
|
return $this->documentHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream = $this->file->openStream('DocumentHeader');
|
||||||
|
if($stream == NULL) {
|
||||||
|
throw new MapException("DocumentHeader file not found on map MPQ file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$parser = new BinaryStreamParser($stream);
|
||||||
|
$this->documentHeader = new DocumentHeader($parser);
|
||||||
|
return $this->documentHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Minimap
|
||||||
|
* @throws MapException
|
||||||
|
*/
|
||||||
|
public function getMinimap() {
|
||||||
|
if($this->minimap != NULL) {
|
||||||
|
return $this->minimap;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream = $this->file->openStream('Minimap.tga');
|
||||||
|
if($stream == NULL) {
|
||||||
|
throw new MapException("Minimap.tga file not found on map MPQ file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->minimap = new Minimap($stream);
|
||||||
|
return $this->minimap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user