// // Copyright 2022 alterNERDtive. // // This file is part of YAVAPF. // // YAVAPF is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // YAVAPF is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with YAVAPF. If not, see <https://www.gnu.org/licenses/>. // using VoiceAttack; namespace alterNERDtive.Yavapf { /// /// Provides an interface to run VoiceAttack commands from a plugin. /// public class VoiceAttackCommands { private readonly VoiceAttackInitProxyClass vaProxy; private readonly VoiceAttackLog log; /// /// Initializes a new instance of the /// class. /// /// The /// proxy object. /// The object. internal VoiceAttackCommands(VoiceAttackInitProxyClass vaProxy, VoiceAttackLog log) => (this.vaProxy, this.log) = (vaProxy, log); /// /// Runs a VoiceAttack command. /// /// The name of the command. /// Whether or not to log a message if the /// command in question does not exist in the current profile. /// Whether to wait for the command to finish /// executing before returning. /// Whether the called command should be run as /// a subcommand to the current command context. /// The parameters for the command. Has to be /// an array of arrays, with the inner arrays being of a valid /// Voiceattack variable type. /// Thrown if the name of the /// command is missing. public void Run(string command, bool logMissing = true, bool wait = false, bool subcommand = false, dynamic[]? parameters = null) { _ = command ?? throw new ArgumentNullException("command"); if (this.vaProxy.Command.Exists(command)) { this.log.Debug($"Parsing arguments for command '{command}' …"); string[]? strings = null; int[]? integers = null; decimal[]? decimals = null; bool[]? booleans = null; DateTime[]? dates = null; // this might not work! foreach (var values in parameters ?? Enumerable.Empty()) { switch (values) { case bool[] b: booleans = b; break; case DateTime[] d: dates = d; break; case decimal[] d: decimals = d; break; case int[] i: integers = i; break; case string[] s: strings = s; break; default: break; } } this.log.Debug($"Running command '{command}' …"); this.vaProxy.Command.Execute( CommandPhrase: command, WaitForReturn: wait, AsSubcommand: subcommand, CompletedAction: null, PassedText: strings == null ? null : $"\"{string.Join("\";\"", strings)}\"", PassedIntegers: integers == null ? null : string.Join(";", integers), PassedDecimals: decimals == null ? null : string.Join(";", decimals), PassedBooleans: booleans == null ? null : string.Join(";", booleans), PassedDates: dates == null ? null : string.Join(";", dates)); } else { if (logMissing) { this.log.Warn($"Tried running missing command '{command}'."); } } } /// /// Runs a VoiceAttack command with a given list of prefixes. Will run /// `prefix.command` for each prefix. /// /// The list of prefixes. /// The name of the command. /// Whether or not to log a message if the /// command in question does not exist in the current profile. /// Whether to wait for the command to finish /// executing before returning. /// Whether the called command should be run as /// a subcommand to the current command context. /// The parameters for the command. /// Thrown if the name of the /// command is missing. public void RunAll(IEnumerable prefixes, string command, bool logMissing = true, bool wait = false, bool subcommand = false, dynamic[][]? parameters = null) { foreach (string prefix in prefixes) { this.Run($"{prefix}.{command}", logMissing, wait, subcommand, parameters); } } /// /// Runs a VoiceAttack event command. Event commands are enclosed in /// double paratheses by convention, they will be added automatically. /// /// The name of the event. /// Whether or not to log a message if the /// command in question does not exist in the current profile. /// Whether to wait for the command to finish /// executing before returning. /// Whether the called command should be run as /// a subcommand to the current command context. /// The parameters for the command. Has to be /// an array of arrays, with the inner arrays being of a valid /// Voiceattack variable type. /// Thrown if the name of the /// command is missing. public void TriggerEvent(string name, bool logMissing = true, bool wait = false, bool subcommand = false, dynamic[]? parameters = null) { this.Run($"(({name}))", logMissing, wait, subcommand, parameters); } /// /// Runs a VoiceAttack event command with a given list of prefixes. /// Event commands are enclosed in double paratheses by convention, they /// will be added automatically. Will run `((prefix.name))` for each /// prefix. /// /// The list of prefixes. /// The name of the event. /// Whether or not to log a message if the /// command in question does not exist in the current profile. /// Whether to wait for the command to finish /// executing before returning. /// Whether the called command should be run as /// a subcommand to the current command context. /// The parameters for the command. Has to be /// an array of arrays, with the inner arrays being of a valid /// Voiceattack variable type. /// Thrown if the name of the /// command is missing. public void TriggerEventAll(IEnumerable prefixes, string name, bool logMissing = true, bool wait = false, bool subcommand = false, dynamic[][]? parameters = null) { foreach (string prefix in prefixes) { this.Run($"(({prefix}.{name}))", logMissing, wait, subcommand, parameters); } } } }