Skip to content

Commit

Permalink
Fix WDC4/WDC5 writing crashes
Browse files Browse the repository at this point in the history
  • Loading branch information
Marlamin committed Aug 8, 2024
1 parent 5003e22 commit e9ae98c
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 23 deletions.
11 changes: 6 additions & 5 deletions DBCD.IO/Readers/WDC4Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,19 +283,20 @@ public WDC4Reader(Stream stream)
int palletDataSize = reader.ReadInt32(); // in bytes, sizeof(DBC2PalletValue) == 4
int sectionsCount = reader.ReadInt32();

if (sectionsCount == 0 || RecordsCount == 0)
return;

var sections = reader.ReadArray<SectionHeaderWDC4>(sectionsCount);
var sections = (sectionsCount == 0) ? new List<SectionHeaderWDC4>() : reader.ReadArray<SectionHeaderWDC4>(sectionsCount).ToList();
this.m_sections = sections.OfType<IEncryptableDatabaseSection>().ToList();
this.m_encryptedIDs = new Dictionary<ulong, int[]>();

// field meta data
Meta = reader.ReadArray<FieldMetaData>(FieldsCount);

// column meta data
ColumnMeta = reader.ReadArray<ColumnMetaData>(FieldsCount);

if (sectionsCount == 0 || RecordsCount == 0)
return;

this.m_encryptedIDs = new Dictionary<ulong, int[]>();

// pallet data
PalletData = new Value32[ColumnMeta.Length][];
for (int i = 0; i < ColumnMeta.Length; i++)
Expand Down
11 changes: 6 additions & 5 deletions DBCD.IO/Readers/WDC5Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,19 +287,20 @@ public WDC5Reader(Stream stream)
int palletDataSize = reader.ReadInt32(); // in bytes, sizeof(DBC2PalletValue) == 4
int sectionsCount = reader.ReadInt32();

if (sectionsCount == 0 || RecordsCount == 0)
return;

var sections = reader.ReadArray<SectionHeaderWDC4>(sectionsCount);
var sections = (sectionsCount == 0) ? new List<SectionHeaderWDC5>() : reader.ReadArray<SectionHeaderWDC5>(sectionsCount).ToList();
this.m_sections = sections.OfType<IEncryptableDatabaseSection>().ToList();
this.m_encryptedIDs = new Dictionary<ulong, int[]>();

// field meta data
Meta = reader.ReadArray<FieldMetaData>(FieldsCount);

// column meta data
ColumnMeta = reader.ReadArray<ColumnMetaData>(FieldsCount);

if(sectionsCount == 0 || RecordsCount == 0)
return;

this.m_encryptedIDs = new Dictionary<ulong, int[]>();

// pallet data
PalletData = new Value32[ColumnMeta.Length][];
for (int i = 0; i < ColumnMeta.Length; i++)
Expand Down
17 changes: 12 additions & 5 deletions DBCD.IO/Writers/WDC4Writer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ public WDC4Writer(WDC4Reader reader, IDictionary<int, T> storage, Stream stream)
writer.Write(fileOffset); // FileOffset
writer.Write(RecordsCount); // NumRecords
writer.Write(StringTableSize);
writer.Write(0); // OffsetRecordsEndOffset
writer.Write(0); // OffsetRecordsEndOffset, this is set after writing the records for sparse tables
writer.Write(Flags.HasFlagExt(DB2Flags.Index) ? RecordsCount * 4 : 0); // IndexDataSize
writer.Write(referenceDataSize); // ParentLookupDataSize
writer.Write(Flags.HasFlagExt(DB2Flags.Sparse) ? RecordsCount : 0); // OffsetMapIDCount
Expand Down Expand Up @@ -404,7 +404,7 @@ public WDC4Writer(WDC4Reader reader, IDictionary<int, T> storage, Stream stream)
if (Flags.HasFlagExt(DB2Flags.Sparse))
{
long oldPos = writer.BaseStream.Position;
writer.BaseStream.Position = 92;
writer.BaseStream.Position = HeaderSize + 20;
writer.Write((uint)oldPos);
writer.BaseStream.Position = oldPos;
}
Expand All @@ -424,6 +424,10 @@ public WDC4Writer(WDC4Reader reader, IDictionary<int, T> storage, Stream stream)
if (Flags.HasFlagExt(DB2Flags.Sparse))
writer.WriteArray(SparseEntries.Values.ToArray());

// sparse data ids (if flag 0x2 is set)
if (Flags.HasFlagExt(DB2Flags.Sparse) && Flags.HasFlag(DB2Flags.SecondaryKey))
writer.WriteArray(SparseEntries.Keys.ToArray());

