using AcDream.Core.Chat; using AcDream.Runtime.Chat; using AcDream.Runtime.Gameplay; namespace AcDream.Runtime.Tests.Chat; public sealed class LiveChatCommandRouteTests { [Fact] public void FourRegistrationsPreserveOrderedWireRoutesAndCanonicalEcho() { using var communication = new RuntimeCommunicationState(); using var character = new RuntimeCharacterState(); var sent = new List(); var route = new LiveChatCommandRoute(new LiveChatCommandBindings( command => sent.Add($"client:{command.Command}"), communication, communication.Chat, communication.TurbineChat, character, () => 0x50000001u, text => sent.Add($"talk:{text}"), (target, text) => sent.Add($"tell:{target}:{text}"), (channel, text) => sent.Add($"channel:{channel:X8}:{text}"), (_, _, _, _, text, _) => sent.Add($"turbine:{text}"))); route.Activate(); route.Publish(new SendServerCommandCmd("@server")); route.Publish(new SendChatCmd(ChatChannelKind.Say, null, "say")); route.Publish(new SendChatCmd(ChatChannelKind.Tell, "Bob", "secret")); route.Publish(new SendChatCmd( ChatChannelKind.Fellowship, null, "group")); route.Publish(new SendRawChannelCmd(0x00000002u, "admin")); route.Publish(new ExecuteClientCommandCmd( ClientCommandId.QueryAge, string.Empty)); Assert.Equal( [ "talk:@server", "talk:say", "tell:Bob:secret", "channel:00000800:group", "channel:00000002:admin", "client:QueryAge", ], sent); // A tell is SENT and nothing is echoed locally. The server returns the // "You tell Bob, ..." line itself (ACE GameActionTell -> // GameMessageSystemChat with ChatMessageType.OutgoingTell), and retail's // own send path @0x00577CF4 has no AddTextToScroll beside it — so an // optimistic echo here printed every tell TWICE in the chat window. // Say has always relied on the server echo for exactly this reason. Assert.Empty(communication.Chat.Snapshot()); route.Dispose(); route.Publish(new SendServerCommandCmd("@stale")); Assert.Equal(6, sent.Count); } }