acdream/tests/AcDream.Core.Net.Tests/Messages
Erik bcfddc97e7 feat(CT): CT2 — Runtime character-title ownership + wire
Campaign CT slice CT2: the client now learns the character's earned
titles and current display title from the server, owns that state in
Runtime, and can send a display-title change. No UI (CT3/CT4).

Wire (Core.Net):
- GameEvents.ParseCharacterTitleTable (0x0029 CharacterTitle): retail
  CharacterTitleTable::UnPack @0x005c6e90 skips a leading u32 into no
  field — its own Pack @0x005c6e40 always writes the literal 1 there,
  matching ACE's unconditional Writer.Write(1u) — then reads
  displayTitleId, then a count-prefixed PList<uint> of earned ids.
- GameEvents.ParseUpdateTitle (0x002B UpdateTitle): titleId +
  setAsDisplay, per CM_Social::DispatchUI_AddOrSetCharacterTitle
  @0x006a54c0 -> Handle_Social__AddOrSetCharacterTitle @0x00564260,
  which ALWAYS adds (SendNotice_AddCharacterTitle, unconditional) and
  additionally sets display only when setAsDisplay != 0
  (SendNotice_SetDisplayCharacterTitle, gated).
- SocialActions.BuildTitleSet / WorldSession.SendSetTitle: outbound
  TitleSet (0x002C), u32 titleId, matching ACE's GameActionSetTitle.
- GameEventWiring gains onCharacterTitleTable/onUpdateTitle delegate
  holes (Core.Net cannot reference AcDream.Runtime directly).

Runtime:
- New RuntimeCharacterTitleState (RuntimeCharacterState.Titles): earned
  title id set + display title id, TableReplaced/TitleAdded/
  DisplayTitleChanged events matching retail's unconditional-add /
  gated-display-set contract, clears at generation reset.
  RuntimeCharacterOwnershipSnapshot/CaptureOwnership/IsConverged and
  RuntimeCharacterSnapshot extended (trailing optional fields, no
  existing call site broken).
