DB2

From wowdev
Revision as of 08:51, 2 December 2015 by Simca (talk | contribs) (→‎WDB2 / WCH2)
Jump to navigation Jump to search

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 / WCH2

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 copy_table_size;
};

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 / WCH4

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, row data will be displaced (moved farther into the file) 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. This format can still have the non-inline indices block or the row redundancy reduction block. Also strings are inline in this format. Since it has to iterate 1 by 1 from minID to maxID, there are often tens of thousands of the 6 byte structs that are pure 0 since the row doesn't exist. Make sure you are detecting if fileOffset is 0 and ignoring those entries. Detecting this format is tricky - the best method is probably to read the first integer after the header and check to see whether it is equal to the fileOffset that would move you to the end of the 6-byte struct array.