DB2: Difference between revisions

From wowdev
Jump to navigation Jump to search
No edit summary
Line 4: Line 4:
This page describes the structure of [[DB2]] files. For a list of existing DB2 files and their contents see the categories [[:Category:DBC|DBC]], [[:Category:DBC_Vanilla|Vanilla]], [[:Category:DBC_BC|Burning Crusade]], [[:Category:DBC_WotLK|Wrath of the Lich King]], [[:Category:DBC_Cataclysm|Cataclysm]], [[:Category:DBC_MoP|Mists of Pandaria]] and [[:Category:DBC_WoD|Warlords of Draenor]]. If you add documentation for a file, please add the correct categories (also the build number) as well.
This page describes the structure of [[DB2]] files. For a list of existing DB2 files and their contents see the categories [[:Category:DBC|DBC]], [[:Category:DBC_Vanilla|Vanilla]], [[:Category:DBC_BC|Burning Crusade]], [[:Category:DBC_WotLK|Wrath of the Lich King]], [[:Category:DBC_Cataclysm|Cataclysm]], [[:Category:DBC_MoP|Mists of Pandaria]] and [[:Category:DBC_WoD|Warlords of Draenor]]. If you add documentation for a file, please add the correct categories (also the build number) as well.


=Structure=
=WDB2=
==Structure==
  struct db2_header
  struct db2_header
  {
  {
Line 42: Line 43:
=Localization=
=Localization=
[[DB2]] records can contain localized strings. In contrast to [[DBC|DBCs]], a [[DB2]] file only contains localized values for a given locale (header.locale).  
[[DB2]] records can contain localized strings. In contrast to [[DBC|DBCs]], a [[DB2]] file only contains localized values for a given locale (header.locale).  
=WDB3=
paraphrased from Simca on #modcraft, Wed Nov 25 2015 12:54:32
three major differences:
* optionally, non-inline indices, located in a new block after string block
* optionally, row redundancy reduction tech, where the WDB3 file has removed all rows who match other rows exactly. a new block has been added to the end (after the previously mentioned new block) that is an array of 8-byte structs in the form (uint32 IDOfNewRow, uint32 IDOfRowToCopy)
* optionally, all of this new stuff (and in fact all WDBx structure at all besides the header) will be ignored, in favor of a wonky array of 6-byte structs in the form (uint32 fileOffset, uint16 recordLength) where the length of the array is 1 + maxID - minID (maxID and minID being header fields)
that wonky format has you seek to the fileoffset listed and read the row in place. IDs are not included in the data there and must be inferred by the position in the array (minID + index in array = current ID). also strings are inline in that format because, again, it throws away all convention. to top it off, since it has to iterate 1 by 1 from minID to maxID, there are tens of thousands of the 6 byte structs that are pure 0 since the row doesn't exist. making the format not only A) weird as fuck B) completely contrary to the standard C) detected by exactly nothing other than the name of the db2 (item-sparse) but also D) incredibly inefficient. I feel bad for the community tools that have to implement this shit


[[Category:Format]]
[[Category:Format]]

Revision as of 15:53, 26 November 2015

DB2 files are the new version of client side databases, introduced in Cataclysm, containing data about items, NPCs, environment, world and a lot more. Except for their header they are pretty much equivalent to DBC files. You may want to also look at those. The structure described here is also used in ADB files, which are a cache of dynamically streamed database entries / hotfixes.

Table content structures

This page describes the structure of DB2 files. For a list of existing DB2 files and their contents see the categories DBC, Vanilla, Burning Crusade, Wrath of the Lich King, Cataclysm, Mists of Pandaria and Warlords of Draenor. If you add documentation for a file, please add the correct categories (also the build number) as well.

WDB2

Structure

struct db2_header
{
  uint32_t magic;                                               // 'WDB2' for .db2 (database), 'WCH2' for .adb (cache)
  uint32_t record_count;
  uint32_t field_count;
  uint32_t record_size;
  uint32_t string_table_size;                                   // string block always contains at least one zero-byte
  uint32_t table_hash;
  uint32_t build;
  uint32_t timestamp_last_written;                              // set to time(0); when writing in WowClientDB2_Base::Save()
  uint32_t min_id;
  uint32_t max_id;
  uint32_t locale;                                              // as seen in TextWowEnum
  uint32_t unk2;
};

template<typename record_type>
struct db2_file
{
  db2_header header;
  // static_assert (header.record_size == sizeof (record_type));

  if (header.max_id != 0)
  {
    int indices[header.max_id - header.min_id + 1];             // maps from id to row index in records[] below
    short string_lengths[header.max_id - header.min_id + 1];    // sum of lengths of all strings in row
  }
 
  record_type records[header.record_count]; 
  char string_block[header.string_block_size];
};

String Block

Equivalent to DBC version. See documentation there.

Localization

DB2 records can contain localized strings. In contrast to DBCs, a DB2 file only contains localized values for a given locale (header.locale).

WDB3

paraphrased from Simca on #modcraft, Wed Nov 25 2015 12:54:32

three major differences:

  • optionally, non-inline indices, located in a new block after string block
  • optionally, row redundancy reduction tech, where the WDB3 file has removed all rows who match other rows exactly. a new block has been added to the end (after the previously mentioned new block) that is an array of 8-byte structs in the form (uint32 IDOfNewRow, uint32 IDOfRowToCopy)
  • optionally, all of this new stuff (and in fact all WDBx structure at all besides the header) will be ignored, in favor of a wonky array of 6-byte structs in the form (uint32 fileOffset, uint16 recordLength) where the length of the array is 1 + maxID - minID (maxID and minID being header fields)

that wonky format has you seek to the fileoffset listed and read the row in place. IDs are not included in the data there and must be inferred by the position in the array (minID + index in array = current ID). also strings are inline in that format because, again, it throws away all convention. to top it off, since it has to iterate 1 by 1 from minID to maxID, there are tens of thousands of the 6 byte structs that are pure 0 since the row doesn't exist. making the format not only A) weird as fuck B) completely contrary to the standard C) detected by exactly nothing other than the name of the db2 (item-sparse) but also D) incredibly inefficient. I feel bad for the community tools that have to implement this shit