warcrafty 2.1.2
warcrafty: ^2.1.2 copied to clipboard
A high-performance pure Dart library for reading and writing World of Warcraft DBC files and MPQ archives.
2.1.2 #
Fixed #
- 8-bit fields in five predefined schemas read back as signed
int8— the 8/16/64-bit integer type support (2.0.0) mapped WoWDBDefs' bare<8>tokens to signedint8(B) inCharBaseInfo,CharStartOutfit,PowerDisplay,SpellChainEffects, andSpellItemEnchantmentCondition. WoWDBDefs has no signed 8-bit token (<s8>appears nowhere in its definitions; later builds spell the same fields<u8>), and AzerothCore reads these fields asuint8, so bare<8>is unsigned. Current data (values 0-5) parses identically either way, butuint8is the correct physical format for 3.3.5a. The definition generator now maps all 8-bit fields touint8(b) and the five schemas were regenerated to match
2.1.1 #
Fixed #
- Published 2.1.0 was not importable either — the
.pubignoreentrydbc/matchedlib/src/dbc/at any depth (gitignore semantics), stripping the DBC implementation from the package and breaking every definition import (6038 errors). All.pubignorepatterns are now anchored to the repo root (/dbc/,/tool/,/CLAUDE.md) - Added
tool/check_publish.dart— parses thedart pub publish --dry-runfile tree and fails if the public entry point or either subsystem directory is missing from the package, preventing silent packaging regressions. Run it before publishing
2.1.0 #
Added #
- Pure Dart MPQ Archive Support
- Read and write Blizzard MPQ archives (v1 ≤4 GB, v2 with 64-bit offsets and hi-block table) with no native library — StormLib FFI removed
- Decompression for zlib, PKWARE DCL (implode), bzip2, and sparse, including arbitrary multi-method combinations (order mirrors StormLib's
dcmp_table) - Writing via zlib, sparse, or stored sectors, with per-sector fallback to plain data when compression gains nothing
- Read support for encrypted files,
MPQ_FILE_KEY_V2offset/size-adjusted keys,SINGLE_UNITfiles, and hi-block tables - Optional per-sector Adler-32 verification (
checkSectorCrc), matching StormLib'sMPQ_OPEN_CHECK_SECTOR_CRCopt-in semantics — checksum blocks are unencrypted and stored after the last sector MpqArchiveCRUD (extract/extractTo/addFile/removeFile/compact),MpqArchive.create()/open()with deferred table flush onclose()compact()copies blocks directly (re-encryptingKEY_V2keys for their new offsets) instead of recompressing; files missing from(listfile)are preserved under reversible(pseudo)\XXXXXXXXnames and the listfile is rebuilt- Dedicated exception hierarchy:
MpqOpenException,MpqFileNotFoundException,MpqReadException,MpqWriteException,MpqRemoveException,MpqCompactException,MpqExtractException,MpqCompressionException,MpqCorruptException
Fixed #
- Published 2.0.0 was not importable — its
warcrafty.dartexportedsrc/dbc/*paths that did not exist in the package (the source-tree reorganization shipped half-finished); importing the package failed to compile. The DBC implementation moved tosrc/dbc/and all exports resolve - MPQ compact could silently drop files — compaction iterated the
(listfile)contents, so an archive with a missing or stripped listfile (common in patch packs) would have its unreferenced files deleted; it now copies from the block table keyed by the hash table and preserves unknown names as pseudo-names, refusing withMpqCompactExceptionwhen a block is unrecognizable - Decompression had no output bound — a malicious archive could declare a 4 GB sparse length header or oversized bzip2/zlib output and trigger multi-gigabyte allocations; sparse, bzip2, and zlib now enforce the expected sector/file size as a hard cap (matching StormLib's
DecompressSparsecheck), and a zero-length sparse header now decompresses to empty instead of erroring close()could corrupt an existing archive on hash-table exhaustion — the(listfile)slot is now reserved up front; writes that would leave no room for it fail before touching the disk instead of afterKEY_V2re-encryption during compact used the old data offset — keys are now recomputed for the destination position, keeping encrypted files readable after compaction- 32-bit sector offsets overflowed past 2 GB — sector offset tables now use
Uint32List/List<int>, and per-sector offsets are checked for monotonicity and sector-size bounds MpqArchive.open()now wraps filesystem failures inMpqOpenExceptioninstead of leakingFileSystemException;removeFilerejects internal files; compact failures are consistently reported asMpqCompactException- Removed the
compressBzip2write constant that always failed — writing supports zlib and sparse only
2.0.0 #
Added #
- Explicit Format Dialects
- Added
DbcFormatDialect.warcraftyas the default extended typed dialect - Added
DbcFormatDialect.azerothCorefor AzerothCore/TrinityCoreDBCfmt.hcompatibility (x X s f i b d n l) DbcLoader,DbcWriter,DbcSchema, andFieldOffsetsnow carry dialect information- AzerothCore dialect interprets
iasuint32, while the default Warcrafty dialect keepsiasint32and usesuforuint32
- Added
Changed #
- Documentation now describes AzerothCore format strings as a supported dialect rather than claiming all Warcrafty extended format strings are directly valid in AzerothCore
DBCfmt.h
Note: the published 2.0.0 package was not importable (broken export paths); use 2.1.0+.
1.0.2 #
Fixed #
- Locstring Flag Field Type Mismatch
- Corrected the format string for
locstringfields: the 17th slot (locale flags) is nowint32(i) instead ofstring(s), matching the field definitions produced bycreateLocaleFieldsWithFlag(16 strings + 1 int32 flag) - This resolves a type mismatch between import and export: the flag field was previously read as a
Stringon load (viatoMap()) and expected as aStringon write, corrupting non-zero locale flags and breaking round-trip write of records carrying int flag values - Record size and field offsets are unchanged (
sandiare both 4 bytes); only the type dispatch at the flag position is corrected - Regenerated all 245 predefined schemas from the fixed generator
- Corrected the format string for
Changed #
DbcRecord.toMap()now returns anintfor locale flag fields (previously aStringparsed from the flag bitmask). Direct accessorsgetInt/getStringare unaffected because they already read raw bytes by offset
Added #
- Schema Consistency Test: asserts
format[i] == fields[i].type.characross all 245 predefined schemas, preventing format/field drift regressions - Locstring Round-Trip Test: verifies locale flag fields write and read back as
int
1.0.1 #
Fixed #
- Exception Handling
- Replace
FormatExceptionwithDbcFormatExceptionfor consistent error handling across DBC operations - Improved error specificity for format-related issues
- Replace
Refactored #
- Code Cleanup
- Removed redundant
fieldOffsetsgetter fromDbcLoader - Simplified
loader.dartby eliminating unnecessary field offset delegation - Updated
DbcIndexto directly access field offsets from loader's internal structure
- Removed redundant
1.0.0 #
Added #
-
Core DBC Operations
DbcLoader- Read DBC files with sync/async supportDbcWriter- Write DBC files with string deduplicationDbcRecord- Access record fields with type-safe methodsDbcIndexBuilder- Build ID-based indexes with O(1) lookup
-
Locale Field Utilities (
locale_fields.dart)createLocaleFields()- Generate field definitions for 16 languagescreateLocaleFieldsWithFlag()- Generate locale fields with flag fieldcreateUnusedFields()- Generate unused field definitionscreateIntFields()- Generate consecutive integer field definitions
-
Type Validation in DbcWriter
- Validate field types before writing (int, float, string, bool)
- Range checking for byte fields (0-255)
- Friendly error messages with record and field index
-
100+ Predefined DBC Formats
- Achievement, Character, Creature, Faction formats
- Item, Map, Quest, Skill, Spell formats
- Vehicle, GT tables, and more
-
String Block Handler
- O(1) string lookup with prebuilt index
- Efficient string deduplication on write
Changed #
- Refactored
DbcWriterto extract_collectStrings()and_validateFieldType()methods