CWDG论坛-专业魔兽插件's Archiver

月色狼影 发表于 2007-9-18 17:27

php parsing LUA/DBC/WDB core

PHP WDB 解析

The parser doesn't account for the 8 or so null bytes at the end of the file.
Basic usage:[code] $p = new parser;
$p->filename = '/absolute/path';
$p->setVars();

if (!$data = $p->fetchData())
return true; // file had no data[/code]The source:[code] 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;
   }
}[/code]

月色狼影 发表于 2007-9-18 17:29

PHP LUA Parsing Class

Credit goes to Freddy for this one (obviously because the codes not all tab indented :P)
array parseLUA(string abspath)

[code] function parseLUA($filepath)
{
    $luaLinesArray = file($filepath);
$stack = array( array( "",  array()));
$stack_pos = 0;
$last_line = "";
foreach( $luaLinesArray as $line )
{
if(substr( $line, -2, 1 ) == '\\')
{
  $last_line .= substr($line, 0, -2) . "\n";
  continue;
}
$line = $last_line . $line;
$last_line = "";
if(strstr( $line, "=" ))
{
  list($name, $value) = explode("=", $line, 2);
  $name = preg_replace( "/^\s*/","", $name);
  $name = preg_replace( "/\s*$/","", $name);
  if(substr($name,0,2) == "[\"")
  {
   $name = substr($name, 2, -2);
  }
  elseif(substr($name, 0, 1) == "[")
  {
   $name = intval(substr($name, 1, -1));
  }
  $name = trim($name, chr(0xEF).chr(0xBB).chr(0xBF));
  $value = preg_replace("/^\s*/", "", $value);
  $value = preg_replace("/\s*$/", "", $value);
  if($value == "{")
  {
   $stack_pos++;
   $stack[$stack_pos] = array($name, array());
  }
  else
  {
   if(preg_match("/^\"([^\"\\\\]|\\\\.)*\"/", $value, $matches))
   {
    $value = substr($matches[0],1,-1);
    $value = preg_replace( "/\\\\(.)/", "\\1", $value
    );
   }
   elseif(preg_match("/([0-9\.]*)e\+([0-9]+)/", $value, $matches))
   {
    #$value = $matches[1] * pow(10, $matches[2]);
    $value = floatval($matches[0]);
   }
   elseif(preg_match("/^-?[0-9]+\\.[0-9]+/", $value, $matches))
   {
    $value = floatval($matches[0]);
   }
   elseif(preg_match("/^-?[0-9+]+/", $value, $matches))
   {
    $value = intval($matches[0]);
   }
   elseif(preg_match("/^(True|False)/", $value, $matches))
   {
    if($matches[0] == "True")
    {
     $value = True;
    }
    else
    {
     $value = False;
    }
   }
   elseif(preg_match("/^nil/", $value))
   {
    $value = NULL;
   }
   $value = $value;
   $stack[$stack_pos][1][$name] = $value;
  }
}
elseif( preg_match("/^\s*}/", $line))
{
  $hash = $stack[$stack_pos];
  $stack_pos--;
  $stack[$stack_pos][1][$hash[0]] = $hash[1];
}
}
return $stack[0][1];
}

[/code]

月色狼影 发表于 2007-9-18 17:30

PHP DBC Category Tree Function

This source code added in speculation and theory to [url=http://www.sourcepeek.com/wiki/CharBaseInfo.dbc][color=#810081]CharBaseInfo.dbc[/color][/url] and is irrelevant to any files, systems, or required algorithms presented in any World of Warcraft data.

[code]
$g_tree[] = array('id' => "your id", 'id_parent' => "your category parent", 'title' => " your title");
$ret_tree = array();
tree(0,0);
[/code]


[code] function tree($id_parent = 0, $indent = 0)
{
        global $g_tree, $ret_tree;
        $tt = array();
        $x = 0;
        $loop = 0;

        foreach($g_tree as $n)
        {
                if( $n['id_parent'] == $id_parent)
                {
                        $tt[$x++] = $loop;
                }
                $loop++;
        }

        if( $x != 0)
        {
                foreach($tt as $d)
                {
                        $tmp = array();

                        foreach($g_tree[$d] as $key => $value)
                        {
                                $tmp[$key] = $value;
                        }
                        $tmp['indent'] = $indent;
                        $ret_tree[] = $tmp;

                        tree($tmp['id'], $indent+1);
                }
        }
        else
        {
                return;
        }
}

[/code]

月色狼影 发表于 2007-9-19 04:28

数据库的第一分析 将通过php parse.. 分解出各种信息源
然后汇入数据库 进行数据匹配工作

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.