private void Command_OnCommandInstanceAdded(object sender, CommandInstanceModel commandInstance) { if (!this.filterApplied && commandInstance.ShowInUI) { this.CommandInstances.Insert(0, new CommandInstanceViewModel(commandInstance)); } }
public void Cancel(CommandInstanceModel commandInstance) { if (commandInstance.State == CommandInstanceStateEnum.Pending || commandInstance.State == CommandInstanceStateEnum.Running) { commandInstance.State = CommandInstanceStateEnum.Canceled; } }
private async Task <Result> ValidateCommand(CommandInstanceModel commandInstance) { Result validationResult = new Result(); CommandModelBase command = commandInstance.Command; if (command != null) { validationResult = await command.CustomValidation(commandInstance.Parameters); if (validationResult.Success) { validationResult = await command.ValidateRequirements(commandInstance.Parameters); if (!validationResult.Success && ChannelSession.Settings.RequirementErrorsCooldownType != RequirementErrorCooldownTypeEnum.PerCommand) { command.CommandErrorCooldown = RequirementModelBase.UpdateErrorCooldown(); } } else { if (ChannelSession.Settings.RequirementErrorsCooldownType != RequirementErrorCooldownTypeEnum.None) { if (!string.IsNullOrEmpty(validationResult.Message) && validationResult.DisplayMessage) { await ChannelSession.Services.Chat.SendMessage(validationResult.Message); } } } if (validationResult.Success) { if (command.Requirements != null) { await command.PerformRequirements(commandInstance.Parameters); commandInstance.RunnerParameters = new List <CommandParametersModel>(command.GetPerformingUsers(commandInstance.Parameters)); } } else { if (!string.IsNullOrEmpty(validationResult.Message)) { commandInstance.ErrorMessage = validationResult.Message; commandInstance.State = CommandInstanceStateEnum.Failed; } else { commandInstance.State = CommandInstanceStateEnum.Completed; } } } return(validationResult); }
private bool CanCommandBeRunBasedOnActions(CommandInstanceModel commandInstance) { HashSet <ActionTypeEnum> actionTypes = commandInstance.GetActionTypes(); foreach (ActionTypeEnum actionType in actionTypes) { if (this.perActionTypeInUse.Contains(actionType)) { return(false); } } return(true); }
private async Task RunDirectlyInternal(CommandInstanceModel commandInstance, CommandParametersModel parameters) { CommandModelBase command = commandInstance.Command; if (command != null) { await command.PreRun(parameters); } if (command != null && command.HasCustomRun) { await commandInstance.Command.CustomRun(parameters); } else { List <ActionModelBase> actions = commandInstance.GetActions(); for (int i = 0; i < actions.Count; i++) { if (commandInstance.State == CommandInstanceStateEnum.Canceled) { return; } ActionModelBase action = actions[i]; if (action is OverlayActionModel && ChannelSession.Services.Overlay.IsConnected) { ChannelSession.Services.Overlay.StartBatching(); } await action.Perform(parameters); if (action is OverlayActionModel && ChannelSession.Services.Overlay.IsConnected) { if (i == (actions.Count - 1) || !(actions[i + 1] is OverlayActionModel)) { await ChannelSession.Services.Overlay.EndBatching(); } } } } if (commandInstance.State == CommandInstanceStateEnum.Canceled) { return; } if (command != null) { await command.PostRun(parameters); } }
public async Task RunDirectly(CommandInstanceModel commandInstance) { try { if (commandInstance.State != CommandInstanceStateEnum.Pending) { return; } CommandModelBase command = commandInstance.Command; if (command != null) { if (!command.IsEnabled || !command.HasWork) { commandInstance.State = CommandInstanceStateEnum.Canceled; return; } commandInstance.Parameters.SpecialIdentifiers[CommandModelBase.CommandNameSpecialIdentifier] = command.Name; command.TrackTelemetry(); } if (commandInstance.RunnerParameters.Count == 0) { commandInstance.RunnerParameters = new List <CommandParametersModel>() { commandInstance.Parameters }; } Logger.Log(LogLevel.Debug, $"Starting command performing: {this}"); commandInstance.State = CommandInstanceStateEnum.Running; foreach (CommandParametersModel p in commandInstance.RunnerParameters) { p.User.Data.TotalCommandsRun++; await this.RunDirectlyInternal(commandInstance, p); } if (commandInstance.State == CommandInstanceStateEnum.Running) { commandInstance.State = CommandInstanceStateEnum.Completed; } } catch (Exception ex) { Logger.Log(ex); } }
public CommandInstanceViewModel(CommandInstanceModel model) { this.model = model; this.model.OnStateUpdated += Model_OnStateUpdated; this.CancelCommand = this.CreateCommand(() => { ChannelSession.Services.Command.Cancel(this.model); return(Task.FromResult(0)); }); this.ReplayCommand = this.CreateCommand(async() => { await ChannelSession.Services.Command.Replay(this.model.Duplicate()); }); }
private async Task BackgroundCommandTypeRunner(CommandTypeEnum type) { CommandInstanceModel instance = null; do { instance = await this.commandQueueLock.WaitAndRelease(() => { CommandInstanceModel commandInstance = null; if (ChannelSession.Settings.CommandServiceLockType == CommandServiceLockTypeEnum.PerCommandType) { if (perCommandTypeInstances.ContainsKey(type) && perCommandTypeInstances[type].Count > 0) { commandInstance = perCommandTypeInstances[type].RemoveFirst(); } else { perCommandTypeTasks[type] = null; } } else if (ChannelSession.Settings.CommandServiceLockType == CommandServiceLockTypeEnum.PerActionType) { if (instance != null) { foreach (ActionTypeEnum actionType in instance.GetActionTypes()) { this.perActionTypeInUse.Remove(actionType); } } commandInstance = this.perActionTypeInstances.FirstOrDefault(c => this.CanCommandBeRunBasedOnActions(c)); if (commandInstance != null) { this.perActionTypeInstances.Remove(commandInstance); foreach (ActionTypeEnum actionType in commandInstance.GetActionTypes()) { this.perActionTypeInUse.Add(actionType); } } } else if (ChannelSession.Settings.CommandServiceLockType == CommandServiceLockTypeEnum.VisualAudioActions || ChannelSession.Settings.CommandServiceLockType == CommandServiceLockTypeEnum.Singular) { if (singularInstances.Count > 0) { commandInstance = singularInstances.RemoveFirst(); } else { singularTask = null; } } return(Task.FromResult(commandInstance)); }); if (instance != null && instance.State == CommandInstanceStateEnum.Pending) { await this.RunDirectly(instance); } } while (instance != null); }
public async Task Replay(CommandInstanceModel commandInstance) { await this.Queue(commandInstance.Duplicate()); }
public async Task RunDirectlyWithValidation(CommandInstanceModel commandInstance) { await this.ValidateCommand(commandInstance); await this.RunDirectly(commandInstance); }
public async Task Queue(CommandInstanceModel commandInstance) { if (commandInstance.Parameters.User != null) { commandInstance.Parameters.User.UpdateLastActivity(); } CommandModelBase command = commandInstance.Command; if (command != null) { if (!command.IsEnabled || !command.HasWork) { return; } await this.ValidateCommand(commandInstance); } lock (this.commandInstances) { this.commandInstances.Insert(0, commandInstance); } if (commandInstance.State == CommandInstanceStateEnum.Pending) { CommandTypeEnum type = commandInstance.QueueCommandType; if (commandInstance.DontQueue) { #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed AsyncRunner.RunAsync(() => this.RunDirectly(commandInstance)); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } else { await this.commandQueueLock.WaitAndRelease(() => { if (ChannelSession.Settings.CommandServiceLockType == CommandServiceLockTypeEnum.PerCommandType) { perCommandTypeInstances[type].Add(commandInstance); if (perCommandTypeTasks[type] == null) { perCommandTypeTasks[type] = AsyncRunner.RunAsync(() => this.BackgroundCommandTypeRunner(type)); } } else if (ChannelSession.Settings.CommandServiceLockType == CommandServiceLockTypeEnum.PerActionType) { this.perActionTypeInstances.Add(commandInstance); if (this.CanCommandBeRunBasedOnActions(commandInstance)) { this.perActionTypeTasks.Add(AsyncRunner.RunAsync(() => this.BackgroundCommandTypeRunner(type))); } } else if (ChannelSession.Settings.CommandServiceLockType == CommandServiceLockTypeEnum.VisualAudioActions) { HashSet <ActionTypeEnum> actionTypes = commandInstance.GetActionTypes(); if (actionTypes.Contains(ActionTypeEnum.Overlay) || actionTypes.Contains(ActionTypeEnum.OvrStream) || actionTypes.Contains(ActionTypeEnum.Sound) || actionTypes.Contains(ActionTypeEnum.StreamingSoftware) || actionTypes.Contains(ActionTypeEnum.TextToSpeech)) { singularInstances.Add(commandInstance); if (singularTask == null) { singularTask = AsyncRunner.RunAsync(() => this.BackgroundCommandTypeRunner(type)); } } else { #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed AsyncRunner.RunAsync(() => this.RunDirectly(commandInstance)); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } } else if (ChannelSession.Settings.CommandServiceLockType == CommandServiceLockTypeEnum.Singular) { singularInstances.Add(commandInstance); if (singularTask == null) { singularTask = AsyncRunner.RunAsync(() => this.BackgroundCommandTypeRunner(type)); } } return(Task.FromResult(0)); }); } } this.OnCommandInstanceAdded(this, commandInstance); }
protected override async Task PerformInternal(CommandParametersModel parameters) { CommandModelBase command = this.Command; if (this.ActionType == CommandActionTypeEnum.RunCommand) { if (command != null) { List <string> newArguments = new List <string>(); if (!string.IsNullOrEmpty(this.Arguments)) { string processedMessage = await ReplaceStringWithSpecialModifiers(this.Arguments, parameters); newArguments = processedMessage.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).ToList(); } else { newArguments = parameters.Arguments; } CommandParametersModel copyParameters = parameters.Duplicate(); copyParameters.Arguments = newArguments; CommandInstanceModel commandInstance = new CommandInstanceModel(command, copyParameters); if (this.WaitForCommandToFinish) { await ChannelSession.Services.Command.RunDirectlyWithValidation(commandInstance); } else { await ChannelSession.Services.Command.Queue(commandInstance); } } } else if (this.ActionType == CommandActionTypeEnum.DisableCommand || this.ActionType == CommandActionTypeEnum.EnableCommand) { if (command != null) { command.IsEnabled = (this.ActionType == CommandActionTypeEnum.EnableCommand) ? true : false; ChannelSession.Services.Chat.RebuildCommandTriggers(); } } else if (this.ActionType == CommandActionTypeEnum.DisableCommandGroup || this.ActionType == CommandActionTypeEnum.EnableCommandGroup) { IEnumerable <CommandModelBase> commands = this.CommandGroup; if (commands != null) { foreach (CommandModelBase cmd in commands) { cmd.IsEnabled = (this.ActionType == CommandActionTypeEnum.EnableCommandGroup) ? true : false; ChannelSession.Settings.Commands.ManualValueChanged(cmd.ID); } ChannelSession.Services.Chat.RebuildCommandTriggers(); } } else if (this.ActionType == CommandActionTypeEnum.CancelAllCommands) { foreach (CommandInstanceModel commandInstance in ChannelSession.Services.Command.CommandInstances.Where(c => c.State == CommandInstanceStateEnum.Pending || c.State == CommandInstanceStateEnum.Running)) { ChannelSession.Services.Command.Cancel(commandInstance); } } }