// // 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 System; using alterNERDtive.Yavapf; using VoiceAttack; namespace alterNERDtive.Example { /// /// This is an example for a VoiceAttack plugin using YAVAPF. /// /// You can use this class and this project as base for your own implementation. /// public class ExamplePlugin : VoiceAttackPlugin { private static readonly ExamplePlugin Plugin; /// /// Initializes static members of the class. /// /// Since VoiceAttack’s plugin API requires a bunch of static methods /// instead of instantiating a plugin class, the “Constructor” here also /// needs to be static. It is executed right before a static method is /// used for the first time, which would usually be when VoiceAttack /// calls the method. /// static ExamplePlugin() { // You can generate a GUID in Visual Studio under “Tools” → “Create // GUID”. Choose “Registry Format”. Plugin = new () { Name = "Example Plugin", Version = "0.0.1", Info = "This is a description", Guid = "{76FE674F-F729-45FD-A1DD-E53E9E66B360}", }; // Event handlers are mainly added via attributes, see the end of // the file. // You can even add lambdas! This one logs an explicit error for // invoking the plugin without a context. Plugin.Contexts += [Context("")] (vaProxy) => { Plugin.Log.Error($"Invoking this plugin without a context is not allowed."); }; } /// /// The plugin’s display name, as required by the VoiceAttack plugin /// API. /// /// Since it is required to be static, it must be defined in your plugin /// class for VoiceAttack to pick it up as a plugin. /// /// The display name. public static string VA_DisplayName() => Plugin.VaDisplayName(); /// /// The plugin’s description, as required by the VoiceAttack plugin API. /// /// Since it is required to be static, it must be defined in your plugin /// class for VoiceAttack to pick it up as a plugin. /// /// The description. public static string VA_DisplayInfo() => Plugin.VaDisplayInfo(); /// /// The plugin’s GUID, as required by the VoiceAttack plugin API. /// /// Since it is required to be static, it must be defined in your plugin /// class for VoiceAttack to pick it up as a plugin. /// /// The GUID. public static Guid VA_Id() => Plugin.VaId(); /// /// The Init method, as required by the VoiceAttack plugin API. /// Runs when the plugin is initially loaded. /// /// Since it is required to be static, it must be defined in your plugin /// class for VoiceAttack to pick it up as a plugin. /// /// The VoiceAttack proxy object. public static void VA_Init1(dynamic vaProxy) => Plugin.VaInit1(vaProxy); /// /// The Invoke method, as required by the VoiceAttack plugin API. /// Runs whenever a plugin context is invoked. /// /// Since it is required to be static, it must be defined in your plugin /// class for VoiceAttack to pick it up as a plugin. /// /// The VoiceAttack proxy object. public static void VA_Invoke1(dynamic vaProxy) => Plugin.VaInvoke1(vaProxy); /// /// The Exit method, as required by the VoiceAttack plugin API. /// Runs when VoiceAttack is shut down. /// /// Since it is required to be static, it must be defined in your plugin /// class for VoiceAttack to pick it up as a plugin. /// /// The VoiceAttack proxy object. public static void VA_Exit1(dynamic vaProxy) => Plugin.VaExit1(vaProxy); /// /// The StopCommand method, as required by the VoiceAttack plugin API. /// Runs whenever all commands are stopped using the “Stop All Commands” /// button or action. /// /// Since it is required to be static, it must be defined in your plugin /// class for VoiceAttack to pick it up as a plugin. /// public static void VA_StopCommand() => Plugin.VaStopCommand(); /// /// An example handler for VA_Init1. Init handlers are the place to do /// anything that your plugin needs to set up when it is initially /// loaded at VoiceAttack start. /// /// The current VoiceAttack proxy object. [Init] public static void Init(VoiceAttackInitProxyClass vaProxy) { Plugin.Log.Notice("This is the example Init handler method."); } /// /// An example handler for VA_Exit1. Exit handlers have to make sure /// your plugin is properly shut down with VoiceAttack. Do note that /// there is a default timeout of 5s. /// /// The current VoiceAttack proxy object. [Exit] public static void Exit(VoiceAttackProxyClass vaProxy) { Plugin.Log.Notice("This is the example Exit handler method."); } /// /// An example handler for VA_StopCommand. If your plugin needs to /// execute anything when all commands are stopped this is the place. /// [StopCommand] public static void StopCommand() { Plugin.Log.Notice("This is the example StopCommand handler method."); } /// /// An example handler for plugin contexts. The context(s) must be /// specified with “Context” attributes. Contexts must be all lower case. /// /// This example handles the “test” and “different test” plugin /// contexts. They expect that a text parameter “~test” is set in /// VoiceAttack. /// /// The current VoiceAttack proxy object. [Context("test")] [Context("different test")] public static void Test(VoiceAttackInvokeProxyClass vaProxy) { Plugin.Log.Notice( $"This is the example handler for the plugin contexts “test” and “different test”. It has been invoked with '{vaProxy.Context}'."); string test = vaProxy.Get("~test") ?? throw new ArgumentNullException("~test"); Plugin.Log.Notice($"The value of 'TXT:~test' is '{test}'"); } /// /// An example handler for plugin contexts. The context(s) must be /// specified with “Context” attributes. Contexts must be all lower case. /// /// This example demonstrates using regular expressions. It handles all /// contexts that begin with “foo” or contain “bar”. /// /// The current VoiceAttack proxy object. [Context(@"^foo.*")] [Context(@"^.*bar.*")] public static void RegexContext(VoiceAttackInvokeProxyClass vaProxy) { Plugin.Log.Notice( $"This is the example handler for the plugin contexts “^foo.*” and “^.*bar.*”. It has been invoked with '{vaProxy.Context}'."); } /// /// An example handler for changed variables. It only /// applies to the “isDay#” variable. /// /// The name of the variable. /// The old value of the variable. /// The new value of the variable. [Bool("isDay#")] public static void DayChanged(string name, bool? from, bool? to) { Plugin.Log.Notice($"This is the example handler for changed bool variables. It is now {(to ?? false ? "day" : "night")}."); } /// /// An example handler for changed variables. It /// doesn’t specify a name, so it applies to all of them. /// /// The name of the variable. /// The old value of the variable. /// The new value of the variable. [String] public static void StringChanged(string name, string? from, string? to) { // exclude log level changes if (name != $"{Plugin.Name}.loglevel#") { Plugin.Log.Notice($"This is the example handler for changed string variables. '{name}' changed from '{from ?? "Not Set"}' to '{to ?? "Not Set"}'."); } } } }