Vital sharing across computers through the backend
Outgoing, the original's share_* frames byte for byte: subscribe with the player id on start and without it after every reconnect, vitals on change or every 3 s, position on change or every 10 s, the item heartbeat every 5 s, unsubscribe on stop. Debuff casts come from the host's peer network: the attempts and landings the bot announces, plus the player's own completed casts, so a hand-cast debuff is shared once it lands (a plugin cannot see outgoing packets, so hand-cast attempts are not). Ids stay signed ints, skill a double, duration_ms the spell's duration. Incoming, another computer's characters and casts go into the host's peer network (the new relay imports), where the bot reads them exactly as it reads characters on this computer: vitals and position for heals, landed debuffs for target choice. Peers not heard from for 15 s drop out; the original kept them forever. Logoff now runs features in reverse so the unsubscribe leaves before the socket closes, and stopping the socket flushes what was queued. Builds against a preview of the plugin API with the peer relay (0.1.19-mmpreview.1, packed from the relay commit); switch to the released package when it exists. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5799ea956e
commit
78813cf861
9 changed files with 1042 additions and 4 deletions
81
src/OpenAC.MosswartMassacre/Sharing/PeerTable.cs
Normal file
81
src/OpenAC.MosswartMassacre/Sharing/PeerTable.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
namespace OpenAC.MosswartMassacre.Sharing;
|
||||
|
||||
/// <summary>One character heard from through the backend.</summary>
|
||||
internal sealed class Peer
|
||||
{
|
||||
public Peer(string characterName)
|
||||
{
|
||||
CharacterName = characterName;
|
||||
}
|
||||
|
||||
public string CharacterName { get; }
|
||||
|
||||
public uint PlayerId { get; set; }
|
||||
|
||||
public int CurrentHealth { get; set; }
|
||||
|
||||
public int MaxHealth { get; set; }
|
||||
|
||||
public int CurrentStamina { get; set; }
|
||||
|
||||
public int MaxStamina { get; set; }
|
||||
|
||||
public int CurrentMana { get; set; }
|
||||
|
||||
public int MaxMana { get; set; }
|
||||
|
||||
public double EW { get; set; }
|
||||
|
||||
public double NS { get; set; }
|
||||
|
||||
/// <summary>Height in metres.</summary>
|
||||
public double Z { get; set; }
|
||||
|
||||
public double Heading { get; set; }
|
||||
|
||||
public bool HasPosition { get; set; }
|
||||
|
||||
public IReadOnlyList<string> Tags { get; set; } = [];
|
||||
|
||||
public DateTime LastUpdateUtc { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The peers heard from, by name. A peer not heard from for fifteen seconds
|
||||
/// drops out, the rule the host applies to its own peers; the original kept
|
||||
/// logged-off peers forever.
|
||||
/// </summary>
|
||||
internal sealed class PeerTable
|
||||
{
|
||||
public static readonly TimeSpan Staleness = TimeSpan.FromSeconds(15);
|
||||
|
||||
private readonly Dictionary<string, Peer> _peers = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public Peer Upsert(string name, DateTime nowUtc)
|
||||
{
|
||||
if (!_peers.TryGetValue(name, out Peer? peer))
|
||||
{
|
||||
peer = new Peer(name);
|
||||
_peers[name] = peer;
|
||||
}
|
||||
peer.LastUpdateUtc = nowUtc;
|
||||
return peer;
|
||||
}
|
||||
|
||||
public bool TryGet(string name, out Peer? peer) => _peers.TryGetValue(name, out peer);
|
||||
|
||||
/// <summary>The peers heard from within the last fifteen seconds, by name.</summary>
|
||||
public IReadOnlyList<Peer> Current(DateTime nowUtc)
|
||||
{
|
||||
foreach (string stale in _peers.Values
|
||||
.Where(peer => nowUtc - peer.LastUpdateUtc > Staleness)
|
||||
.Select(peer => peer.CharacterName)
|
||||
.ToList())
|
||||
{
|
||||
_peers.Remove(stale);
|
||||
}
|
||||
return [.. _peers.Values.OrderBy(peer => peer.CharacterName, StringComparer.OrdinalIgnoreCase)];
|
||||
}
|
||||
|
||||
public void Clear() => _peers.Clear();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue