using System; using System.Collections; using System.Collections.Generic; using Server.Commands; using Server.Gumps; using Server.Mobiles; using Server.Targeting; namespace Server.Engines.Help { public class SpeechLog : IEnumerable { // Are speech logs enabled? public static readonly bool Enabled = true; // How long should we maintain each speech entry? public static readonly TimeSpan EntryDuration = TimeSpan.FromMinutes(20.0); // What is the maximum number of entries a log can contain? (0 -> no limit) public static readonly int MaxLength = 0; private readonly Queue m_Queue; public SpeechLog() => m_Queue = new Queue(); public int Count => m_Queue.Count; IEnumerator IEnumerable.GetEnumerator() => m_Queue.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => m_Queue.GetEnumerator(); public static void Initialize() { CommandSystem.Register("SpeechLog", AccessLevel.Counselor, SpeechLog_OnCommand); } [Usage("SpeechLog")] [Description("Opens the speech log of a given target.")] private static void SpeechLog_OnCommand(CommandEventArgs e) { Mobile from = e.Mobile; from.SendMessage("Target a player to view his speech log."); e.Mobile.Target = new SpeechLogTarget(); } public void Add(Mobile from, string speech) { Add(new SpeechLogEntry(from, speech)); } public void Add(SpeechLogEntry entry) { if (MaxLength > 0 && m_Queue.Count >= MaxLength) m_Queue.Dequeue(); Clean(); m_Queue.Enqueue(entry); } public void Clean() { while (m_Queue.Count > 0) { SpeechLogEntry entry = m_Queue.Peek(); if (DateTime.UtcNow - entry.Created > EntryDuration) m_Queue.Dequeue(); else break; } } public void CopyTo(SpeechLogEntry[] array, int index) { m_Queue.CopyTo(array, index); } private class SpeechLogTarget : Target { public SpeechLogTarget() : base(-1, false, TargetFlags.None) { } protected override void OnTarget(Mobile from, object targeted) { if (!(targeted is PlayerMobile pm)) { from.SendMessage("Speech logs aren't supported on that target."); } else if (from != targeted && from.AccessLevel <= pm.AccessLevel && from.AccessLevel != AccessLevel.Owner) { from.SendMessage("You don't have the required access level to view {0} speech log.", pm.Female ? "her" : "his"); } else if (pm.SpeechLog == null) { from.SendMessage("{0} has no speech log.", pm.Female ? "She" : "He"); } else { CommandLogging.WriteLine(from, "{0} {1} viewing speech log of {2}", from.AccessLevel, CommandLogging.Format(from), CommandLogging.Format(targeted)); Gump gump = new SpeechLogGump(pm, pm.SpeechLog); from.SendGump(gump); } } } } public class SpeechLogEntry { public SpeechLogEntry(Mobile from, string speech) { From = from; Speech = speech; Created = DateTime.UtcNow; } public Mobile From { get; } public string Speech { get; } public DateTime Created { get; } } }