From adfd47fc4a1f90c58fd0cb56b046af8f1f2768af Mon Sep 17 00:00:00 2001 From: Drake53 <49623303+Drake53@users.noreply.github.com> Date: Sat, 4 Jul 2026 12:40:02 +0200 Subject: [PATCH 1/5] Changed MpqArchive's `this[int]` from internal to public, and added a `Count` property to go with it. --- src/War3Net.IO.Mpq/MpqArchive.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/War3Net.IO.Mpq/MpqArchive.cs b/src/War3Net.IO.Mpq/MpqArchive.cs index 02c36f23..86b82eb4 100644 --- a/src/War3Net.IO.Mpq/MpqArchive.cs +++ b/src/War3Net.IO.Mpq/MpqArchive.cs @@ -386,6 +386,11 @@ void InsertMpqFile(MpqFile mpqFile, bool updateEndOfStream, bool allowMultiple = } } + /// + /// Gets the size of the , i.e. the exclusive upper bound for . + /// + public int Count => (int)_blockTable.Size; + internal Stream BaseStream => _baseStream; internal MemoryMappedFile? MemoryMappedFile => _memoryMappedFile; @@ -403,7 +408,12 @@ void InsertMpqFile(MpqFile mpqFile, bool updateEndOfStream, bool allowMultiple = internal BlockTable BlockTable => _blockTable; - internal MpqEntry this[int index] => _blockTable[index]; + /// + /// Gets the at the given position in the . + /// + /// The zero-based index of the in the . + /// Thrown when is not a valid index in the . + public MpqEntry this[int index] => _blockTable[index]; /// /// Opens an existing for reading. From 781f2c09267f977d4e93d4de12d03de7d6482996 Mon Sep 17 00:00:00 2001 From: Drake53 <49623303+Drake53@users.noreply.github.com> Date: Sat, 4 Jul 2026 13:03:11 +0200 Subject: [PATCH 2/5] Add MpqArchive.EnumerateHashes method. --- src/War3Net.IO.Mpq/MpqArchive.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/War3Net.IO.Mpq/MpqArchive.cs b/src/War3Net.IO.Mpq/MpqArchive.cs index 86b82eb4..fc7f027f 100644 --- a/src/War3Net.IO.Mpq/MpqArchive.cs +++ b/src/War3Net.IO.Mpq/MpqArchive.cs @@ -759,6 +759,25 @@ public IEnumerable GetMpqEntries(string fileName, MpqLocale? locale = } } + /// + /// Enumerates the 's live entries (i.e. excluding empty and deleted entries). + /// + /// + /// A 's corresponding can be retrieved through , + /// using as the index. + /// + public IEnumerable EnumerateHashes() + { + for (var i = 0; i < _hashTable.Size; i++) + { + var hash = _hashTable[i]; + if (!hash.IsEmpty && !hash.IsDeleted) + { + yield return hash; + } + } + } + // TODO: set hashCollisions values (currently they're always set to 0) public IEnumerable GetMpqFiles() { From 0824765278440175039f6dbc304774634a0447f5 Mon Sep 17 00:00:00 2001 From: Drake53 <49623303+Drake53@users.noreply.github.com> Date: Sat, 4 Jul 2026 13:08:54 +0200 Subject: [PATCH 3/5] This *should* eliminate bounds-checking. --- src/War3Net.IO.Mpq/HashTable.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/War3Net.IO.Mpq/HashTable.cs b/src/War3Net.IO.Mpq/HashTable.cs index ad7d70af..f122f95f 100644 --- a/src/War3Net.IO.Mpq/HashTable.cs +++ b/src/War3Net.IO.Mpq/HashTable.cs @@ -26,7 +26,7 @@ public HashTable(uint size) } _mask = GenerateMask(size); - size = Size; + size = _mask + 1; _hashes = new MpqHash[size]; for (var i = 0; i < size; i++) @@ -103,7 +103,7 @@ internal HashTable(BinaryReader reader, uint size) /// /// Gets the capacity of the . /// - public override uint Size => _mask + 1; + public override uint Size => (uint)_hashes.Length; /// /// Gets the mask for this . From 96b7840f4cd53e42b2313b3bc54c09369baea74c Mon Sep 17 00:00:00 2001 From: Drake53 <49623303+Drake53@users.noreply.github.com> Date: Sat, 4 Jul 2026 13:13:25 +0200 Subject: [PATCH 4/5] Change MpqTable.Size from uint to int. --- src/War3Net.IO.Mpq/BlockTable.cs | 2 +- src/War3Net.IO.Mpq/HashTable.cs | 4 ++-- src/War3Net.IO.Mpq/MpqArchive.cs | 13 ++++++++++--- src/War3Net.IO.Mpq/MpqTable.cs | 4 ++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/War3Net.IO.Mpq/BlockTable.cs b/src/War3Net.IO.Mpq/BlockTable.cs index 220c59fc..45d6aeeb 100644 --- a/src/War3Net.IO.Mpq/BlockTable.cs +++ b/src/War3Net.IO.Mpq/BlockTable.cs @@ -59,7 +59,7 @@ internal BlockTable(BinaryReader reader, uint size, uint headerOffset) /// /// Gets the capacity of the . /// - public override uint Size => (uint)_entries.Count; + public override int Size => _entries.Count; /// /// Gets the key used to encrypt and decrypt the . diff --git a/src/War3Net.IO.Mpq/HashTable.cs b/src/War3Net.IO.Mpq/HashTable.cs index f122f95f..634817ff 100644 --- a/src/War3Net.IO.Mpq/HashTable.cs +++ b/src/War3Net.IO.Mpq/HashTable.cs @@ -103,7 +103,7 @@ internal HashTable(BinaryReader reader, uint size) /// /// Gets the capacity of the . /// - public override uint Size => (uint)_hashes.Length; + public override int Size => _hashes.Length; /// /// Gets the mask for this . @@ -207,7 +207,7 @@ private void TryAdd(MpqHash hash, uint index, uint hashCollisions) var startIndex = (int)index - (int)hashCollisions; if (startIndex < 0) { - startIndex += (int)Size; + startIndex += Size; } for (var i = 0; i < hashCollisions; i++) diff --git a/src/War3Net.IO.Mpq/MpqArchive.cs b/src/War3Net.IO.Mpq/MpqArchive.cs index fc7f027f..a766e36c 100644 --- a/src/War3Net.IO.Mpq/MpqArchive.cs +++ b/src/War3Net.IO.Mpq/MpqArchive.cs @@ -366,7 +366,14 @@ void InsertMpqFile(MpqFile mpqFile, bool updateEndOfStream, bool allowMultiple = writer.Seek((int)_headerOffset, SeekOrigin.Begin); - _mpqHeader = new MpqHeader((uint)_headerOffset, (uint)(endOfStream - fileOffset), _hashTable.Size, _blockTable.Size, createOptions.BlockSize, _archiveFollowsHeader); + _mpqHeader = new MpqHeader( + (uint)_headerOffset, + (uint)(endOfStream - fileOffset), + (uint)_hashTable.Size, + (uint)_blockTable.Size, + createOptions.BlockSize, + _archiveFollowsHeader); + _mpqHeader.WriteTo(writer); if (wantGenerateSignature) @@ -389,7 +396,7 @@ void InsertMpqFile(MpqFile mpqFile, bool updateEndOfStream, bool allowMultiple = /// /// Gets the size of the , i.e. the exclusive upper bound for . /// - public int Count => (int)_blockTable.Size; + public int Count => _blockTable.Size; internal Stream BaseStream => _baseStream; @@ -807,7 +814,7 @@ public IEnumerable GetMpqFiles() } } - for (var i = 0; i < (int)_blockTable.Size; i++) + for (var i = 0; i < _blockTable.Size; i++) { var mpqEntry = _blockTable[i]; if (!addedEntries.Contains(mpqEntry)) diff --git a/src/War3Net.IO.Mpq/MpqTable.cs b/src/War3Net.IO.Mpq/MpqTable.cs index a2704ec8..9bb2a36d 100644 --- a/src/War3Net.IO.Mpq/MpqTable.cs +++ b/src/War3Net.IO.Mpq/MpqTable.cs @@ -20,7 +20,7 @@ internal MpqTable() /// /// Gets the capacity of the . /// - public abstract uint Size { get; } + public abstract int Size { get; } /// /// Gets the key used to encrypt and decrypt the . @@ -106,7 +106,7 @@ private byte[] GetEncryptedData() using (var reader = new BinaryReader(memoryStream)) { - data = reader.ReadBytes((int)Size * EntrySize); + data = reader.ReadBytes(Size * EntrySize); Encrypt(data); } } From 3028da860882b1457e35009d71baf56455ba8f26 Mon Sep 17 00:00:00 2001 From: Drake53 <49623303+Drake53@users.noreply.github.com> Date: Sat, 4 Jul 2026 13:20:45 +0200 Subject: [PATCH 5/5] Update versions+changelogs. --- Directory.Packages.props | 8 ++++---- docs/changelogs/War3Net.Build.Core.changelog.md | 4 ++++ docs/changelogs/War3Net.Build.changelog.md | 4 ++++ docs/changelogs/War3Net.IO.Mpq.changelog.md | 5 +++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 7247a19e..b58c3ca7 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -33,10 +33,10 @@ - - + + - + @@ -46,7 +46,7 @@ - + diff --git a/docs/changelogs/War3Net.Build.Core.changelog.md b/docs/changelogs/War3Net.Build.Core.changelog.md index 20bb036d..c9bd614e 100644 --- a/docs/changelogs/War3Net.Build.Core.changelog.md +++ b/docs/changelogs/War3Net.Build.Core.changelog.md @@ -1,5 +1,9 @@ # War3Net.Build.Core Changelog +## v6.0.3 +### Changes +- Updated War3Net.IO.Mpq from v6.0.2 to v6.0.3. + ## v6.0.2 ### Breaking changes - Updated target framework from .NET 5.0 to .NET 6.0. diff --git a/docs/changelogs/War3Net.Build.changelog.md b/docs/changelogs/War3Net.Build.changelog.md index 2c223ef4..7ed725e7 100644 --- a/docs/changelogs/War3Net.Build.changelog.md +++ b/docs/changelogs/War3Net.Build.changelog.md @@ -1,5 +1,9 @@ # War3Net.Build Changelog +## v6.0.3 +### Changes +- Updated War3Net.Build.Core from v6.0.2 to v6.0.3. + ## v6.0.2 ### Breaking changes - Updated target framework from .NET 5.0 to .NET 6.0. diff --git a/docs/changelogs/War3Net.IO.Mpq.changelog.md b/docs/changelogs/War3Net.IO.Mpq.changelog.md index 840f1483..6d180109 100644 --- a/docs/changelogs/War3Net.IO.Mpq.changelog.md +++ b/docs/changelogs/War3Net.IO.Mpq.changelog.md @@ -1,5 +1,10 @@ # War3Net.IO.Mpq Changelog +## v6.0.3 +### Changes +- Added `Count` and `EnumerateHashes()` to `MpqArchive`. +- Changed `MpqArchive[int]` from internal to public. + ## v6.0.2 ### Breaking changes - `Attributes.Crc32s` changed from `List` to `List`, matching the actual unsigned nature of CRC32 values.