fix: trade gate round 2 - the trade window is state-managed, never

layout-persisted; deeper [trade] wire probes

A session that ended mid-trade saved Visible=true for "secure-trade" in
the window-layout file, restoring an empty open trade window at every
launch. Added to the stateManagedVisibilityWindows set beside
Combat/JumpPowerbar/ExternalContainer/Vendor - visibility belongs to
RuntimeTradeState's open/closed lifecycle exclusively.

Also carries the round-2 [trade] probes for the still-open "open never
registers" diagnosis: the round-1 log proved the request seam fires
(4x "request partner=0x50000001 item=0 open=False") but no window ever
opened - the new probes bracket the command router (open-cmd sent
flag), the wire send (wire-open seq), and the inbound RegisterTrade
apply, so the next gate log pinpoints whether the send leaves the
client and whether ACE replies.

App suite 4,990/3 skips.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-14 12:24:43 +02:00
parent 22f30f291d
commit f2144ab2a4
4 changed files with 20 additions and 2 deletions

View file

@ -229,8 +229,14 @@ internal sealed class LiveSessionCommandRouter : ILiveSessionCommandRouting
commands.Register<AddFriendRuntimeCmd>( commands.Register<AddFriendRuntimeCmd>(
command => SendIfActive(() => bindings.AddFriend(command.Name))); command => SendIfActive(() => bindings.AddFriend(command.Name)));
commands.Register<OpenTradeNegotiationsRuntimeCmd>( commands.Register<OpenTradeNegotiationsRuntimeCmd>(
command => SendIfActive(() => command =>
bindings.OpenTradeNegotiations(command.PartnerGuid))); {
bool sent = SendIfActive(() =>
bindings.OpenTradeNegotiations(command.PartnerGuid));
// TEMPORARY [trade] probe (2026-08-14 gate round 2).
Console.WriteLine(
$"[trade] open-cmd partner=0x{command.PartnerGuid:X8} sent={sent}");
});
commands.Register<CloseTradeNegotiationsRuntimeCmd>( commands.Register<CloseTradeNegotiationsRuntimeCmd>(
_ => SendIfActive(bindings.CloseTradeNegotiations)); _ => SendIfActive(bindings.CloseTradeNegotiations));
commands.Register<AddToTradeRuntimeCmd>( commands.Register<AddToTradeRuntimeCmd>(

View file

@ -500,6 +500,12 @@ public sealed class RetailUiRuntime : IDisposable
WindowNames.JumpPowerbar, WindowNames.JumpPowerbar,
WindowNames.ExternalContainer, WindowNames.ExternalContainer,
WindowNames.Vendor, WindowNames.Vendor,
// Trade gate round 2 (2026-08-14): the trade window is
// transient — visibility belongs to RuntimeTradeState's
// open/closed lifecycle, never to the layout file (a
// session that ended mid-trade was restoring an empty
// open window at every launch).
WindowNames.SecureTrade,
]); ]);
} }

View file

@ -2568,6 +2568,8 @@ public sealed class WorldSession : IDisposable
public void SendOpenTradeNegotiations(uint partnerGuid) public void SendOpenTradeNegotiations(uint partnerGuid)
{ {
uint seq = NextGameActionSequence(); uint seq = NextGameActionSequence();
// TEMPORARY [trade] probe (2026-08-14 gate round 2).
Console.WriteLine($"[trade] wire-open partner=0x{partnerGuid:X8} seq={seq}");
SendGameAction(TradeRequests.BuildOpenTradeNegotiations(seq, partnerGuid)); SendGameAction(TradeRequests.BuildOpenTradeNegotiations(seq, partnerGuid));
} }

View file

@ -87,6 +87,10 @@ public sealed class RuntimeTradeState : IDisposable
/// </summary> /// </summary>
public void ApplyRegister(GameEvents.RegisterTrade update, uint selfGuid) public void ApplyRegister(GameEvents.RegisterTrade update, uint selfGuid)
{ {
// TEMPORARY [trade] probe (2026-08-14 gate round 2).
Console.WriteLine(
$"[trade] register initiator=0x{update.Initiator:X8} "
+ $"partner=0x{update.Partner:X8} self=0x{selfGuid:X8}");
lock (_gate) lock (_gate)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);