WowDevTools / libwarcraft

All-in-one managed library for reading and writing World of Warcraft data files.
GNU General Public License v3.0
59 stars 25 forks source link

ADT does not handle offsets correctly #14

Open wachag opened 2 years ago

wachag commented 2 years ago

When an ADT file is parsed, this call throws an invalid chunk exception, failing to load ADT

https://github.com/WowDevTools/libwarcraft/blob/355fb29211a3f31b3d7d55308d27f69eb48cd197/libwarcraft/ADT/TerrainTile.cs#L124

Nihlus commented 2 years ago

This library is pretty much on ice at the moment; I don't have time to actively maintain and develop it. It needs a lot of updates and modernization, and I'm afraid I won't be able to take care of this issue any time soon :(

maltesermailo commented 2 years ago

To comment on this, ADT Offsets are relative to their reading location in MHDR, which in case map chunk offsets in each ADT File is 0x14. Easy way to fix this would be to just get the current position in the reader and add the offset to it, thereby fixing this problem.

I mean, most people of us are probably gonna use this to edit ADT and WDT files rather than the rest, so if someone could throw in a Push-Request, that would fix it.(I can't do it since I can't compile the library without some modifications(Disabling FxCopAnalyzer, idk what is happening there))

wachag commented 2 years ago

I already have it fixed on my side, + 8 offset is required for current chunk offset. Unfortunately, I have other issues with mcnk too, I want to fix them before a PR

maltesermailo commented 2 years ago

@wachag +8 can't be the offset. It was +20 for most ADT files I tested. Might be different across several versions in which case, you'd have to use my approach by reading the start of the MHDR section(After the signature and size parameter, but before the Flags since thats data) and saving that location.

wachag commented 2 years ago

It is:

''' Works like this:

        // In all ADT files, the version chunk and header chunk are at the beginning of the file,
        // with the header following the version. From them, the rest of the chunks can be
        // seeked to and read.

        // Read Version Chunk
        Version = br.ReadIFFChunk<TerrainVersion>();
        long globalOffset = br.BaseStream.Position + 8;
        // Read the header chunk
        Header = br.ReadIFFChunk<TerrainHeader>();

        if (Header.MapChunkOffsetsOffset > 0)
        {
            br.BaseStream.Position = globalOffset + Header.MapChunkOffsetsOffset;
            MapChunkOffsets = br.ReadIFFChunk<TerrainMapChunkOffsets>();
        }

'''

wachag commented 2 years ago

Of course, I am relative to the MHDR, +8 is because how the chunk reading is organized in the lib

wachag commented 2 years ago

For similar reasons, from MCNK offsets we need to subtract 8. Baked shadow chunks have a bit of an issue too, fixing those too.

wachag commented 2 years ago

In MapChunkHeader.cs these are incorrectly read (stream position will be wrong after these): LowResTextureMap = br.ReadUInt16(); PredTex = br.ReadUInt32(); NoEffectDoodad = br.ReadUInt32();

https://wowdev.wiki/ADT/v18#MCNK_chunk