diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index c025c2c..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,6 +0,0 @@ -CHANGELOG - -v1.0 -- Stable version release -- Changelog added -- Added DBC::VERSION diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..55d8ec2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +### v1.2 - May 16, 2013 +- Allow adding nulls to records (thanks Steff!) +- Ensure string-block is always written preventing DBC corruption (thanks Sigmur!) + +### v1.1 - April 8, 2013 +- Fixed rule count bug when explicitly defining count of one +- Fixed dealing with sequential string mappings (thanks Artox!) +- Ensure empty field mappings default to unsigned integer +- `DBCRecord.get` and `DBCRecord.set` now use mappings correctly (thanks Artox!) +- Implemented `DBCMap::getFieldType` + +### v1.0 - August 5, 2011 +- Stable version release +- Changelog added +- Added DBC::VERSION diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 7d33f55..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) 2011 Tim Kurvers - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..de51ffe --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,24 @@ +# License + +Licensed under the **MIT** license + +> Copyright (c) 2011-2013 Tim Kurvers <> +> +> Permission is hereby granted, free of charge, to any person obtaining +> a copy of this software and associated documentation files (the +> "Software"), to deal in the Software without restriction, including +> without limitation the rights to use, copy, modify, merge, publish, +> distribute, sublicense, and/or sell copies of the Software, and to +> permit persons to whom the Software is furnished to do so, subject to +> the following conditions: +> +> The above copyright notice and this permission notice shall be +> included in all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 9ac17b0..aba5c83 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,24 @@ -World of Warcraft DBC Library -============================= +# World of Warcraft DBC Library -Copyright (c) 2011 Tim Kurvers +![Unmaintained](https://img.shields.io/badge/%E2%9A%A0-unmaintained-red.svg?style=flat) -This library allows creation, reading and export of World of Warcraft's -client-side database files. These so-called DBCs store information -required by the client to operate successfully and can be extracted -from the MPQ archives of the actual game client. +This library allows creation, reading and export of World of Warcraft's +client-side database files. + +These so-called DBCs store information required by the client and can be +extracted from the MPQ archives of the actual game client. **Required PHP version: 5.x** Licensed under the **MIT** license, see LICENSE for more information. +## Getting Started -Getting Started ---------------- - -Will be adding a quick-start quide soon. - +Check out the `examples` to get started. -Usage Notes ------------ +## Usage Notes -* String localization will only provide accurate results when used with -the US English (enUS) or British English (enGB) distributed DBCs. +- String localization will only provide accurate results when used with US + English (enUS) or British English (enGB) distributed DBCs. -* Attempting to read DBCs with a non-standard field size, **may fail**. +- Attempting to read DBCs with a non-standard field size, **may fail**. diff --git a/examples/api.php b/examples/api.php index 74771b6..4b15745 100644 --- a/examples/api.php +++ b/examples/api.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ diff --git a/examples/creation.php b/examples/creation.php index 388196c..de3ce97 100644 --- a/examples/creation.php +++ b/examples/creation.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ diff --git a/examples/edit.php b/examples/edit.php index a08a9cd..09f1cd8 100644 --- a/examples/edit.php +++ b/examples/edit.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ diff --git a/examples/export.database.php b/examples/export.database.php index 3d4168e..e6f1f2e 100644 --- a/examples/export.database.php +++ b/examples/export.database.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -39,7 +39,7 @@ // And instruct it to export the given DBC to the default table 'dbc' (ensure the DBC has an attached map) $dbe->export($dbc); -// Alternatively supports exporting to a file by providing a second argument +// Alternatively supports exporting to a file by providing a second argument $dbe->export($dbc, './export/sample.sql'); // If you would rather export to a specific table, pass in a third parameter diff --git a/examples/export.json.php b/examples/export.json.php index a472cda..5ae93c2 100644 --- a/examples/export.json.php +++ b/examples/export.json.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -42,5 +42,5 @@ // And instruct it to export the given DBC (ensure the DBC has an attached map) $json->export($dbc); -// Alternatively supports exporting to a file by providing a second argument +// Alternatively supports exporting to a file by providing a second argument $json->export($dbc, './export/sample.json'); diff --git a/examples/export.xml.php b/examples/export.xml.php index dcf269f..aca7995 100644 --- a/examples/export.xml.php +++ b/examples/export.xml.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ diff --git a/examples/export/sample.sql b/examples/export/sample.sql index 133a517..96dafd2 100644 --- a/examples/export/sample.sql +++ b/examples/export/sample.sql @@ -1,16 +1,16 @@ DROP TABLE IF EXISTS `my_table`; CREATE TABLE `my_table` ( - `id` INT(11) UNSIGNED NOT NULL, - `name` TEXT NOT NULL, - `points` INT(11) SIGNED NOT NULL, - `height` FLOAT NOT NULL, - `friend1` INT(11) SIGNED NOT NULL, - `friend2` INT(11) SIGNED NOT NULL, - PRIMARY KEY (`id`) + `id` INT(11) UNSIGNED NOT NULL, + `name` TEXT NULL, + `points` INT(11) SIGNED NOT NULL, + `height` FLOAT NOT NULL, + `friend1` INT(11) SIGNED NOT NULL, + `friend2` INT(11) SIGNED NOT NULL, + PRIMARY KEY (`id`) ); -INSERT INTO `my_table` VALUES +INSERT INTO `my_table` VALUES (1, 'John', 100, 1.79999995232, 2, 0), (2, 'Tim', 1337, 1.79999995232, 1, 0), (3, 'Pete', -10, 1.54999995232, 1, 2), @@ -19,4 +19,3 @@ INSERT INTO `my_table` VALUES (4, 'Helen', 100, 1.79999995232, 0, 0), (8, 'Frank', 1337, 1.73000001907, 0, 0), (10, 'Brad', -10, 1.54999995232, 0, 0); - diff --git a/examples/mappings.detect.php b/examples/mappings.detect.php index 83deab3..1fffb6d 100644 --- a/examples/mappings.detect.php +++ b/examples/mappings.detect.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ diff --git a/examples/mappings.php b/examples/mappings.php index 839b3f9..be440a3 100644 --- a/examples/mappings.php +++ b/examples/mappings.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -37,7 +37,7 @@ $map->add('id'); // Add 'name' as a string field (Use DBC::STRING_LOC for a localized string) -$map->add('name', DBC::STRING_LOC); +$map->add('name', DBC::STRING); // Add 'points' as a signed integer field $map->add('points', DBC::INT); @@ -58,3 +58,18 @@ // Write the mappings to given INI-file $map->toINI('./maps/Sample.ini'); + +// Open the given DBC (ensure read-access) with the aforementioned map +$dbc = new DBC('./dbcs/Sample.dbc', $map); + +// Reference to the first record +$record = $dbc->getRecord(0); + +// Getting name as a string according to mapping +echo $record->get('name'); + +// Getting height as a float according to mapping +echo $record->get('height'); + +// Setting height as a float according to mapping +$record->set('height', 1.80); diff --git a/lib/DBC.class.php b/lib/DBC.class.php index 3af47f1..cef936a 100644 --- a/lib/DBC.class.php +++ b/lib/DBC.class.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -26,112 +26,112 @@ * Represents a World of Warcraft DBC */ class DBC implements IteratorAggregate { - + /** * Version of the World of Warcraft DBC Library */ - const VERSION = 'v1.0'; - + const VERSION = 'v1.2'; + /** * Defines signature for a DBC file */ const SIGNATURE = 'WDBC'; - + /** - * Defines the size of the header in bytes + * Defines the size of the header in bytes */ const HEADER_SIZE = 20; - + /** * Defines the field size in bytes */ const FIELD_SIZE = 4; - + /** * Convenience NULL-byte constant */ const NULL_BYTE = "\0"; - + /** * Denotes an unsigned integer field type */ const UINT = 'L'; - + /** * Denotes a signed integer field type */ const INT = 'l'; - + /** * Denotes a float field type */ const FLOAT = 'f'; - + /** * Denotes a string field type */ const STRING = 's'; - + /** * Denotes a localized string field type */ const STRING_LOC = 'sl'; - + /** * Number of localization string fields */ const LOCALIZATION = 16; - + /** * Holds a reference to this DBC on disk */ private $_handle = null; - + /** * Holds path to this DBC on disk */ private $_path = null; - + /** * Represents the index for the records in this DBC paired by ID/position */ private $_index = null; - + /** * Amount of records in this DBC */ private $_recordCount = 0; - + /** * Record size in bytes */ private $_recordSize = 0; - + /** * Amount of fields in this DBC */ private $_fieldCount = 0; - + /** * Reference to the attached map (if any) */ private $_map = null; - + /** * String-block contains all strings defined in the DBC file */ private $_stringBlock = self::NULL_BYTE; - + /** * Size of the string-block */ private $_stringBlockSize = 1; - + /** * Whether this DBC is writable (enables adding records and strings) */ private $_writable = true; - + /** * Constructs a new DBC instance from given path with an optional DBCMap to attach as the default */ @@ -140,9 +140,9 @@ public function __construct($path, DBCMap $map=null) { throw new DBCException('DBC "'.$path.'" could not be found'); return; } - + $this->_path = $path; - + $this->_handle = @fopen($path, 'r+b'); if(!$this->_handle) { $this->_handle = @fopen($path, 'rb'); @@ -153,7 +153,7 @@ public function __construct($path, DBCMap $map=null) { } } $size = filesize($path); - + $sig = fread($this->_handle, 4); if($sig !== self::SIGNATURE) { throw new DBCException('DBC "'.$path.'" has an invalid signature and is therefore not valid'); @@ -163,23 +163,23 @@ public function __construct($path, DBCMap $map=null) { throw new DBCException('DBC "'.$path.'" has a malformed header'); return; } - + list(, $this->_recordCount, $this->_fieldCount, $this->_recordSize, $this->_stringBlockSize) = unpack(self::UINT.'4', fread($this->_handle, 16)); - + $offset = self::HEADER_SIZE + $this->_recordCount * $this->_recordSize; - + if($size < $offset) { throw new DBCException('DBC "'.$path.'" is short of '.($offset - $size).' bytes for '.$this->_recordCount.' records'); return; } fseek($this->_handle, $offset); - + if($size < $offset + $this->_stringBlockSize) { throw new DBCException('DBC "'.$path.'" is short of '.($offset + $this->_stringBlockSize - $size).' bytes for string-block'); return; } $this->_stringBlock = fread($this->_handle, $this->_stringBlockSize); - + $this->attach($map); } @@ -196,7 +196,7 @@ public function __destruct() { $this->_map = null; $this->_stringBlock = null; } - + /** * Finalizes this writable DBC, updating its header and writing the string block */ @@ -205,14 +205,14 @@ public function finalize() { if($this->_handle !== null && $this->_writable && $this->_stringBlockSize !== $size) { fseek($this->_handle, self::HEADER_SIZE + $this->_recordCount * $this->_recordSize); fwrite($this->_handle, $this->_stringBlock); - + $this->_stringBlockSize = $size; - + fseek($this->_handle, 16); fwrite($this->_handle, pack(self::UINT, $this->_stringBlockSize)); } } - + /** * Attaches a mapping */ @@ -228,7 +228,7 @@ public function attach(DBCMap $map=null) { } return $this; } - + /** * Generates an index of this DBC consisting of ID/position pairs and optionally updates given ID to given position */ @@ -251,7 +251,7 @@ public function index($id=null, $position=null) { } return $this; } - + /** * Adds a set of scalar values as a record or adds given arrays as records (nesting is allowed) */ @@ -260,12 +260,12 @@ public function add() { throw new DBCException('Adding records requires DBC "'.$this->_path.'" to be writable and have a valid mapping attached'); return $this; } - + $args = func_get_args(); if(isset($args[0])) { $scalars = true; foreach($args as $arg) { - if($scalars && !is_scalar($arg)) { + if(!is_null($arg) && !is_scalar($arg)) { $scalars = false; } if(is_array($arg)) { @@ -278,15 +278,15 @@ public function add() { } return $this; } - + /** * Adds the given record of scalar values to the DBC being created */ private function _add(array $record) { $fields = $this->_map->getFields(); - + fseek($this->_handle, self::HEADER_SIZE + $this->_recordCount * $this->_recordSize); - + foreach($fields as $name=>$rule) { $count = max($rule & 0xFF, 1); for($i=0; $i<$count; $i++) { @@ -309,46 +309,50 @@ private function _add(array $record) { } } } - + fseek($this->_handle, 4); fwrite($this->_handle, pack(self::UINT, ++$this->_recordCount)); + + // New record data may have overwritten the string-block + // Invalidate its size to enforce writing it on finalization + $this->_stringBlockSize = 0; } - + /** * Whether this DBC is writable */ public function isWritable() { return ($this->_handle !== null && $this->_writable); } - + /** * Returns the handle to the DBC on disk */ public function getHandle() { return $this->_handle; } - + /** * Returns the path to the DBC on disk */ public function getPath() { return $this->_path; } - + /** * Returns the amount of records in this DBC */ public function getRecordCount() { return $this->_recordCount; } - + /** * Returns the size of each record in bytes - */ + */ public function getRecordSize() { return $this->_recordSize; } - + /** * Fetches a record by zero-based position (if any) */ @@ -358,7 +362,7 @@ public function getRecord($pos) { } return null; } - + /** * Fetches a record by ID (first field) and will ensure the index has been generated */ @@ -371,14 +375,14 @@ public function getRecordByID($id) { } return null; } - + /** * Whether this DBC has a record at the given zero-based position */ public function hasRecord($pos) { return ($pos >= 0 && $pos < $this->_recordCount); } - + /** * Whether this DBC has a record identified by given ID (first field) */ @@ -388,35 +392,35 @@ public function hasRecordByID($id) { } return (isset($this->_index[$id])); } - + /** * Returns the amount of fields in this DBC */ public function getFieldCount() { return $this->_fieldCount; } - + /** * Whether the field given by the zero-based offset exists in this DBC */ public function hasField($field) { return ($field >= 0 && $field < $this->_fieldCount); } - + /** * Returns the map attached to this DBC (if any) */ public function getMap() { return $this->_map; } - + /** * Generates a new iterator to iterate over the records in this DBC */ public function getIterator() { return new DBCIterator($this); } - + /** * Returns the string found in the string-block given by the offset in bytes (if any) */ @@ -427,7 +431,7 @@ public function getString($offset) { $length = strpos($this->_stringBlock, self::NULL_BYTE, $offset) - $offset; return substr($this->_stringBlock, $offset, $length); } - + /** * Adds a string to the string-block and returns the offset in bytes */ @@ -440,14 +444,14 @@ public function addString($string) { $this->_stringBlock .= $string.self::NULL_BYTE; return $offset; } - + /** * Returns the entire string-block */ public function getStringBlock() { return $this->_stringBlock; } - + /** * Creates an empty DBC using the given mapping (will overwrite any existing DBCs) */ @@ -457,20 +461,20 @@ public static function create($file, $count) { throw new DBCException('New DBC "'.$file.'" could not be created/opened for writing'); return null; } - + $map = null; if($count instanceof DBCMap) { $map = $count; - $count = $map->getFieldCount(); + $count = $map->getFieldCount(); } - + fwrite($handle, self::SIGNATURE); fwrite($handle, pack(self::UINT.'4', 0, $count, $count * self::FIELD_SIZE, 1)); fwrite($handle, self::NULL_BYTE); fclose($handle); - + $dbc = new self($file, $map); return $dbc; } - + } diff --git a/lib/DBCException.class.php b/lib/DBCException.class.php index ecfca0f..36ebb70 100644 --- a/lib/DBCException.class.php +++ b/lib/DBCException.class.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -26,7 +26,5 @@ * Dummy exception thrown by DBC library components */ class DBCException extends Exception { - - - + } diff --git a/lib/DBCExporter.interface.php b/lib/DBCExporter.interface.php index c565d8d..30ca07d 100644 --- a/lib/DBCExporter.interface.php +++ b/lib/DBCExporter.interface.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -26,17 +26,17 @@ * Denotes a DBC exporter */ interface IDBCExporter { - + /** * Denotes the standard PHP output stream (default export target) */ const OUTPUT = 'php://output'; - + /** * Exception message when DBC has no mapping attached */ const NO_MAP = 'Given DBC has no map attached'; - + /** * Exports the given DBC using this exporter to the given target(-stream) */ diff --git a/lib/DBCIterator.class.php b/lib/DBCIterator.class.php index 22f9eee..2caa7cb 100644 --- a/lib/DBCIterator.class.php +++ b/lib/DBCIterator.class.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -26,78 +26,78 @@ * Allows iteration over DBC records */ class DBCIterator implements Iterator { - + /** * Holds a reference to the DBC being iterated */ private $_dbc = null; - + /** * Current position in the DBC */ private $_pos = 0; - + /** * Constructs a new iterator for given DBC */ public function __construct(DBC $dbc) { $this->_dbc = $dbc; } - + /** * Destructs this iterator */ public function __destruct() { $this->_dbc = null; } - + /** * Rewinds the position */ public function rewind() { $this->_pos = 0; } - + /** * Returns the record at the current position (if any) */ public function current() { return $this->_dbc->getRecord($this->_pos); } - + /** * Returns the current position */ public function key() { return $this->_pos; } - + /** * Advances the position */ public function next() { $this->_pos++; } - + /** * Retracts the position */ public function prev() { $this->_pos--; } - + /** * Seeks to given position */ public function seek($pos) { $this->_pos = $pos; } - + /** * Whether the DBC has a record at the current position */ public function valid() { return $this->_dbc->hasRecord($this->_pos); } - + } diff --git a/lib/DBCMap.class.php b/lib/DBCMap.class.php index 45d3d83..cc225d8 100644 --- a/lib/DBCMap.class.php +++ b/lib/DBCMap.class.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -35,82 +35,82 @@ * Mapping of fields for a DBC */ class DBCMap { - + /** * Unsigned integer bit mask */ const UINT_MASK = 0x0100; - + /** * Signed integer bit mask */ const INT_MASK = 0x0200; - + /** * Float bit mask */ const FLOAT_MASK = 0x0400; - + /** * String bit mask */ const STRING_MASK = 0x0800; - + /** * Localized string bit mask */ const STRING_LOC_MASK = 0x1000; - + /** * Sample count */ const SAMPLES = 255; - + /** * Holds all fields defined in this mapping in name/rule pairs */ private $_fields = null; - + /** * Actual number of raw fields in this mapping */ private $_count = 0; - + /** * Constructs a new mapping (with optional given fields) */ public function __construct(array $fields=null) { $this->_fields = ($fields !== null) ? $fields : array(); foreach($this->_fields as $field=>&$rule) { - if($rule === null) { + if(!$rule) { $rule = self::UINT_MASK; } $rule = (int)$rule; $this->_count += self::countInBitmask($rule); } } - + /** * Destructs this mapping */ public function __destruct() { - $this->_fields = null; + $this->_fields = null; } - + /** * Returns the set of fields currently in this mapping */ public function getFields() { return $this->_fields; } - + /** * Returns the actual amount of fields required in the DBC */ public function getFieldCount() { return $this->_count; } - + /** * Returns the actual offset for given field */ @@ -122,13 +122,13 @@ public function getFieldOffset($field) { $suffix = (int)$suffix - 1; } } - + if(!isset($this->_fields[$field])) { return -1; } - + $target = $field; - + $offset = 0; foreach($this->_fields as $field=>$rule) { if($target === $field) { @@ -139,7 +139,32 @@ public function getFieldOffset($field) { } return -1; } - + + /** + * Returns type for given field offset + */ + public function getFieldType($field) { + + if(!isset($this->_fields[$field])) { + if(preg_match('#(.+?)\d+?$#', $field, $match) === 1) { + list(, $field) = $match; + } + } + + $rule = $this->_fields[$field]; + if($rule & self::INT_MASK) { + return DBC::INT; + }else if($rule & self::FLOAT_MASK) { + return DBC::FLOAT; + }else if($rule & self::STRING_MASK) { + return DBC::STRING; + }else if($rule & self::STRING_LOC_MASK) { + return DBC::STRING_LOC; + }else{ + return DBC::UINT; + } + } + /** * Adds a field using given type and count */ @@ -162,14 +187,14 @@ public function add($field, $type=DBC::UINT, $count=0) { $this->_count += self::countInBitmask($bitmask); $this->_fields[$field] = $bitmask; } - + /** * Whether given field exists in this mapping */ public function exists($field) { return (isset($this->_fields[$field])); } - + /** * Removes given field from the mapping provided it exists */ @@ -179,14 +204,14 @@ public function remove($field) { unset($this->_fields[$field]); } } - + /** * Exports this mapping in INI-format to given target (defaults to output stream) with given tab width in spaces */ public function toINI($target=IDBCExporter::OUTPUT, $tabWidth=4) { $maxlen = max(array_map('strlen', array_keys($this->_fields))); $spaces = ceil($maxlen / $tabWidth) * $tabWidth; - + $handle = fopen($target, 'w+'); foreach($this->_fields as $field=>$bitmask) { $line = $field; @@ -209,12 +234,12 @@ public function toINI($target=IDBCExporter::OUTPUT, $tabWidth=4) { $line .= ' | '.$count; } $line .= PHP_EOL; - + fwrite($handle, $line); } fclose($handle); } - + /** * Calculates the number of fields used up by the given bitmask */ @@ -225,22 +250,22 @@ public static function countInBitmask($bitmask, $upTo=PHP_INT_MAX) { } return $count; } - + /** * Constructs a new mapping from given INI-file */ public static function fromINI($ini) { return new self(parse_ini_file($ini)); } - + /** * Attempts to construct a map based on given DBC, predicting what each field could possibly hold by way of sampling */ public static function fromDBC(DBC $dbc, $attach=true) { - + $fields = $dbc->getFieldCount(); $samples = ($dbc->getRecordCount() > self::SAMPLES) ? self::SAMPLES : $dbc->getRecordCount(); - + $block = $dbc->getStringBlock(); preg_match_all('#\0#', $block, $matches, PREG_OFFSET_CAPTURE); $strings = array(); @@ -250,9 +275,9 @@ public static function fromDBC(DBC $dbc, $attach=true) { $strings[$offset] = true; } } - + $matrix = array_fill(1, $fields, 0); - + for($i=0; $i<$samples; $i++) { $record = $dbc->getRecord($i); $values = $record->asArray(); @@ -271,9 +296,9 @@ public static function fromDBC(DBC $dbc, $attach=true) { } } } - + $map = new self(); - + for($i=1; $i<=$fields; $i++) { $probs = $matrix[$i]; $int = ($probs & 0x000000FF) / $samples; @@ -306,14 +331,14 @@ public static function fromDBC(DBC $dbc, $attach=true) { } $map->add($field, $type); } - + if($attach && $dbc->getMap() === null) { $dbc->attach($map); } - + return $map; } - + /** * Whether given set of bits is a probable IEEE-754 single precision floating point number * @see http://stackoverflow.com/questions/2485388/heuristic-to-identify-if-a-series-of-4-bytes-chunks-of-data-are-integers-or-float/2953466#2953466 @@ -322,7 +347,7 @@ public static function isProbableFloat($bits) { $sign = ($bits & 0x80000000) != 0; $exp = (($bits & 0x7F800000) >> 23) - 127; $mant = $bits & 0x007FFFFF; - + if(-30 <= $exp && $exp <= 30) { return true; } @@ -331,5 +356,5 @@ public static function isProbableFloat($bits) { } return false; } - + } diff --git a/lib/DBCRecord.class.php b/lib/DBCRecord.class.php index f94f776..704d6d4 100644 --- a/lib/DBCRecord.class.php +++ b/lib/DBCRecord.class.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -26,48 +26,48 @@ * Represents a single record in a DBC */ class DBCRecord { - + /** * Identifier (first field) for this record (if any) */ private $_id = null; - + /** * Position of this record in the DBC */ private $_pos = 0; - + /** * Offset of this record in the DBC in bytes */ private $_offset = 0; - + /** * Data contained in this record in a byte-string */ private $_data = null; - + /** * Reference to the associated DBC */ private $_dbc = null; - + /** * Constructs a new record found at the given zero-based position in the associated DBC */ public function __construct(DBC $dbc, $pos) { $this->_dbc = $dbc; $this->_pos = $pos; - + $this->_offset = DBC::HEADER_SIZE + $pos * $dbc->getRecordSize(); - + $handle = $dbc->getHandle(); fseek($handle, $this->_offset); if($dbc->getRecordSize() > 0) { $this->_data = fread($handle, $dbc->getRecordSize()); } } - + /** * Destructs this record */ @@ -76,7 +76,7 @@ public function __destruct() { $this->_data = null; $this->_dbc = null; } - + /** * Extracts all data from this record using mappings in either the given or default DBCMap */ @@ -100,13 +100,26 @@ public function extract(DBCMap $map=null) { $format[] = DBC::FLOAT.$count.$name; }else if($rule & DBCMap::STRING_MASK) { $format[] = DBC::UINT.$count.$name; - $strings[] = $name; + if($count > 1) { + for($i=1; $i<=$count; $i++) { + $strings[] = $name.$i; + } + }else{ + $strings[] = $name; + } }else if($rule & DBCMap::STRING_LOC_MASK) { $bytes += DBC::FIELD_SIZE * DBC::LOCALIZATION * $count; $format[] = DBC::UINT.$count.$name.'/@'.$bytes; - $strings[] = $name; + if($count > 1) { + for($i=1; $i<=$count; $i++) { + $strings[] = $name.$i; + } + }else{ + $strings[] = $name; + } } } + $format = implode('/', $format); $fields = unpack($format, $this->_data); foreach($strings as $string) { @@ -114,14 +127,14 @@ public function extract(DBCMap $map=null) { } return $fields; } - + /** * Returns a collection of fields contained within this record as unsigned integers */ public function asArray() { return unpack(DBC::UINT.$this->_dbc->getFieldCount(), $this->_data); } - + /** * Returns the identifier of this record (first field) */ @@ -131,32 +144,35 @@ public function getID() { } return $this->_id; } - + /** * Returns the position of this record */ public function getPos() { return $this->_pos; } - + /** * Reads data from this record for given field of given type */ - public function get($field, $type=DBC::UINT) { + public function get($field, $type=null) { if(is_string($field)) { if($map = $this->_dbc->getMap()) { + $type = $map->getFieldType($field); $field = $map->getFieldOffset($field); }else{ throw new DBCException('Addressing fields through string values requires DBC "'.$this->_dbc->getPath().'" to have a valid mapping attached'); return null; } } - + + $type = ($type === null) ? DBC::UINT : $type; + $offset = $field * DBC::FIELD_SIZE; if($offset >= strlen($this->_data)) { return null; } - + if($string = ($type === DBC::STRING || $type === DBC::STRING_LOC)) { $type = DBC::UINT; } @@ -166,106 +182,109 @@ public function get($field, $type=DBC::UINT) { } return $value; } - + /** * Writes data into this record for given field as given type */ - public function set($field, $value, $type=DBC::UINT) { + public function set($field, $value, $type=null) { if(!$this->_dbc->isWritable()) { throw new DBCException('Modifying records requires DBC "'.$this->_dbc->getPath().'" to be writable'); return $this; } - + if(is_string($field)) { if($map = $this->_dbc->getMap()) { + $type = $map->getFieldType($field); $field = $map->getFieldOffset($field); }else{ throw new DBCException('Addressing fields through string values requires DBC "'.$this->_dbc->getPath().'" to have a valid mapping attached'); return $this; } } - + + $type = ($type === null) ? DBC::UINT : $type; + $offset = $field * DBC::FIELD_SIZE; if($offset >= strlen($this->_data)) { return $this; } - + $handle = $this->_dbc->getHandle(); - + if($string = ($type === DBC::STRING || $type === DBC::STRING_LOC)) { $value = $this->_dbc->addString($value); $type = DBC::UINT; } $value = pack($type, $value); - + fseek($handle, $this->_offset + $offset); fwrite($handle, $value); $this->_data = substr_replace($this->_data, $value, $offset, 4); - + if($field === 0) { $this->_dbc->index($value, $this->_pos); } return $this; } - + /** * Reads an unsigned integer for given field from this record */ public function getUInt($field) { return $this->get($field, DBC::UINT); } - + /** * Writes an unsigned integer to given field into this record */ public function setUInt($field, $uint) { return $this->set($field, $uint, DBC::UINT); } - + /** * Reads a signed integer for given field from this record */ public function getInt($field) { return $this->get($field, DBC::INT); } - + /** * Writes a signed integer for given field into this record */ public function setInt($field, $int) { return $this->set($field, $int, DBC::INT); } - + /** * Reads a float for given field from this record */ public function getFloat($field) { return $this->get($field, DBC::FLOAT); } - + /** * Writes a float for given field into this record */ public function setFloat($field, $float) { return $this->set($field, $float, DBC::FLOAT); } - + /** * Reads a string for given field from this record */ public function getString($field) { return $this->get($field, DBC::STRING); } - + /** * Writes a string for given field into this record */ public function setString($field, $string) { return $this->set($field, $string, DBC::STRING); } - + /** - * Dumps field information for this record (optionally uses the default map attached to the associated DBC) + * Dumps field information for this record (optionally uses the default map attached to the associated DBC) */ public function dump($useMap=false) { if(!$useMap || $this->_dbc->getMap() === null) { @@ -275,5 +294,5 @@ public function dump($useMap=false) { } var_dump($fields); } - + } diff --git a/lib/bootstrap.php b/lib/bootstrap.php index f931aa8..9354cf6 100644 --- a/lib/bootstrap.php +++ b/lib/bootstrap.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ diff --git a/lib/exporters/DBCDatabaseExporter.class.php b/lib/exporters/DBCDatabaseExporter.class.php index 48aa0b2..1d042b4 100644 --- a/lib/exporters/DBCDatabaseExporter.class.php +++ b/lib/exporters/DBCDatabaseExporter.class.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -26,43 +26,43 @@ * Database Exporter */ class DBCDatabaseExporter implements IDBCExporter { - + /** * Default maximum number of records per INSERT-query */ const RECORDS_PER_QUERY = 1000; - + /** * Reference to PDO instance (if any) */ private $_pdo = null; - + /** * Maximum number of records per INSERT-query */ public $recordsPerQuery = self::RECORDS_PER_QUERY; - + /** * Constructs a new database exporter with given PDO instance (optional) */ public function __construct(PDO $pdo=null, $recordsPerQuery=self::RECORDS_PER_QUERY) { $this->setPDO($pdo); } - + /** * Sets new PDO instance */ public function setPDO(PDO $pdo=null) { $this->_pdo = $pdo; } - + /** * Retrieves the PDO instance */ public function getPDO() { return $this->_pdo; } - + /** * Escapes given string (nested collections of strings allowed) * @see http://php.net/manual/en/function.mysql-real-escape-string.php#101248 @@ -80,7 +80,7 @@ public function escape($string) { } return $string; } - + /** * Joins given fields into a comma-separated string */ @@ -95,24 +95,24 @@ public function join(array $fields) { } } return implode(', ', $copy); - } - + } + /** * Exports given DBC in SQL format to given target (defaults to output stream) using given table name */ public function export(DBC $dbc, $target=self::OUTPUT, $table='dbc') { $target = ($target === null) ? self::OUTPUT : $target; - + $map = $dbc->getMap(); if($map === null) { throw new DBCException(self::NO_MAP); - return; + return; } - + $sql = fopen($target, 'w+'); - + $table = "`".$this->escape($table)."`"; - + fwrite($sql, "DROP TABLE IF EXISTS ".$table.";".PHP_EOL.PHP_EOL); $dd = array(); $fields = $map->getFields(); @@ -131,28 +131,28 @@ public function export(DBC $dbc, $target=self::OUTPUT, $table='dbc') { } for($i=1; $i<=$count; $i++) { $suffix = ($count > 1) ? $i : ''; - $dd[] = ' `'.$this->escape($name).$suffix.'` '.$type.' '.((!$null) ? 'NOT' : '').' NULL'; + $dd[] = ' `'.$this->escape($name).$suffix.'` '.$type.' '.(($null) ? 'NULL' : 'NOT NULL'); } } reset($fields); - fwrite($sql, "CREATE TABLE ".$table." (".PHP_EOL.implode(', '.PHP_EOL, $dd).', '.PHP_EOL.' PRIMARY KEY (`'.key($fields).'`) '.PHP_EOL.');'.PHP_EOL.PHP_EOL); + fwrite($sql, "CREATE TABLE ".$table." (".PHP_EOL.implode(','.PHP_EOL, $dd).','.PHP_EOL.' PRIMARY KEY (`'.key($fields).'`)'.PHP_EOL.');'.PHP_EOL.PHP_EOL); foreach($dbc as $i=>$record) { if($i % $this->recordsPerQuery === 0) { - fwrite($sql, "INSERT INTO ".$table." VALUES ".PHP_EOL." ("); + fwrite($sql, "INSERT INTO ".$table." VALUES".PHP_EOL." ("); }else{ fwrite($sql, ",".PHP_EOL." ("); } fwrite($sql, $this->join($record->extract())); if(($i+1) % $this->recordsPerQuery === 0 || $i === $dbc->getRecordCount() - 1) { - fwrite($sql, ");".PHP_EOL.PHP_EOL); + fwrite($sql, ");".PHP_EOL); }else{ fwrite($sql, ")"); } } fclose($sql); - + return $target; - + } - + } diff --git a/lib/exporters/DBCJSONExporter.class.php b/lib/exporters/DBCJSONExporter.class.php index b1e18b8..037547e 100644 --- a/lib/exporters/DBCJSONExporter.class.php +++ b/lib/exporters/DBCJSONExporter.class.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -26,7 +26,7 @@ * JSON Exporter */ class DBCJSONExporter implements IDBCExporter { - + /** * Exports given DBC in JSON format to given target (defaults to output stream) */ @@ -34,14 +34,14 @@ public function export(DBC $dbc, $target=self::OUTPUT) { $map = $dbc->getMap(); if($map === null) { throw new DBCException(self::NO_MAP); - return; + return; } - + $data = array( 'fields'=>array(), 'records'=>array() ); - + $fields = $map->getFields(); foreach($fields as $name=>$rule) { $count = max($rule & 0xFF, 1); @@ -62,8 +62,8 @@ public function export(DBC $dbc, $target=self::OUTPUT) { foreach($dbc as $record) { $data['records'][] = array_values($record->extract()); } - + file_put_contents($target, json_encode($data)); } - + } diff --git a/lib/exporters/DBCXMLExporter.class.php b/lib/exporters/DBCXMLExporter.class.php index 6c0f807..4ec13da 100644 --- a/lib/exporters/DBCXMLExporter.class.php +++ b/lib/exporters/DBCXMLExporter.class.php @@ -2,23 +2,23 @@ /** * World of Warcraft DBC Library * Copyright (c) 2011 Tim Kurvers - * + * * This library allows creation, reading and export of World of Warcraft's * client-side database files. These so-called DBCs store information * required by the client to operate successfully and can be extracted * from the MPQ archives of the actual game client. - * - * The contents of this file are subject to the MIT License, under which + * + * The contents of this file are subject to the MIT License, under which * this library is licensed. See the LICENSE file for the full license. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Tim Kurvers */ @@ -26,7 +26,7 @@ * XML Exporter */ class DBCXMLExporter implements IDBCExporter { - + /** * Exports given DBC in XML format to given target (defaults to output stream) */ @@ -34,16 +34,16 @@ public function export(DBC $dbc, $target=self::OUTPUT) { $map = $dbc->getMap(); if($map === null) { throw new DBCException(self::NO_MAP); - return; + return; } - + $dom = new DOMDocument('1.0'); $dom->formatOutput = true; - + $edbc = $dom->appendChild($dom->createElement('dbc')); $efields = $edbc->appendChild($dom->createElement('fields')); $erecords = $edbc->appendChild($dom->createElement('records')); - + $fields = $map->getFields(); foreach($fields as $name=>$rule) { $count = max($rule & 0xFF, 1); @@ -70,10 +70,10 @@ public function export(DBC $dbc, $target=self::OUTPUT) { $erecord->appendChild($attr); } } - + $data = $dom->saveXML(); - + file_put_contents($target, $data); } - + }