public bool HandleTextMessage(NotifyTextMessageEvent evt, Action <string> messageCallback) { if (!Settings.ChatCommandsEnabled || string.IsNullOrEmpty(evt.Message) || !evt.Message.StartsWith(Settings.ChatCommandPrefix)) { return(false); } Parent.LogMessage($"{evt.InvokerName} requested command: \"{evt.Message}\""); //Copy event as to not mess up other event handlers NotifyTextMessageEvent tempEvt = new NotifyTextMessageEvent(); evt.CopyProperties(tempEvt); evt = tempEvt; evt.Message = evt.Message.Substring(Settings.ChatCommandPrefix.Length); bool hasAdmin = Settings.AdminUniqueIds.Contains(evt.InvokerUniqueId); if (Parent.RateLimiter.CheckRateLimit("chat_command", evt.InvokerUniqueId, hasAdmin) == false) { messageCallback.Invoke(ColorCoder.ErrorBright("Slow down a little, you are sending too many commands!")); return(true); } string[] messageSplit = evt.Message.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); string command = messageSplit[0].ToLower(); List <string> parameters = messageSplit.Skip(1).ToList(); parameters = ParseParameterEscapes(parameters); ChatCommand commandToExecute = null; //Handle exceptions that occur during the parsing of the parameters try { commandToExecute = GetCommandForMessage(command, parameters, evt.InvokerUniqueId); } catch (ChatCommandNotFoundException) { messageCallback.Invoke(ColorCoder.ErrorBright("Command was not found")); return(true); } catch (ChatCommandInvalidSyntaxException ex) { messageCallback.Invoke(ColorCoder.ErrorBright($"Invalid syntax. Usage of command:\n{Settings.ChatCommandPrefix}{ex.Message}")); return(true); } catch (NoPermissionException) { messageCallback.Invoke(ColorCoder.ErrorBright($"You don't have access to this command, {ColorCoder.Username(evt.InvokerName)}")); return(true); } catch (CommandParameterInvalidFormatException ex) { messageCallback.Invoke(ColorCoder.ErrorBright($"The {ex.GetParameterPosition()} parameter's format was invalid ({ex.ParameterName} = '{ex.ParameterValue}'). It has to be {ColorCoder.Bold(ex.GetNeededType())}!\nUsage: {Settings.ChatCommandPrefix}{ex.UsageHelp}")); return(true); } catch (TimeStringParseException ex) { messageCallback.Invoke(ColorCoder.ErrorBright($"The provided time value '{ex.Input}' had invalid syntax: {ex.Message}")); return(true); } //Handle exceptions that occur during execution of the command try { commandToExecute.HandleCommand(evt, command, parameters, messageCallback); } catch (MultipleTargetsFoundException ex) { string joined = string.Join(", ", ex.AllFoundTargets.Select(client => ColorCoder.Bold($"'{client.Nickname}'"))); messageCallback.Invoke(ColorCoder.ErrorBright($"Too many targets were found with {ColorCoder.Bold($"'{ex.Message}'")} in their name ({joined})")); } catch (CooldownNotExpiredException ex) { messageCallback.Invoke(ColorCoder.ErrorBright($"That command is still on cooldown. ({ColorCoder.Bold($"{CooldownManager.FormatCooldownTime(ex.Duration)}")} cooldown)")); } catch (NoTargetsFoundException ex) { messageCallback.Invoke(ColorCoder.ErrorBright($"No targets were found with {ColorCoder.Bold($"'{ex.Message}'")} in their name...")); } catch (Exception ex) { Parent.LogMessage($"Encountered exception in command '{commandToExecute.GetType().Name}': {ex}"); } return(true); }