- IRuntimeCharacterCommands.SetTitle: generation-gated, sends
  TitleSet only — NO optimistic local mutation. Verified against
  retail's own CM_Social::Event_SetDisplayCharacterTitle @0x006a5720,
  which sends the wire message and touches no local field; the display
  title updates only from the server's own echo (the CA-campaign
  lesson: never re-add an optimistic write). Implemented on both hosts
  (DirectGameRuntimeCommandAdapter direct-send;
  CurrentGameRuntimeCommandAdapter via LiveCommandBus /
  LiveSessionCommandRouter's new SetTitleRuntimeCmd).
- LiveSessionEventRouter wires the two inbound events unconditionally
  (RuntimeCharacterState.Titles is a required child, not an optional
  sibling like Fellowship/Allegiance).

App (non-UI plumbing + resolver):
- CharacterTitleResolver (src/AcDream.App/UI/Layout/): ports
  CharacterTitleTable::GetCharacterTitleFromID @0x005c6ed0 — titleId ->
  EnumMapper(0x22000041) canonical key -> compute_str_hash ->
  StringTable(0x2300000E) localized text. Runtime stays id-only; CT3/
  CT4 consume this for display. DIDs hardcoded per the RetailKeyNames
  precedent (CT1 verified them end-to-end).

Register: no new row. Retail's send path is non-optimistic and so is
ours — no deviation to record for this slice.

Tests: wire conformance (byte-exact + truncation) in
CharacterTitleEventsTests.cs + SocialActionsTests.cs; Runtime owner
unit tests in RuntimeCharacterTitleStateTests.cs plus integration in
RuntimeCharacterStateTests.cs; a no-local-mutation command test in
DirectGameRuntimeCommandAdapterTests.cs; an InstalledDat pin
(CharacterTitleResolverLiveDatTests.cs, ids 0/1/2/3/5/13/14, run green
with ACDREAM_RUN_INSTALLED_DAT_TESTS=1). Full solution build green;
hermetic filtered suite green (15,380 passed / 0 failed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 22:03:22 +02:00
..
AceWireWriter.cs fix(chat): Campaign CH user-gate round 1 — jump-in-air edge, portal cue cadence, wrap/prefix/color fixes 2026-08-09 23:42:32 +02:00
AllegianceProfileVersionGateTests.cs fix(net): FA1 review round -- zero-id tree rejection, monarch clear, 0x001F builder 2026-08-12 00:46:42 +02:00
AllegianceRequestsTests.cs fix(net): FA1 review round -- zero-id tree rejection, monarch clear, 0x001F builder 2026-08-12 00:46:42 +02:00
AllegianceSmallEventsTests.cs feat(net): FA1 -- S->C parsers for fellowship/allegiance, confirmation triple, allegiance version gates 2026-08-12 00:13:10 +02:00
AppraiseInfoParserTests.cs fix #234: port retail appraisal floaty and inscriptions 2026-07-23 12:12:57 +02:00
AppraiseTests.cs fix(gameplay): reconcile wield ownership and target facing 2026-07-15 08:19:23 +02:00
AutonomousPositionTests.cs feat(L.2b): outbound movement wire parity — RawMotionState default-difference, JumpPack, contact byte 2026-06-30 22:30:01 +02:00
CastSpellTests.cs test: remove exact duplicate coverage 2026-08-18 12:36:41 +02:00
CharacterActionsTests.cs fix(net): xpSpent is a dword on the wire, and we were sending eight bytes 2026-07-29 01:59:47 +02:00
CharacterCreateTests.cs feat(net,runtime): Campaign CC CC2 — CharacterCreate wire, 0xF643 correlation, creation status events 2026-08-15 12:49:52 +02:00
CharacterDeleteTests.cs feat(net): Campaign LA LA7a — CharacterDelete/CharacterRestore/CharacterError wire messages 2026-08-14 15:46:48 +02:00
CharacterEnterWorldTests.cs perf(net): frame recurring sends in place 2026-07-25 06:02:52 +02:00
CharacterErrorTests.cs feat(net): Campaign LA LA7a — CharacterDelete/CharacterRestore/CharacterError wire messages 2026-08-14 15:46:48 +02:00
CharacterListTests.cs fix(net): conform character entry and session shutdown 2026-07-21 10:33:03 +02:00
CharacterLogOffTests.cs fix(net): conform character entry and session shutdown 2026-07-21 10:33:03 +02:00
CharacterRestoreTests.cs fix(net): Campaign LA LA7a review fixes — AD-97 register row, corrected restore justification 2026-08-14 16:01:52 +02:00
CharacterTitleEventsTests.cs feat(CT): CT2 — Runtime character-title ownership + wire 2026-08-24 22:03:22 +02:00
CharGenVerificationResponseTests.cs feat(net,runtime): Campaign CC CC2 — CharacterCreate wire, 0xF643 correlation, creation status events 2026-08-15 12:49:52 +02:00
ChatTests.cs fix(net): ranged speech carries a range float our parser was eating 2026-07-29 01:51:34 +02:00
ClientCommandRequestsTests.cs feat(chat): port retail's @pklite client command (EnterPkLite 0x028F) 2026-08-03 18:57:17 +02:00
ClientCommandResponsesTests.cs fix(net): FA1 review round -- zero-id tree rejection, monarch clear, 0x001F builder 2026-08-12 00:46:42 +02:00
CombatEventTests.cs fix(net): Phase L.1c conform combat wire events 2026-04-28 10:54:50 +02:00
ConfirmationTripleTests.cs feat(net): FA1 -- S->C parsers for fellowship/allegiance, confirmation triple, allegiance version gates 2026-08-12 00:13:10 +02:00
ContractTrackerMessagesTests.cs fix(journal): the location readout is a FIELD, refresh at the click, and Abandon works 2026-08-21 16:19:18 +02:00
CreateObjectTests.cs fix(physics): AP-129 review fix - port CanMoveInto/IsAllowedIn, stop failing closed 2026-07-30 11:36:11 +02:00
DeleteObjectTests.cs feat(net): port retail physics spawn and event timestamps 2026-07-14 00:22:17 +02:00
EmoteTextTests.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
FellowshipEventsTests.cs fix(net): FA1 review round -- zero-id tree rejection, monarch clear, 0x001F builder 2026-08-12 00:46:42 +02:00
GameActionLoginCompleteTests.cs feat(net): Phase 4.8 — send GameAction.LoginComplete after EnterWorld 2026-04-11 23:36:19 +02:00
GameEventDispatcherTests.cs fix(net): stop dropping every transient string on a chat type that isn't sent 2026-07-29 01:58:02 +02:00
GameEventsInventoryTests.cs fix(net): D.2b-B B-Wire — ParseInventoryServerSaveFailed reads weenieError 2026-06-21 18:55:56 +02:00
HearSpeechGoldenTests.cs fix(net): ranged speech carries a range float our parser was eating 2026-07-29 01:51:34 +02:00
HouseEventsTests.cs feat(net): Map/House panel — slice 4a, House wire parsing groundwork 2026-08-17 02:09:34 +02:00
InteractRequestsTests.cs test(B.5): exercise i32 sign-correctness for BuildPickUp.placement 2026-05-14 15:05:07 +02:00
InventoryActionsTests.cs fix #234: port retail appraisal floaty and inscriptions 2026-07-23 12:12:57 +02:00
InventoryRemoveObjectTests.cs feat(net): D.2b-B B-Wire — InventoryRemoveObject (0x0024) parser 2026-06-21 18:52:21 +02:00
JumpActionTests.cs feat(L.2b): outbound movement wire parity — RawMotionState default-difference, JumpPack, contact byte 2026-06-30 22:30:01 +02:00
MoveToStateGoldenTests.cs feat(L.2b): outbound movement wire parity — RawMotionState default-difference, JumpPack, contact byte 2026-06-30 22:30:01 +02:00
MoveToStateTests.cs feat(L.2b): outbound movement wire parity — RawMotionState default-difference, JumpPack, contact byte 2026-06-30 22:30:01 +02:00
ObjDescEventTests.cs feat(net): port retail physics spawn and event timestamps 2026-07-14 00:22:17 +02:00
ParentEventTests.cs feat(combat): port retail held weapon parenting 2026-07-11 13:02:26 +02:00
PickupEventTests.cs fix(B.5): handle PickupEvent 0xF74A so picked-up items despawn locally 2026-05-14 16:13:16 +02:00
PlayerKilledTests.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
PlayScriptGoldenTests.cs test(net): generate wire fixtures from ACE's own writer, not hand-typed hex 2026-07-29 01:49:15 +02:00
PositionPackTests.cs feat(L.2b): outbound movement wire parity — RawMotionState default-difference, JumpPack, contact byte 2026-06-30 22:30:01 +02:00
PrivateUpdatePropertyInt64Tests.cs fix(ui): port live experience quality updates (#217) 2026-07-13 20:43:48 +02:00
PrivateUpdatePropertyIntTests.cs feat(net): D.2b-B B-Wire — PrivateUpdatePropertyInt (0x02CD) parser 2026-06-21 18:50:56 +02:00
ProjectileVfxPacketFixtures.cs feat(net): port retail physics spawn and event timestamps 2026-07-14 00:22:17 +02:00
PublicUpdatePropertyIntTests.cs feat(D.5.2): PublicUpdatePropertyInt (0x02CE) parser 2026-06-17 18:29:23 +02:00
RawMotionStatePackTests.cs feat(L.2b): outbound movement wire parity — RawMotionState default-difference, JumpPack, contact byte 2026-06-30 22:30:01 +02:00
ServerMessageTests.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
ServerNameTests.cs fix(ui,net): Campaign LA gate round 2 — char-select exit confirmation, authored row justify, world name 2026-08-15 11:50:45 +02:00
SetStackSizeTests.cs feat(net): D.2b-B B-Wire — SetStackSize (0x0197) parser 2026-06-21 18:51:42 +02:00
SetStateTests.cs feat(phys L.2g slice 1): inbound SetState (0xF74B) parser 2026-05-12 22:15:31 +02:00
SetTurbineChatChannelsTests.cs feat(net+chat): #19 TurbineChat (0xF7DE) codec + ChatChannelInfo + SetTurbineChatChannels parser 2026-04-25 19:44:56 +02:00
SocialActionsTests.cs feat(CT): CT2 — Runtime character-title ownership + wire 2026-08-24 22:03:22 +02:00
SocialStateMessagesTests.cs feat(chat): port retail client command families 2026-07-13 14:50:15 +02:00
SoulEmoteTests.cs feat(net): #18 holtburger inbound chat parity - EmoteText, SoulEmote, ServerMessage, PlayerKilled, WeenieError + Windows-1252 codec 2026-04-25 19:06:01 +02:00
SoundEventTests.cs feat(audio): Campaign A slice A3 — the server sound channel (0xF750) 2026-08-08 22:07:23 +02:00
TradeRequestsTests.cs feat: secure trade with other players - wire, RuntimeTradeState, the 2026-08-14 11:49:13 +02:00
TurbineChatTests.cs feat(net+chat): #19 TurbineChat (0xF7DE) codec + ChatChannelInfo + SetTurbineChatChannels parser 2026-04-25 19:44:56 +02:00
UpdateMotionTests.cs feat(R4-V3): wire completion - mt 8/9 parsing + full params exposure + the mt-0 sticky trailer (closes M7, M13, M14-wire-note) 2026-07-03 11:53:53 +02:00
UpdatePositionTests.cs feat(net): port retail physics spawn and event timestamps 2026-07-14 00:22:17 +02:00
VectorUpdateGoldenTests.cs test(net): generate wire fixtures from ACE's own writer, not hand-typed hex 2026-07-29 01:49:15 +02:00
VendorApproachTests.cs fix(runtime/core): Slice 5.3 review corrections — retirement/transit close, per-unit pricing, guarded auto-close dispatch 2026-08-07 16:15:57 +02:00
VendorRequestsTests.cs feat(vendor): Slice 6b/6c — move-to-use, buy staging, selling; the vendor arc is functionally complete 2026-08-08 11:43:11 +02:00