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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Inventory.cs" />
|
||||
<Compile Include="vTank.cs" />
|
||||
<Compile Include="VtankControl.cs" />
|
||||
<Compile Include="Telemetry.cs" />
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue