The backend's inventory views and mana panel are fed by three streams the original sent: the whole inventory after login, at logoff and on /mm sendinventory; an add, update or remove per item as it enters, changes in or leaves the packs; and the per-item cantrip state of worn and wielded gear. This ports all three onto the host's object events, with the frames built exactly as the original built them. Behaviour kept: adds and removes go out at once, changes are coalesced into one update per item on a two-to-five-minute timer re-rolled per flush; the first login appraises everything worth appraising and waits before sending; later logins merge in the saved appraisal data (kept in the character's storage, as the original kept a file per character); the mana panel debounces a quarter second and projects mana down between reports. Adapted to the host: appraisals go through a tick-driven queue, one at a time, retrying while the host's single slot is busy; the login upload waits for the inventory to stop arriving and for the socket, so it is not written into a closed socket; the logoff upload subscribes ahead of the root so the socket is still open; enchantment changes are polled once a second (the host has no event); an item-cast enchantment is the one that never runs out. A request the server never answers no longer holds the upload back for good. The Prismatic Taper count telemetry reads is InventoryFeature.PrismaticTaperCount. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
88 lines
2.7 KiB
C#
88 lines
2.7 KiB
C#
using AcDream.Plugin.Abstractions;
|
|
using OpenAC.MosswartMassacre.Inventory;
|
|
using OpenAC.MosswartMassacre.Tests.Fakes;
|
|
|
|
namespace OpenAC.MosswartMassacre.Tests.Inventory;
|
|
|
|
public sealed class IdentifyQueueTests
|
|
{
|
|
private static (IdentifyQueue Queue, FakeAutomation Automation, List<(uint, bool)> Finished) Create()
|
|
{
|
|
var automation = new FakeAutomation { IsAvailable = true };
|
|
var queue = new IdentifyQueue(() => automation);
|
|
var finished = new List<(uint, bool)>();
|
|
queue.Finished += (id, ok) => finished.Add((id, ok));
|
|
return (queue, automation, finished);
|
|
}
|
|
|
|
[Fact]
|
|
public void Requests_go_out_one_at_a_time_and_the_next_waits_for_the_answer()
|
|
{
|
|
var (queue, automation, finished) = Create();
|
|
queue.Enqueue(1);
|
|
queue.Enqueue(2);
|
|
queue.Enqueue(1);
|
|
|
|
queue.Pump(0.015);
|
|
queue.Pump(0.015);
|
|
Assert.Equal([1u], automation.Objects.IdentifyRequests);
|
|
|
|
queue.OnIdentReceived(1);
|
|
queue.Pump(0.015);
|
|
Assert.Equal([1u, 2u], automation.Objects.IdentifyRequests);
|
|
Assert.Equal([(1u, true)], finished);
|
|
Assert.False(queue.IsIdle);
|
|
|
|
queue.OnIdentReceived(2);
|
|
Assert.True(queue.IsIdle);
|
|
}
|
|
|
|
[Fact]
|
|
public void A_busy_slot_is_asked_again_on_a_later_tick()
|
|
{
|
|
var (queue, automation, _) = Create();
|
|
automation.Objects.IdentifyBusyForCalls[7] = 2;
|
|
queue.Enqueue(7);
|
|
|
|
queue.Pump(0.015);
|
|
queue.Pump(0.015);
|
|
queue.Pump(0.015);
|
|
|
|
Assert.Equal([7u, 7u, 7u], automation.Objects.IdentifyRequests);
|
|
Assert.Equal(1, queue.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void The_host_answer_or_abandon_finishes_a_request()
|
|
{
|
|
var (queue, automation, finished) = Create();
|
|
queue.Enqueue(3);
|
|
queue.Enqueue(4);
|
|
queue.Pump(0.015);
|
|
|
|
automation.Loot.Appraisal = new PluginAppraisalState(5, 0u, 3u);
|
|
queue.Pump(0.015);
|
|
automation.Loot.Appraisal = new PluginAppraisalState(6, 0u, 3u, LastAbandonedObjectId: 4u);
|
|
queue.Pump(0.015);
|
|
|
|
Assert.Equal([(3u, true), (4u, false)], finished);
|
|
}
|
|
|
|
[Fact]
|
|
public void An_unanswered_request_is_given_up_after_the_timeout_and_a_refusal_at_once()
|
|
{
|
|
var (queue, automation, finished) = Create();
|
|
automation.Objects.IdentifyResultOverrides[8] = PluginItemCommandStatus.InvalidItem;
|
|
queue.Enqueue(8);
|
|
queue.Enqueue(9);
|
|
|
|
queue.Pump(0.015);
|
|
Assert.Equal([(8u, false)], finished);
|
|
|
|
for (int i = 0; i < 700; i++)
|
|
queue.Pump(0.015);
|
|
|
|
Assert.Equal([(8u, false), (9u, false)], finished);
|
|
Assert.True(queue.IsIdle);
|
|
}
|
|
}
|