PHP WDB Parsing Class
From Source Peek Wiki
The parser doesn't account for the 8 or so null bytes at the end of the file.
Basic usage:
$p = new parser;
$p->filename = '/absolute/path';
$p->setVars();
if (!$data = $p->fetchData())
return true; // file had no data
The source:
class parser {
var $lang = 'en',
$author,
$ip,
$debug = false,
$timestamp,
$filename,
$dataType,
$error = '',
$tableID,
$tableName,
$dataHeader,
$dataVersion,
$langName;
function getcsv($dataArray, $delimiter=',', $enclosure='"')
{
$string = "";
$writeDelimiter = false;
foreach($dataArray as $dataElement)
{
if ($writeDelimiter)
$string .= $delimiter;
$string .= $enclosure . $dataElement . $enclosure;
$writeDelimiter = true;
}
return $string;
}
function setVars()
{
if (!is_readable($this->filename))
{
$this->error = 'not readable';
return false;
}
if (!is_file($this->filename))
{
$this->error = 'cannot open';
return false;
}
return true;
}
function fetchData()
{
if (!$fp = fopen($this->filename, "rb"))
{
$this->error = 'unable to open file';
return false;
}
$header = fread($fp, 4);
if (($this->dataHeader = $this->selectType($header)) !== false)
{
$this->dataType = 'wdb';
if (!$this->selectTable($this->dataHeader) && !$this->debug)
{
@unlink($this->filename);
$this->error = 'useless data';
return false;
}
if ((!$fields = $this->selectFields($this->dataHeader)) && !$this->debug)
{
$this->error = 'unable to select fields';
return false;
}
$hex = bin2hex(fread($fp, 4));
$hex = substr($hex, 6, 2).substr($hex, 4, 2).substr($hex, 2, 2).substr($hex, 0, 2);
$this->dataVersion = hexdec($hex);
if (!($this->dataVersion >= 5195))
{
@unlink($this->filename);
$this->error = 'old data';
return false;
}
$this->langName = strrev(fread($fp, 4));
$this->lang = substr($this->langName, 0, 2);
if (trim($this->lang) == 'zh')
$this->lang = strtolower(substr($this->langName, -2));
$hdr = $this->dataVersion.$this->langName.fread($fp, 8);
if(!(ord($hdr)&1) && 0x5a!=ord($hdr))
$hdr .= fread($fp, 4);
$e = 0;
while (!feof($fp))
{
$hex = bin2hex(fread($fp, 4));
$hex = substr($hex, 6, 2).substr($hex, 4, 2).substr($hex, 2, 2).substr($hex, 0, 2);
$id = hexdec($hex);
$hex = bin2hex(fread($fp, 4));
$hex = substr($hex, 6, 2).substr($hex, 4, 2).substr($hex, 2, 2).substr($hex, 0, 2);
$length = hexdec($hex);
$rest = @fread($fp, $length);
$array[$e][0] = $id;
$z = 2;
$i = 0;
while ($i < strlen($rest))
{
if (empty($fields[$z]))
$fields[$z] = array('0');
$string = '';
if ($fields[$z][0] == 1 || $fields[$z][0] == 2)
{
for($s=$i; ord(substr($rest, $i, 1)); ++$i)
;
$string = substr($rest, $s, $i-$s);
$array[$e][$z] = $string;
$i++;
}
else
{
$string = substr($rest, $i, 4);
$i += 4;
$hex = bin2hex($string);
$hex = substr($hex, 6, 2).substr($hex, 4, 2).substr($hex, 2, 2).substr($hex, 0, 2);
list(,$floatval) = unpack("f*", $string);
if (round($floatval,0) == $floatval || $fields[$z][0] == 3)
{
$array[$e][$z] = round($floatval,2);
}
else
$array[$e][$z] = $this->parse_unsigned_int(hexdec($hex));
$string = '';
}
$z++;
}
$e++;
}
fclose($fp);
return $array;
}
fclose($fp);
$this->error = 'unknown error';
return false;
}
function selectType($header)
{
switch ($header)
{
case 'BOGW':
return 'gameobjectcache';
case 'BOMW':
return 'creaturecache';
case 'BDNW':
return 'itemnamecache';
case 'TSQW':
return 'questcache';
case 'BDIW':
return 'itemcache';
case 'XTIW':
return 'itemtextcaxhe';
case 'CPNW':
return 'npccache';
case 'XTPW':
return 'pagetextcache';
}
}
function selectTable($type)
{
switch ($type)
{
case "creaturecache":
{
$this->tableName = 'db_creatures';
$this->tableID = 'creatureID';
return true;
}
case "itemcache":
{
$this->tableName = 'db_items';
$this->tableID = 'itemID';
return true;
}
case "questcache":
{
$this->tableName = 'db_quests';
$this->tableID = 'questID';
return true;
}
case "gameobjectcache":
{
$this->tableName = 'db_objects';
$this->tableID = 'objectID';
return true;
}
case "pagetextcache":
{
$this->tableName = 'db_pages';
$this->tableID = 'pageID';
return true;
}
}
}
function selectFields($type)
{
// fist param: 1 for string, 2 for trash, 3 for float
// second param: field name for strings
switch ($type)
{
case 'itemcache':
$ar = array();
$ar[4] = array(1,'itemName');
$ar[5] = array(2);
$ar[6] = array(2);
$ar[7] = array(2);
$ar[48] = array(3);
$ar[49] = array(3);
$ar[51] = array(3);
$ar[52] = array(3);
$ar[54] = array(3);
$ar[55] = array(3);
$ar[57] = array(3);
$ar[58] = array(3);
$ar[60] = array(3);
$ar[61] = array(3);
$ar[104] = array(1,'itemDescription');
return $ar;
break;
case 'questcache':
$ar = array();
$ar[41] = array(1,'questName');
$ar[42] = array(1,'questDescription');
$ar[43] = array(1,'questDetails');
$ar[44] = array(1,'questSubdescription');
$ar[61] = array(1,'objective1');
$ar[62] = array(1,'objective2');
$ar[63] = array(1,'objective3');
$ar[64] = array(1,'objective4');
return $ar;
break;
case 'npccache':
$ar = array();
$ar[3] = array(1,'speech1String');
$ar[4] = array(2);
$ar[6] = array(1,'speech2String');
$ar[7] = array(2);
$ar[14] = array(1,'speech3String');
$ar[15] = array(2);
$ar[24] = array(1,'speed4String');
$ar[25] = array(2);
return $ar;
break;
case 'itemnamecache':
return array(
'item_id',
'',
'name:string',
);
break;
case 'itemtextcaxhe':
return array(
'item_id',
'',
'text:string',
);
break;
case 'creaturecache':
$ar = array();
$ar[2] = array(1,'creatureName');
$ar[3] = array(2);
$ar[4] = array(2);
$ar[5] = array(2);
$ar[6] = array(1,'creatureDescription');
return $ar;
break;
case 'gameobjectcache':
$ar = array();
$ar[4] = array(1,'objectName');
$ar[5] = array(2);
$ar[6] = array(2);
$ar[7] = array(2);
return $ar;
break;
case 'pagetextcache':
return array(
'page_id',
'',
'text:string',
);
break;
}
}
function parse_unsigned_int($string) {
$x = (float)$string;
if ($x > (float)2147483647)
$x -= (float)"4294967296";
else
return $string;
return (int)$x;
}
}
