using Content.Shared._Sunrise.MentorHelp; using JetBrains.Annotations; using Robust.Shared.Timing; namespace Content.Client._Sunrise.MentorHelp { /// /// Client-side mentor help system /// [UsedImplicitly] public sealed class MentorHelpSystem : SharedMentorHelpSystem { [Dependency] private readonly IGameTiming _gameTiming = default!; public event EventHandler? OnTicketUpdated; public event EventHandler? OnTicketsListReceived; public event EventHandler? OnTicketMessagesReceived; public event EventHandler? OnStatisticsReceived; public event EventHandler? OnOpenTicketReceived; public event EventHandler? OnPlayerTypingUpdated; private const double TypingUpdateResendIntervalSeconds = 1; private (TimeSpan Timestamp, bool Typing) _lastTypingUpdateSent; protected override void OnCreateTicketMessage(MentorHelpCreateTicketMessage message, EntitySessionEventArgs eventArgs) { // Client doesn't handle this directly } protected override void OnClaimTicketMessage(MentorHelpClaimTicketMessage message, EntitySessionEventArgs eventArgs) { // Client doesn't handle this directly } protected override void OnReplyMessage(MentorHelpReplyMessage message, EntitySessionEventArgs eventArgs) { // Client doesn't handle this directly } protected override void OnCloseTicketMessage(MentorHelpCloseTicketMessage message, EntitySessionEventArgs eventArgs) { // Client doesn't handle this directly } protected override void OnRequestTicketsMessage(MentorHelpRequestTicketsMessage message, EntitySessionEventArgs eventArgs) { // Client doesn't handle this directly } protected override void OnUnassignTicketMessage(MentorHelpUnassignTicketMessage message, EntitySessionEventArgs eventArgs) { // Client doesn't handle this directly } protected override void OnRequestStatisticsMessage(MentorHelpRequestStatisticsMessage message, EntitySessionEventArgs eventArgs) { // Client doesn't handle this directly } public override void Initialize() { base.Initialize(); SubscribeNetworkEvent(OnTicketUpdate); SubscribeNetworkEvent(OnTicketsList); SubscribeNetworkEvent(OnTicketMessages); SubscribeNetworkEvent(OnStatistics); SubscribeNetworkEvent(OnOpenTicket); SubscribeNetworkEvent(OnTypingUpdated); } private void OnOpenTicket(MentorHelpOpenTicketMessage message, EntitySessionEventArgs eventArgs) { OnOpenTicketReceived?.Invoke(this, message); } private void OnTypingUpdated(MentorHelpPlayerTypingUpdated message, EntitySessionEventArgs eventArgs) { OnPlayerTypingUpdated?.Invoke(this, message); } private void OnTicketUpdate(MentorHelpTicketUpdateMessage message, EntitySessionEventArgs eventArgs) { OnTicketUpdated?.Invoke(this, message); } private void OnTicketsList(MentorHelpTicketsListMessage message, EntitySessionEventArgs eventArgs) { OnTicketsListReceived?.Invoke(this, message); } private void OnTicketMessages(MentorHelpTicketMessagesMessage message, EntitySessionEventArgs eventArgs) { OnTicketMessagesReceived?.Invoke(this, message); } /// /// Create a new mentor help ticket /// private void OnStatistics(MentorHelpStatisticsMessage message, EntitySessionEventArgs eventArgs) { OnStatisticsReceived?.Invoke(this, message); } public void CreateTicket(string subject, string message) { RaiseNetworkEvent(new MentorHelpCreateTicketMessage(subject, message)); } /// /// Claim a mentor help ticket /// public void ClaimTicket(int ticketId) { RaiseNetworkEvent(new MentorHelpClaimTicketMessage(ticketId)); } /// /// Unassign a mentor help ticket /// public void UnassignTicket(int ticketId) { RaiseNetworkEvent(new MentorHelpUnassignTicketMessage(ticketId)); } /// /// Reply to a mentor help ticket /// public void ReplyToTicket(int ticketId, string message, bool isStaffOnly = false) { RaiseNetworkEvent(new MentorHelpReplyMessage(ticketId, message, isStaffOnly)); } /// /// Close a mentor help ticket /// public void CloseTicket(int ticketId) { RaiseNetworkEvent(new MentorHelpCloseTicketMessage(ticketId)); } /// /// Request tickets (either all for mentors/admins, or only own for players) /// public void RequestTickets(bool onlyMine = false) { RaiseNetworkEvent(new MentorHelpRequestTicketsMessage(onlyMine)); } /// /// Request messages for a specific ticket /// public void RequestTicketMessages(int ticketId) { // Send a request to the server to fetch messages for the given ticket RaiseNetworkEvent(new MentorHelpRequestTicketMessagesMessage(ticketId)); } /// /// Request mentor help statistics /// public void RequestStatistics() { RaiseNetworkEvent(new MentorHelpRequestStatisticsMessage()); } public void SendInputTextUpdated(int ticketId, bool typing) { if (_lastTypingUpdateSent.Typing == typing && _lastTypingUpdateSent.Timestamp + TimeSpan.FromSeconds(TypingUpdateResendIntervalSeconds) > _gameTiming.RealTime) { return; } _lastTypingUpdateSent = (_gameTiming.RealTime, typing); RaiseNetworkEvent(new MentorHelpClientTypingUpdated(ticketId, typing)); } } }