fix(chat): Campaign CH user-gate round 2 -- portal notice rerouted to SpewBox, verbatim /help extraction, jump-in-air evidence
Item 2: retail's portal-space "In Portal Space..." notice is the SpewBox (ECM_UI::SendNotice_DisplayStringInfo(0x1A,...) -> AddTextToScroll(str, 0x1A, 1, 0), hardcoded to the SpewBox per the decomp), not a dedicated centered overlay. PortalWaitNoticeController and its lease are deleted; PortalTunnelPresentation's per-rotation-segment cadence now writes straight into RuntimeCommunicationState.AddText(ClientLocal) -- the SpewBox's own dedupe-at-index-0 handles the repetition exactly as retail's does. Register row AP-184 records the surface fix and the AP-178 scope extension. Items 4+5: /help text was partially fabricated -- the user caught the "/help death" meta-message. Generalized tools/pdb-extract/sweep_weenie_strings.py to decode narrow PStringBase<char> literals (the ClientCommunicationSystem::Help* family's shape) alongside its original UTF-16LE support, then swept every HelpXxxGroup function's exact byte extent against the PDB-paired acclient.exe. 4 of 7 group topics (death/status/text/allegiances) are now complete verbatim listings; the other 3 (channels/chatting/commands) keep an honest UNVERIFIED note citing HelpStupidChannelHack @0x0056f290 (a genuinely undecodable BN-mislabeled-fragment mechanism) instead of the old fabricated sentinel. 7 of ~35 channel one-liners are also now verbatim. ISSUES.md #364 tracks the remainder; RetailCommandHelpTableTests.cs pins every result byte-exact. Item 1: jump-in-air refusal still silent live is NOT reproduced and NOT speculatively fixed. Exhaustive static re-audit found the mechanism correct by construction (single-writer OnWalkable, exactly-once-per-frame Update()/Capture(), no interfering edge-history resets). A live headless repro (new jump-probe bot policy, real ACE connect) was blocked -- probeaccount2 has no character, and the graphical client already owned testaccount this session so the task's own fallback rule forbade using it. Two temporary probes are left behind ACDREAM_PROBE_JUMP=1 (blocked entirely in Headless by the existing multi-session static-state guard -- graphical-only for the next round). Item 3 confirmed fixed, no regression. Item 6 (resize: no diagonal cursors, cannot grow Y from bottom-right) folded into CH6a's existing scope. Full Release suite: 12,267 passed / 4 skipped / 0 failed (up from 12,221/4/0). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
a485425743
commit
c1f1582576
14 changed files with 788 additions and 254 deletions
|
|
@ -1,74 +0,0 @@
|
|||
using System.Numerics;
|
||||
|
||||
namespace AcDream.App.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Retained presentation of retail's ECM_UI display-string notice emitted by
|
||||
/// <c>gmSmartBoxUI::UseTime @ 0x004D6E30</c> while portal-space cell blocking
|
||||
/// continues. It is a centered overlay, not a chat message.
|
||||
/// </summary>
|
||||
internal sealed class PortalWaitNoticeController : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Register row AP-150/AP-178: CH user-gate round 1 (2026-08-09) PINNED
|
||||
/// this — the user confirmed live, side-by-side against retail, that
|
||||
/// this notice renders in the same bright yellow as an incoming Tell
|
||||
/// (<c>0x81C4C8</c>, <c>RetailChatColorTable.Yellow</c> =
|
||||
/// <c>(1, 1, 0.247, 1)</c>), not white. Same exact value as the
|
||||
/// SpewBox's pinned colour (<see cref="AcDream.App.UI.SpewBoxController"/>).
|
||||
/// </summary>
|
||||
private static readonly Vector4 RetailWaitCueColor = new(1f, 1f, 0.247f, 1f);
|
||||
|
||||
private readonly UiRoot _root;
|
||||
private readonly UiText _text;
|
||||
private UiText.Line[] _lines = [];
|
||||
private bool _disposed;
|
||||
|
||||
public PortalWaitNoticeController(UiRoot root)
|
||||
{
|
||||
_root = root ?? throw new ArgumentNullException(nameof(root));
|
||||
_text = new UiText
|
||||
{
|
||||
Name = "PortalSpaceWaitNotice",
|
||||
Left = 0f,
|
||||
Top = 0f,
|
||||
Width = root.Width,
|
||||
Height = root.Height,
|
||||
Anchors = AnchorEdges.Left
|
||||
| AnchorEdges.Top
|
||||
| AnchorEdges.Right
|
||||
| AnchorEdges.Bottom,
|
||||
Centered = true,
|
||||
OneLine = true,
|
||||
ClickThrough = true,
|
||||
ZOrder = int.MaxValue,
|
||||
DefaultColor = RetailWaitCueColor,
|
||||
Visible = false,
|
||||
};
|
||||
_text.LinesProvider = () => _lines;
|
||||
_root.AddChild(_text);
|
||||
}
|
||||
|
||||
public void Set(string? message)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
if (string.IsNullOrEmpty(message))
|
||||
{
|
||||
_text.Visible = false;
|
||||
_lines = [];
|
||||
return;
|
||||
}
|
||||
|
||||
_lines = [new UiText.Line(message, RetailWaitCueColor)];
|
||||
_text.Visible = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
_root.RemoveChild(_text);
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,15 @@ namespace AcDream.App.UI;
|
|||
/// <summary>
|
||||
/// Retained presentation of retail's <c>gmSpewBoxUI</c> (research doc
|
||||
/// §1.1/§7.3/§7.4) — the transient top-of-viewport interface-text queue.
|
||||
/// Modeled directly on <see cref="PortalWaitNoticeController"/>: a single
|
||||
/// <c>ClickThrough</c> <see cref="UiText"/> block at a high
|
||||
/// <see cref="UiElement.ZOrder"/>. Unlike that controller's single
|
||||
/// overwrite-only slot, this reads <see cref="SpewBoxVM"/>'s bounded,
|
||||
/// newest-on-top, per-entry-expiring queue every frame.
|
||||
/// A single <c>ClickThrough</c> <see cref="UiText"/> block at a high
|
||||
/// <see cref="UiElement.ZOrder"/>. Campaign CH user-gate round 2, item 2:
|
||||
/// this is now the ONLY on-screen interface-text presentation surface —
|
||||
/// the former <c>PortalWaitNoticeController</c> (a dedicated centered
|
||||
/// overlay with a single overwrite-only slot) is deleted; the portal-space
|
||||
/// wait notice routes here too, through the same
|
||||
/// <c>RuntimeCommunicationState.AddText</c> chokepoint every other
|
||||
/// <c>ClientLocal</c> refusal uses. This reads <see cref="SpewBoxVM"/>'s
|
||||
/// bounded, newest-on-top, per-entry-expiring queue every frame.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <b>CH2 REJECT-review rework, BLOCKER 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue