test of inventory

This commit is contained in:
erik 2025-05-11 15:48:48 +02:00
parent 781a7767ee
commit 29fba4b7cb
3 changed files with 161 additions and 0 deletions

View file

@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Decal.Adapter;
using Decal.Adapter.Wrappers;
using Newtonsoft.Json;
namespace MosswartMassacre
{
public sealed class InventoryMonitor : IDisposable
{
private const string Schema = "mm-inv/1.1";
private readonly string _filePath;
private Dictionary<int, ItemRecord> _cache = new Dictionary<int, ItemRecord>();
private readonly WorldFilter _wf;
private readonly CharacterFilter _cf;
private bool _suppress;
public InventoryMonitor()
{
_cf = CoreManager.Current.CharacterFilter;
_wf = CoreManager.Current.WorldFilter;
_filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{_cf.Name}-inventory.json");
_cf.LoginComplete += (_, __) => SnapshotAndSaveAll();
_wf.CreateObject += OnWorldFilterEvent;
_wf.ChangeObject += OnWorldFilterEvent;
_wf.MoveObject += OnWorldFilterEvent;
_wf.ReleaseObject += OnWorldFilterEvent;
if (_cf.LoginStatus == 3)
SnapshotAndSaveAll();
}
public void Dispose()
{
_cf.LoginComplete -= (_, __) => SnapshotAndSaveAll();
_wf.CreateObject -= OnWorldFilterEvent;
_wf.ChangeObject -= OnWorldFilterEvent;
_wf.MoveObject -= OnWorldFilterEvent;
_wf.ReleaseObject -= OnWorldFilterEvent;
}
private void SnapshotAndSaveAll()
{
var snapshot = _wf.GetInventory()
.Select(o => new ItemRecord(o))
.ToDictionary(r => r.Id, r => r);
SaveToDisk(new SnapshotFile
{
schema = Schema,
items = snapshot.Values.ToList()
});
_cache = snapshot;
}
private void OnWorldFilterEvent(object s, EventArgs e)
{
if (_suppress) return;
_suppress = true;
try { DiffAndSave(); }
finally { _suppress = false; }
}
private void DiffAndSave()
{
var latest = _wf.GetInventory()
.Select(o => new ItemRecord(o))
.ToDictionary(r => r.Id, r => r);
var adds = latest.Keys.Except(_cache.Keys)
.Select(id => latest[id]);
var removes = _cache.Keys.Except(latest.Keys);
var updates = latest.Values
.Where(r => _cache.TryGetValue(r.Id, out var old) && !r.Equals(old));
if (!adds.Any() && !removes.Any() && !updates.Any())
return;
var patch = new PatchFile
{
schema = Schema,
type = "events",
adds = adds.ToList(),
removes = removes.ToList(),
updates = updates.ToList()
};
SaveToDisk(patch);
_cache = latest;
}
private void SaveToDisk(object doc)
{
var json = JsonConvert.SerializeObject(doc, Formatting.Indented);
File.WriteAllText(_filePath, json, Encoding.UTF8);
}
// Data classes
private class SnapshotFile
{
public string Schema => schema;
public string schema;
public List<ItemRecord> items;
}
private class PatchFile
{
public string schema;
public string type;
public List<ItemRecord> adds;
public List<int> removes;
public List<ItemRecord> updates;
}
}
public class ItemRecord : IEquatable<ItemRecord>
{
public int Id { get; set; }
public string Name { get; set; }
public int Container { get; set; }
public int Icon { get; set; }
public int Count { get; set; }
public bool Equipped { get; set; }
public bool HasIdData { get; set; }
public int ObjectClass { get; set; }
public ItemRecord() { }
public ItemRecord(WorldObject wo)
{
Id = wo.Id;
Name = wo.Name;
Container = wo.Container;
Icon = wo.Icon;
Count = (int)wo.Values(LongValueKey.StackCount, 1);
Equipped = wo.Values(LongValueKey.EquippedSlots, 0) > 0;
HasIdData = wo.HasIdData;
ObjectClass = (int)wo.ObjectClass;
}
public bool Equals(ItemRecord other)
{
if (other == null) return false;
return Container == other.Container
&& Count == other.Count
&& Equipped == other.Equipped
&& HasIdData == other.HasIdData;
}
public override int GetHashCode() => Id;
}
}

View file

@ -74,6 +74,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Inventory.cs" />
<Compile Include="vTank.cs" />
<Compile Include="VtankControl.cs" />
<Compile Include="Telemetry.cs" />

View file

@ -32,6 +32,7 @@ namespace MosswartMassacre
private static Queue<string> rareMessageQueue = new Queue<string>();
private static DateTime _lastSent = DateTime.MinValue;
private static readonly Queue<string> _chatQueue = new Queue<string>();
private InventoryMonitor _inv;
protected override void Startup()
{
@ -63,6 +64,7 @@ namespace MosswartMassacre
vTank.Enable();
//lyssna på commands
WebSocket.OnServerCommand += HandleServerCommand;
_inv = new InventoryMonitor();
}
catch (Exception ex)
{
@ -101,6 +103,7 @@ namespace MosswartMassacre
// sluta lyssna på commands
WebSocket.OnServerCommand -= HandleServerCommand;
WebSocket.Stop();
_inv?.Dispose();
MyHost = null;
}