test of inventory
This commit is contained in:
parent
781a7767ee
commit
29fba4b7cb
3 changed files with 161 additions and 0 deletions
157
MosswartMassacre/Inventory.cs
Normal file
157
MosswartMassacre/Inventory.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -74,6 +74,7 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Inventory.cs" />
|
||||||
<Compile Include="vTank.cs" />
|
<Compile Include="vTank.cs" />
|
||||||
<Compile Include="VtankControl.cs" />
|
<Compile Include="VtankControl.cs" />
|
||||||
<Compile Include="Telemetry.cs" />
|
<Compile Include="Telemetry.cs" />
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ namespace MosswartMassacre
|
||||||
private static Queue<string> rareMessageQueue = new Queue<string>();
|
private static Queue<string> rareMessageQueue = new Queue<string>();
|
||||||
private static DateTime _lastSent = DateTime.MinValue;
|
private static DateTime _lastSent = DateTime.MinValue;
|
||||||
private static readonly Queue<string> _chatQueue = new Queue<string>();
|
private static readonly Queue<string> _chatQueue = new Queue<string>();
|
||||||
|
private InventoryMonitor _inv;
|
||||||
|
|
||||||
protected override void Startup()
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
|
|
@ -63,6 +64,7 @@ namespace MosswartMassacre
|
||||||
vTank.Enable();
|
vTank.Enable();
|
||||||
//lyssna på commands
|
//lyssna på commands
|
||||||
WebSocket.OnServerCommand += HandleServerCommand;
|
WebSocket.OnServerCommand += HandleServerCommand;
|
||||||
|
_inv = new InventoryMonitor();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -101,6 +103,7 @@ namespace MosswartMassacre
|
||||||
// sluta lyssna på commands
|
// sluta lyssna på commands
|
||||||
WebSocket.OnServerCommand -= HandleServerCommand;
|
WebSocket.OnServerCommand -= HandleServerCommand;
|
||||||
WebSocket.Stop();
|
WebSocket.Stop();
|
||||||
|
_inv?.Dispose();
|
||||||
|
|
||||||
MyHost = null;
|
MyHost = null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue