feat: /mm sendinventory now scans, identifies all items, then sends

Previously sent inventory immediately with potentially unidentified items.
Now uses the same scan-wait-send pattern as first-login:
1. Requests ID for all items needing identification
2. Waits for all identifications to complete (ChangeObject handler)
3. Only sends complete, fully-identified inventory when ready

Ensures clean inventory data for the backend, eliminates stale/partial items.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-08 16:52:18 +02:00
parent 08f2d57e08
commit a4db8e08a5
2 changed files with 37 additions and 7 deletions

View file

@ -87,6 +87,7 @@ namespace MosswartMassacre
private bool loginComplete; private bool loginComplete;
private bool loggedInAndWaitingForIdData; private bool loggedInAndWaitingForIdData;
private bool forceUploadWaitingForIdData;
private readonly List<int> requestedIds = new List<int>(); private readonly List<int> requestedIds = new List<int>();
private void CharacterFilter_LoginComplete(object sender, EventArgs e) private void CharacterFilter_LoginComplete(object sender, EventArgs e)
@ -166,7 +167,7 @@ namespace MosswartMassacre
return; // Settings not ready, skip silently return; // Settings not ready, skip silently
} }
if (loggedInAndWaitingForIdData) if (loggedInAndWaitingForIdData || forceUploadWaitingForIdData)
{ {
bool allHaveId = true; bool allHaveId = true;
foreach (WorldObject wo in CoreManager.Current.WorldFilter.GetInventory()) foreach (WorldObject wo in CoreManager.Current.WorldFilter.GetInventory())
@ -179,9 +180,14 @@ namespace MosswartMassacre
} }
if (allHaveId) if (allHaveId)
{ {
bool wasForceUpload = forceUploadWaitingForIdData;
loggedInAndWaitingForIdData = false; loggedInAndWaitingForIdData = false;
forceUploadWaitingForIdData = false;
DumpInventoryToFile(); DumpInventoryToFile();
PluginCore.WriteToChat("Requesting id information for all armor/weapon inventory completed. Log file written."); if (wasForceUpload)
PluginCore.WriteToChat("[INV] All items identified. Inventory upload completed.");
else
PluginCore.WriteToChat("Requesting id information for all armor/weapon inventory completed. Log file written.");
} }
} }
else else
@ -295,14 +301,15 @@ namespace MosswartMassacre
} }
/// <summary> /// <summary>
/// Forces an inventory upload with ID requests - guarantees complete data /// Forces a full inventory scan: requests ID data for all items that need it,
/// waits for all identifications to complete, then sends the complete inventory.
/// </summary> /// </summary>
public void ForceInventoryUpload() public void ForceInventoryUpload()
{ {
try try
{ {
// Check if inventory logging is enabled // Check if inventory logging is enabled
try try
{ {
if (!PluginSettings.Instance.InventoryLog) if (!PluginSettings.Instance.InventoryLog)
{ {
@ -323,9 +330,32 @@ namespace MosswartMassacre
return; return;
} }
PluginCore.WriteToChat("[INV] Forcing inventory upload with ID requests..."); // Count items needing identification
DumpInventoryToFile(true); // Request IDs if missing int needsId = 0;
PluginCore.WriteToChat("[INV] Inventory upload completed"); int totalItems = 0;
foreach (WorldObject wo in CoreManager.Current.WorldFilter.GetInventory())
{
totalItems++;
if (!wo.HasIdData && ObjectClassNeedsIdent(wo.ObjectClass, wo.Name))
{
CoreManager.Current.Actions.RequestId(wo.Id);
needsId++;
}
}
if (needsId > 0)
{
// Wait for all IDs to come back before sending
forceUploadWaitingForIdData = true;
PluginCore.WriteToChat($"[INV] Scanning {totalItems} items, requesting ID for {needsId}. Waiting for identification...");
}
else
{
// All items already identified, send immediately
PluginCore.WriteToChat($"[INV] All {totalItems} items already identified. Sending...");
DumpInventoryToFile();
PluginCore.WriteToChat("[INV] Inventory upload completed");
}
} }
catch (Exception ex) catch (Exception ex)
{ {