namespace AcDream.Core.Social; /// Authoritative copy of retail's server-supplied SquelchDB. public sealed class SquelchState { private readonly object _gate = new(); private SquelchDatabase _database = SquelchDatabase.Empty; private long _revision; public long Revision => Interlocked.Read(ref _revision); public SquelchDatabase Snapshot() { lock (_gate) return _database; } public void Replace(SquelchDatabase database) { ArgumentNullException.ThrowIfNull(database); lock (_gate) { _database = database; Interlocked.Increment(ref _revision); } } /// /// Drop the server-owned squelch database for the old session. Retail /// CPlayerSystem::LogOnCharacter @ 0x0055F890 calls /// gmCCommunicationSystem::ClearSquelchDB @ 0x00589240 before /// entering the next character. /// public void Clear() { lock (_gate) { _database = SquelchDatabase.Empty; Interlocked.Increment(ref _revision); } } } public sealed record SquelchInfo( string Name, bool AccountWide, IReadOnlySet MessageTypes); public sealed record SquelchDatabase( IReadOnlyDictionary Accounts, IReadOnlyDictionary Characters, SquelchInfo Global) { public static SquelchDatabase Empty { get; } = new( new Dictionary(StringComparer.OrdinalIgnoreCase), new Dictionary(), new SquelchInfo(string.Empty, false, new HashSet())); }