private bool CommandsTooFast(ChatMessageEventArgs chatMessageArgs, ChatUserInfo user, string namedCommand, TimeSpan?cooldown = null) { Debug.Assert(user != null); if (chatMessageArgs.IsModerator || chatMessageArgs.IsOwner) { return(false); } var now = DateTime.UtcNow; if (now - user.LastCommandTime < CooldownTime) { _logger?.LogWarning($"Ignoring command {namedCommand} from {chatMessageArgs.UserName} on {chatMessageArgs.ServiceName}. Cooldown active"); return(true); } if (_commandExecutedTimeMap.TryGetValue(namedCommand, out var dt) && now - dt < cooldown.GetValueOrDefault()) { var remain = cooldown.GetValueOrDefault() - (now - dt); _logger?.LogWarning($"Ignoring command {namedCommand} from {chatMessageArgs.UserName} on {chatMessageArgs.ServiceName}. In cooldown for {(int)remain.TotalSeconds} more secs"); return(true); } return(false); }
private void AfterExecute(ChatUserInfo user, string command) { Debug.Assert(user != null); // Remember last command time user.LastCommandTime = DateTime.UtcNow; _commandExecutedTimeMap[command] = DateTime.UtcNow; }
private async ValueTask <bool> HandleExtendedCommands(IChatService chatService, ChatMessageEventArgs chatMessageArgs, ChatUserInfo user) { Debug.Assert(_extendedCommands != null); foreach (var cmd in _extendedCommands) { Debug.Assert(!string.IsNullOrEmpty(cmd.Name)); if (cmd.CanExecute(chatMessageArgs.UserName, chatMessageArgs.Message)) { // Ignore if the normal user is sending commands to fast, or command is in cooldown if (CommandsTooFast(chatMessageArgs, user, cmd.Name, cmd.Cooldown)) { return(false); } await cmd.Execute(chatService, chatMessageArgs.UserName, chatMessageArgs.Message); AfterExecute(user, cmd.Name); return(cmd.Final); } } return(false); }
private async ValueTask <bool> HandleBasicCommands(IChatService chatService, ChatMessageEventArgs chatMessageArgs, ChatUserInfo user) { Debug.Assert(_basicCommands != null); Debug.Assert(!string.IsNullOrEmpty(chatMessageArgs.Message) && chatMessageArgs.Message[0] == '!'); var trigger = chatMessageArgs.Message.AsMemory(1); var rhs = ReadOnlyMemory <char> .Empty; var n = trigger.Span.IndexOf(' '); if (n != -1) { rhs = trigger.Slice(n + 1); trigger = trigger.Slice(0, n); } foreach (var cmd in _basicCommands) { Debug.Assert(!string.IsNullOrEmpty(cmd.Trigger)); if (trigger.Span.Equals(cmd.Trigger.AsSpan(), StringComparison.OrdinalIgnoreCase)) { // Ignore if the normal user is sending commands to fast, or command is in cooldown if (CommandsTooFast(chatMessageArgs, user, cmd.Trigger, cmd.Cooldown)) { return(true); } if (cmd is IBasicCommand2) { await(cmd as IBasicCommand2).Execute(chatService, chatMessageArgs.UserName, chatMessageArgs.IsModerator, chatMessageArgs.IsOwner, rhs); } else { await cmd.Execute(chatService, chatMessageArgs.UserName, rhs); } AfterExecute(user, cmd.Trigger); return(true); } } return(false); }