// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.GameServer.RemoteView.Guild; using System.Collections.Concurrent; using MUnique.OpenMU.GameLogic; using MUnique.OpenMU.GameLogic.Views.Guild; using MUnique.OpenMU.Interfaces; /// /// Abstract base class for a which allows to cache serialized guild infos. /// /// The type of the actual . Required, so there is one cache per type. // ReSharper disable once UnusedTypeParameter we just use it to get type specific static fields. public abstract class BaseGuildInfoPlugIn { /// /// The cache for already serialized guilds. This data doesn't change, but is requested often. /// // ReSharper disable once StaticMemberInGenericType That's what we want private static readonly ConcurrentDictionary> Cache = new(); // ReSharper disable once StaticMemberInGenericType That's what we want private static readonly HashSet AppendedGuildDeletedSenders = new(); /// /// Initializes a new instance of the class. /// /// The player. protected BaseGuildInfoPlugIn(RemotePlayer player) { this.Player = player; lock (AppendedGuildDeletedSenders) { if (AppendedGuildDeletedSenders.Add(player.GameServerContext)) { // to make sure we just add one event handler this.Player.GameServerContext.GuildDeleted += OnGuildChanged; this.Player.GameServerContext.GuildChanged += OnGuildChanged; } } } /// /// Gets the player. /// /// /// The player. /// protected RemotePlayer Player { get; } /// /// Serializes the specified guild. /// /// The guild. /// The guild identifier. /// The serialized guild data packet. protected abstract Memory Serialize(Guild guild, uint guildId); /// /// Returns the Guild Info Data of a Guild. It will either /// take the data out of the Cache, or get it from the database and serializes it. /// /// The id of the guild. /// /// The data of the guild. /// protected async ValueTask> GetGuildDataAsync(uint guildId) { if (Cache.TryGetValue(guildId, out var guildInfo)) { return guildInfo; } var guild = await this.Player.GameServerContext.GuildServer.GetGuildAsync(guildId).ConfigureAwait(false); if (guild is null) { return Memory.Empty; } var data = this.Serialize(guild, guildId); Cache.TryAdd(guildId, data); return data; } private static void OnGuildChanged(object? sender, GuildEventArgs args) { Cache.TryRemove(args.GuildId, out _); } }