// reference data
if (ReferenceData.Count > 0)
{
Expand All @@ -434,12 +438,15 @@ public WDC4Writer(WDC4Reader reader, IDictionary<int, T> storage, Stream stream)
for (int i = 0; i < ReferenceData.Count; i++)
{
writer.Write(ReferenceData[i]);
writer.Write(i);
if (Flags.HasFlag(DB2Flags.SecondaryKey))
writer.Write(SparseEntries.Keys.ElementAt(i));
else
writer.Write(i);
}
}

// sparse data ids
if (Flags.HasFlagExt(DB2Flags.Sparse))
// sparse data ids (if flag 0x2 is not set)
if (Flags.HasFlagExt(DB2Flags.Sparse) && !Flags.HasFlag(DB2Flags.SecondaryKey))
writer.WriteArray(SparseEntries.Keys.ToArray());
}
}
Expand Down
22 changes: 14 additions & 8 deletions DBCD.IO/Writers/WDC5Writer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ private static void WriteFieldValueArray<TType>(BitWriter r, FieldMetaData field

class WDC5Writer<T> : BaseWriter<T> where T : class
{
private const int HeaderSize = 200;
private const int HeaderSize = 204;
private const uint WDC5FmtSig = 0x35434457; // WDC5

public WDC5Writer(WDC5Reader reader, IDictionary<int, T> storage, Stream stream) : base(reader)
Expand Down Expand Up @@ -308,9 +308,8 @@ public WDC5Writer(WDC5Reader reader, IDictionary<int, T> storage, Stream stream)
int maxIndex = storage.Keys.MaxOrDefault();

writer.Write(WDC5FmtSig);
writer.Write((uint)5); // numaric version
writer.Write((uint)5); // numeric version
writer.Write(Encoding.ASCII.GetBytes(staticVersionString.PadRight(128, '\0')));

writer.Write(RecordsCount);
writer.Write(FieldsCount);
writer.Write(RecordSize);
Expand Down Expand Up @@ -345,7 +344,7 @@ public WDC5Writer(WDC5Reader reader, IDictionary<int, T> storage, Stream stream)
writer.Write(fileOffset); // FileOffset
writer.Write(RecordsCount); // NumRecords
writer.Write(StringTableSize);
writer.Write(0); // OffsetRecordsEndOffset
writer.Write(0); // OffsetRecordsEndOffset, this is set after writing the records for sparse tables
writer.Write(Flags.HasFlagExt(DB2Flags.Index) ? RecordsCount * 4 : 0); // IndexDataSize
writer.Write(referenceDataSize); // ParentLookupDataSize
writer.Write(Flags.HasFlagExt(DB2Flags.Sparse) ? RecordsCount : 0); // OffsetMapIDCount
Expand Down Expand Up @@ -410,7 +409,7 @@ public WDC5Writer(WDC5Reader reader, IDictionary<int, T> storage, Stream stream)
if (Flags.HasFlagExt(DB2Flags.Sparse))
{
long oldPos = writer.BaseStream.Position;
writer.BaseStream.Position = 92;
writer.BaseStream.Position = HeaderSize + 20;
writer.Write((uint)oldPos);
writer.BaseStream.Position = oldPos;
}
Expand All @@ -430,6 +429,10 @@ public WDC5Writer(WDC5Reader reader, IDictionary<int, T> storage, Stream stream)
if (Flags.HasFlagExt(DB2Flags.Sparse))
writer.WriteArray(SparseEntries.Values.ToArray());

// sparse data ids (if flag 0x2 is set)
if (Flags.HasFlagExt(DB2Flags.Sparse) && Flags.HasFlag(DB2Flags.SecondaryKey))
writer.WriteArray(SparseEntries.Keys.ToArray());

// reference data
if (ReferenceData.Count > 0)
{
Expand All @@ -440,12 +443,15 @@ public WDC5Writer(WDC5Reader reader, IDictionary<int, T> storage, Stream stream)
for (int i = 0; i < ReferenceData.Count; i++)
{
writer.Write(ReferenceData[i]);
writer.Write(i);
if (Flags.HasFlag(DB2Flags.SecondaryKey))
writer.Write(SparseEntries.Keys.ElementAt(i));
else
writer.Write(i);
}
}

// sparse data ids
if (Flags.HasFlagExt(DB2Flags.Sparse))
// sparse data ids (if flag 0x2 is not set)
if (Flags.HasFlagExt(DB2Flags.Sparse) && !Flags.HasFlag(DB2Flags.SecondaryKey))
writer.WriteArray(SparseEntries.Keys.ToArray());
}
}
Expand Down

0 comments on commit e9ae98c

Please sign in to comment.