FiftyTifty

Parsing DBC files?

While there is MyDBCEditor, it's very unwieldy for the more exotic .DBC files, with it being rather useless for editing LightIntBand.dbc due to it treating four byte integers as a single dword integer, with no way to change that.

So what I want to do, is create a tool that is designed for editing LightIntBand.dbc. Problem is, the documentation on the DBC files is rather jumbled, and there's no solid examples to work from.

As in, take the header:  https://wowdev.wiki/DBC There is no documentation on how to read, parse, and get to the data. It seems like the header even encases the actual game data, from what I could tell, with no mention of how to work with it.

On the other hand, the documentation for https://wowdev.wiki/DB/LightIntBand Is pretty clear. The data is of a fixed size: There is one dword containing the ID, another dword containing the number of entries in the two following arrays, one array containing dword integers (16 entries * 4 bytes = 64 bytes), and another array containing 16 * 4 byte matrices (1 byte for blue value, 1 byte for green value, 1 byte for red value, 1 byte for whatever X is). That means every single record in the .dbc file is 136 bytes long, so once the header is taken care of, the rest is already laid out.

So how do I read the header, in order to get access to the records inside the .dbc file?

Share this post


Link to post
Share on other sites

It does not? 

The header surely does not contain the record data, just magic, record and field count, record and string block size.

The file contains a header, the records and the string block, with the header given sizes each.

From the DBC point of view, the structure of the data is irrelevant and a byte blob of record_size * record_count. As you noticed, the LoghtIntBand page then explains the structure inside each record. 

In the string Block section there is also code that gives an example of navigating the entire file. 

D2A6CFF4-D48F-4BF3-8308-37A3E3774C58.jpeg

Share this post


Link to post
Share on other sites

Oh, and if you think the wiki is too confusing even after you understood it, please reword stuff there, it is a wiki after all.

Share this post


Link to post
Share on other sites

MyDBCEditor in 2019?! Open for yourself WDBX Editor!

https://github.com/WowDevTools/WDBXEditor

Dont make bicycle!) Speak with author about repository access.

If you can add some features (like multiple select, edit, replace and delete lines) - it be a wonderful!

 

Share this post


Link to post
Share on other sites
12 hours ago, wungasaurus said:

Oh, and if you think the wiki is too confusing even after you understood it, please reword stuff there, it is a wiki after all.

Aye I would, the problem is that it's not written in a way that can be understood by people who don't already know how it works. That code example isn't even code, it's psuedocode that shows how the header is arranged. And that Struct{} part throws me off. If I understand it correctly:

dbc_header Is a record that is at the start of every DBC file, and is 20 bytes in size (according to WDBXE, it's 32 bytes in size: (https://github.com/WowDevTools/WDBXEditor/blob/master/WDBXEditor/Reader/DBHeader.cs ).

Then after the header, the actual amount of data for LightIntBand is (record_count * 134) bytes in size. So to get to the start of the data, we just move forward from the beginning of the file by 20 bytes (or 32, if WDBXE is correct). To get to the end, we then move forward by (record_count * 134) bytes.

But then at the end of the file, is an array of characters, but is named string_block ? This is not intuitive, I've no understanding of the data that follows.

 

4 hours ago, Gratural said:

MyDBCEditor in 2019?! Open for yourself WDBX Editor!

https://github.com/WowDevTools/WDBXEditor

Dont make bicycle!) Speak with author about repository access.

If you can add some features (like multiple select, edit, replace and delete lines) - it be a wonderful!

 

Ooh, good find. I looked at the tool, and it's not exactly pristine in the way it's organized. There's also no documentation, so it's really not clear how everything is being handled. That's compounded by all the nested functions.

What I'll do, once I can figure out how the LightIntBand.dbc file is arranged (already know how to parse the records, but not the header and character array), I'll just make a tool dedicated for editing that file. And since I'll be making more tools as I continue to explore TrinityCore, I'll use that knowledge and release more tools that are designed around the specific .dbc files.

Share this post


Link to post
Share on other sites

Huh? The code on wiki is valid C++ except for the array lengths in dbc_file.

the WDBX code linked is not for dbc but db2. Header size is 5*4, I guarantee.

string block is a pure character dump that in the case of light will be always of size 1. it is used by columns that contain strings, where the field value is an offset into that block.

Share this post


Link to post
Share on other sites
On 6/29/2019 at 5:03 PM, wungasaurus said:

Huh? The code on wiki is valid C++ except for the array lengths in dbc_file.

the WDBX code linked is not for dbc but db2. Header size is 5*4, I guarantee.

string block is a pure character dump that in the case of light will be always of size 1. it is used by columns that contain strings, where the field value is an offset into that block.

Aye that clears it up, thanks.

So how it works, is that the header is 20 bytes in size, and the following records are 136 bytes in size. I took a look at using C# for this, but it's really not made for writing to hex, especially with arrays not having a fixed size option. Decided to use Pascal, and going to use Deplhi to give the IDE a try as it looks better than Lazarus.

Share this post


Link to post
Share on other sites

As an update, here's what I've got so far: VFR9rCr.png

The only thing I need to know now, is how to handle the string block. Is it just 1 character for each record in LightIntBand.dbc?

Share this post


Link to post
Share on other sites

String block size is for entire file, not per record. For that dbc it will be 1, as no column is a string. If it were, the record field would give an offset into the file global stringblock.

Share this post


Link to post
Share on other sites
8 hours ago, wungasaurus said:

String block size is for entire file, not per record. For that dbc it will be 1, as no column is a string. If it were, the record field would give an offset into the file global stringblock.

Wait, it's just one byte in size? If that's the case, I can just add a wee button that allows the modder to append a new record.

Share this post


Link to post
Share on other sites

Regardless of the size - which is given in the header! - you can do such a button. Just move all stringblock bytes a bit to the back?

Pre db2, these files are utterly simple. It is just three blocks of fixed, header given, header given size, and the most complex part is that records can point into the string block. It is just completely dumb arrays.

Share this post


Link to post
Share on other sites
On 7/4/2019 at 1:13 AM, wungasaurus said:

Regardless of the size - which is given in the header! - you can do such a button. Just move all stringblock bytes a bit to the back?

Pre db2, these files are utterly simple. It is just three blocks of fixed, header given, header given size, and the most complex part is that records can point into the string block. It is just completely dumb arrays.

Still working on this, in-between the other stuff I'm doing and researching.

Made more progress. Since the string block for LightIntBand.dbc is literally a single byte with a value of 0x00, adding and removing records is painless to code. So that's a new feature; you can add and remove entries.

And since Delphi uses pointers to fill that tree panel on the left, it's also easy to make another TMemoryStream, read all the records that are still present in the tree as well as those that have been added, chuck them into an array, punt the header and string block in, and bam. New LightIntBand.dbc file that requires no other programs to work with, and it's just much easier.

Any feature requests? I'm not a proper programmer, so I won't be able to do fancy stuff.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now