//
// 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"}'.");
}
}
}
}