Skip to content

Networking updates - #16

Merged
baughj merged 9 commits into
mainfrom
feat/protocol-enums
Jul 7, 2026
Merged

Networking updates#16
baughj merged 9 commits into
mainfrom
feat/protocol-enums

Conversation

@baughj

@baughj baughj commented Jul 7, 2026

Copy link
Copy Markdown
Member
  • Remove unnecessary enums; only model what's needed
  • update 0x56; several things use / send busted CRC
  • bugfixing from Brigid testing / Hybrasyl usage / retail usage

baughj and others added 9 commits June 27, 2026 16:37
Add 13 wire enums in a new DALib.Enums namespace (one file per enum) — the
set Brigid needs but DALib lacked: Element, Class, Nation, Stat, PanelType,
EntityType, BodySprite, BodyAnimation, LanternSize, NameTagStyle,
RestPosition, MetaDataRequestType, DisplayColor.

Values are the retail DOOMVAS wire encoding, validated against the
Chaos.DarkAges package Brigid runs on today. Labels follow the policy ladder
retail > Hybrasyl ecosystem > neutral-canonical, never Chaos editorial:
Element uses retail Light/Dark/Undead per the Darkages.exe string table
@0x00685564 (not Chaos's Holy/Darkness/Nature); DisplayColor uses the
Hybrasyl ItemColor names over the fixed retail dye palette.

Meaningful enums carry per-member XML docs; DisplayColor/BodyAnimation
suppress CS1591 (self-evident dye/emote identifiers). DALib builds clean
(0 errors, 0 warnings).

Relocating Direction/Gender/EquipmentSlot into DALib.Enums and the Brigid
retype follow in subsequent commits.

Co-Authored-By: Imbas <imbas@eris.co>
Claude-Session: https://claude.ai/code/session_015R7kqiamfUFqC6m59Qrd12
…nums

Complete the DALib.Enums consolidation begun in the prior commit. Move the
three protocol enums that already existed elsewhere into the new namespace so
all wire enums live in one place:

- Direction, Gender: out of DALib/Definitions/Enums.cs (file-format enums stay)
- EquipmentSlot: out of DALib/Networking/Packets/Server/ (git-tracked rename)

All three move to namespace DALib.Enums. Consumers retyped: 11 library files
and 10 test files (using DALib.Definitions -> using DALib.Enums where Definitions
became unused; added using DALib.Enums where EquipmentSlot was previously in
the consumer's own namespace). Cross-namespace XML crefs fully qualified
(EquipmentSlot -> Add/RemoveEquipmentPacket; CreateCharFinalizePacket -> Gender).

The Wire/ files matching \bDirection\b reference IPacket.Direction (the packet
direction property), not the movement enum, and are untouched; UserAppearance
and DrawObjects carry Direction as a raw byte and take no enum import.

DALib builds clean (0 errors, 0 warnings); 866/866 tests pass.

Co-Authored-By: Imbas <imbas@eris.co>
Claude-Session: https://claude.ai/code/session_01WxPEox85M2tn3vPWk8hQVR
Retail (USDA) protocol details DALib's self-round-trip tests couldn't catch,
found while live-testing the Brigid client:

- Server parsers (LoginNotification, Attributes, NpcMenu, NpcDialog, Url):
  tolerate a trailing byte instead of throwing. DOOMVAS Normal/MD5Key
  encryption appends an inner-pad byte (0x00, or 0x00+opcode) before the rand
  footer; DecryptServer strips only the footer, leaving the pad. The proper
  fix (strip the inner-pad in DecryptServer) is deferred.
- UserListPacket (0x36): the two leading u16 counts are total-online-across-
  shards and current-shard-count. Use the second (= rows actually present)
  rather than the first, and stop defensively if the body can't hold another
  entry. Fixes a read overrun on the who-list.
- Update the NpcMenuPacket trailing-byte test to assert tolerance.

868/868 tests pass.

Co-Authored-By: Imbas <imbas@eris.co>
Claude-Session: https://claude.ai/code/session_01GTpZdtSiFfPGWd2zUDCWWQ
…sed Nation enum

Apply the 1.0.0 release scrub conventions to the comments added on this
branch: remove reverse-engineering provenance and reference-server
names (binary name-table reference, proxy/RE markers, "Chaos calls
this..." labels), strip the ecosystem cross-references, and normalize
the affected comments to US-ASCII.

Also remove the Nation enum. It is unused in DALib: nation appears only
as the raw byte NationFlag in the profile packets, and the type is a
server-specific implementation detail with no wire-modeling role.

Co-Authored-By: Imbas <imbas@eris.co>
Claude-Session: https://claude.ai/code/session_01An6BcJ6oxzHZb3Z6VPoRS8
The Dark Ages wire protocol (metafile/notice/server-table checksums) uses a
CRC-32 that omits the standard final inversion. CRC32.Calculate previously
always applied it (return ~result), matching zlib/PNG but not the DA wire.

Add an optional finalXor parameter (default true, so the existing zlib
behavior and all current callers are unchanged); DA-protocol callers pass
false. This lets the Brigid client compute metafile/notice CRCs that match
server-sent values without depending on Chaos.Cryptography.

Co-Authored-By: Imbas <imbas@eris.co>
Claude-Session: https://claude.ai/code/session_012nhijk3Dvi3JsxLCYfJBSG
Remove six enums that don't belong in a wire-protocol library, on the
same principle that dropped Nation: each is either game/server semantics
or unused reference data, and none is load-bearing for (de)serialization.

- Element: game mechanics; zero references in DALib.
- Class: server/game content; every wire field was already a raw byte,
  so no field changes were needed.
- DisplayColor, BodyAnimation: client-rendering reference vocabularies
  with zero references.
- MetaDataRequestType: redundant; RequestMetafilePacket already models
  the discriminator as a bool + name.
- PanelType: unused and mismatched with its only intended home
  (SwapSlot's Window is 0-2; this carried an extra Equipment=3).

Content domains a server may define differently stay as bytes on the
wire; consumers reconstitute their own enums at the boundary with a
zero-cost cast. Build clean; 868 tests green.

Co-Authored-By: Imbas <imbas@eris.co>
Claude-Session: https://claude.ai/code/session_01An6BcJ6oxzHZb3Z6VPoRS8
Hybrasyl's lobby emits the 0x56 ServerTableData zlib stream with a bogus
Adler-32 trailer (always 0x00000001, the checksum of empty input) because
ZlibCompression.Compress checksums the stream before rewinding it to 0. The
DEFLATE body is correct; only the trailer is wrong. The retail client and the
servers' own decompressors never validate the trailer, so a strict reader is
stricter than the ecosystem.

ServerTableDataPacket.Decompress used .NET's ZLibStream, which validates the
trailer, and threw "unsupported compression method" on the malformed stream --
breaking the lobby handshake for any consumer connecting to such a server. Raw-
inflate the DEFLATE body directly (skip the 2-byte header + 4-byte trailer) to
match the ecosystem. Compress still writes a correct zlib stream, so round-trip
stays clean.

Regression test pins the exact bytes captured live from a real server. Full
suite green (869).

Co-Authored-By: Imbas <imbas@eris.co>
Claude-Session: https://claude.ai/code/session_01D2jGa4M7BwbLJAfoJbj93n
@baughj
baughj merged commit baa15c0 into main Jul 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant