diff --git a/src/OpenAC.MosswartMassacre/Inventory/InventoryFeature.cs b/src/OpenAC.MosswartMassacre/Inventory/InventoryFeature.cs
index f30b222..d5dd032 100644
--- a/src/OpenAC.MosswartMassacre/Inventory/InventoryFeature.cs
+++ b/src/OpenAC.MosswartMassacre/Inventory/InventoryFeature.cs
@@ -424,7 +424,10 @@ internal sealed class InventoryFeature : IMmFeature
try
{
if (change.Kind == PluginObjectChangeKind.IdentReceived)
+ {
+ _reader.NoteAppraisal(change.ObjectId);
_identify.OnIdentReceived(change.ObjectId);
+ }
PluginWorldObject? current = change.Current;
if (change.Kind == PluginObjectChangeKind.Released
diff --git a/src/OpenAC.MosswartMassacre/Inventory/InventoryReader.cs b/src/OpenAC.MosswartMassacre/Inventory/InventoryReader.cs
index 032c573..c5712bb 100644
--- a/src/OpenAC.MosswartMassacre/Inventory/InventoryReader.cs
+++ b/src/OpenAC.MosswartMassacre/Inventory/InventoryReader.cs
@@ -57,6 +57,16 @@ internal sealed class InventoryReader
&& world.HasAppraisalData
&& world.LastIdTime != 0;
+ ///
+ /// Stamps an appraisal as it arrives, so the record carries the time it
+ /// came in rather than the time the record was first built.
+ ///
+ public void NoteAppraisal(uint objectId)
+ {
+ if (_context.Automation.Objects.TryGet(objectId, out PluginWorldObject world) && world.LastIdTime != 0)
+ Stamp(objectId, world.LastIdTime);
+ }
+
/// The item record for one owned item, as it stands now.
public MyWorldObject Build(in PluginInventoryItem item)
{
diff --git a/tests/OpenAC.MosswartMassacre.Tests/Inventory/InventoryFeatureTests.cs b/tests/OpenAC.MosswartMassacre.Tests/Inventory/InventoryFeatureTests.cs
index e283ed5..a659950 100644
--- a/tests/OpenAC.MosswartMassacre.Tests/Inventory/InventoryFeatureTests.cs
+++ b/tests/OpenAC.MosswartMassacre.Tests/Inventory/InventoryFeatureTests.cs
@@ -252,4 +252,22 @@ public sealed class InventoryFeatureTests
Assert.Empty(harness.FramesOfTypeRaw("full_inventory"));
}
+
+ [Fact]
+ public void The_appraisal_time_is_the_wall_clock_when_the_appraisal_arrived()
+ {
+ using var harness = new PluginHarness("Mossy");
+ InventoryFeature feature = LoginAndSettle(harness);
+ Own(harness.Host, Tachi(appraised: false));
+ Raise(harness.Host, 0x80000202u, PluginObjectChangeKind.Created);
+
+ Own(harness.Host, Tachi(appraised: true), TachiProps(), hostIdTime: 5000);
+ Raise(harness.Host, 0x80000202u, PluginObjectChangeKind.IdentReceived);
+ harness.Clock.Advance(TimeSpan.FromMinutes(3));
+ harness.Frames.Clear();
+ feature.FlushDirtyItems();
+
+ JObject update = JObject.Parse(harness.FramesOfTypeRaw("inventory_delta").Single());
+ Assert.Equal(1790325015, (int)update["item"]!["LastIdTime"]!);
+ }
}