Brainy Posted February 5, 2017 Report Share Posted February 5, 2017 Hey a few hours ago I've started writing a PHP library to access the db2 files of the current WoW client. To test my library I've implemented the structure of CharTitles.db2. This looks like that: class CharTitles extends DB2File { public function __construct(File $file) { parent::__construct(new BinaryReader($file->getBuffer())); } public function getStructure() : array { return [ DB2File::FIELD_STR, DB2File::FIELD_STR, DB2File::FIELD_INT16, DB2File::FIELD_BYTE ]; } public function hasIndexFieldInData() : bool { return true; } } I've taken the structure from the current trinitycore version. If I load the file now, I'll just get one correct record (the first one). The others are containing bad data. The reason for this is a single byte after each record so if change the structure to this DB2File::FIELD_STR, DB2File::FIELD_STR, DB2File::FIELD_INT16, DB2File::FIELD_INT16 all will work as it should. Now my question. What exactly is that byte after each record? Is it a kind of seperator or is the structure of the current trinitycore just outdated? Thanks in advance! Link to comment Share on other sites More sharing options...
Brainy Posted February 5, 2017 Author Report Share Posted February 5, 2017 I did another test with ChatChannels.db2. It seems that the total amount of bytes in a record modulo 4 must be 0. So I've implemented following logic $bytesToSkip = 4 - ($recordSize % 4); if ($bytesToSkip != 4) $this->reader->skip($bytesToSkip); Is this correct or just a bad hack? EDIT#1: In general it seems to work [records:protected] => Array ( [0] => DB2\DB2Record Object ( [id:protected] => 1 [fields:protected] => Array ( [0] => 1572875 [1] => General - %s [2] => General [3] => 0 ) ) [1] => DB2\DB2Record Object ( [id:protected] => 2 [fields:protected] => Array ( [0] => 1048635 [1] => Trade - %s [2] => Trade [3] => 0 ) ) ..... Link to comment Share on other sites More sharing options...
Shauren Posted February 5, 2017 Report Share Posted February 5, 2017 They are not aligned to 4 bytes, they are aligned to RecordSize from db2 header 1 Link to comment Share on other sites More sharing options...
Brainy Posted February 5, 2017 Author Report Share Posted February 5, 2017 Ok understand. Thanks you Shauren. But now I have another question. For the AreaTable.db2 I can read this header DB2Header Object ( [magic] => WDB5 [recordCount] => 5564 [fieldCount] => 23 [recordSize] => 56 [stringTableSize] => 158430 [tableHash] => 1918102339 [layoutHash] => 886938365 [minId] => 1 [maxId] => 8623 [locale] => 1 [copyTableSize] => 0 [flags] => 262144 [idIndex] => 0 ) You see the recordSize of 56 but if I count the bytes of the structure excepting the ID field, it will be 58 bytes long. How is this possible? Link to comment Share on other sites More sharing options...
Shauren Posted February 5, 2017 Report Share Posted February 5, 2017 Whenever you see uint32 near the end of structure its not uint32, its something called varint and its size will be determined by the field table block in header (https://github.com/TrinityCore/TrinityCore/blob/master/src/server/shared/DataStores/DB2StorageLoader.cpp#L197) 1 Link to comment Share on other sites More sharing options...
Brainy Posted February 5, 2017 Author Report Share Posted February 5, 2017 Ah I understand. Thank you very much for your help! Link to comment Share on other sites More sharing options...
Recommended Posts