2022-07-05 00:19:04 +02:00
|
|
|
|
// <copyright file="VoiceAttackPlugin.cs" company="alterNERDtive">
|
|
|
|
|
// 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/>.
|
|
|
|
|
// </copyright>
|
|
|
|
|
|
|
|
|
|
using System;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
2022-07-08 22:31:25 +02:00
|
|
|
|
using System.Linq;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
using System.Reflection;
|
2022-07-08 20:22:50 +02:00
|
|
|
|
using System.Text.RegularExpressions;
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
2022-07-07 14:58:12 +02:00
|
|
|
|
using VoiceAttack;
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
|
|
|
|
namespace alterNERDtive.Yavapf
|
|
|
|
|
{
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Framework class for implementing a VoiceAttack plugin.
|
|
|
|
|
/// </summary>
|
2022-07-05 00:19:04 +02:00
|
|
|
|
public class VoiceAttackPlugin
|
|
|
|
|
{
|
2022-07-08 20:22:50 +02:00
|
|
|
|
private VoiceAttackLog? log;
|
|
|
|
|
private VoiceAttackInitProxyClass? vaProxy;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when VoiceAttack initializes the plugin.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
protected event Action<VoiceAttackInitProxyClass>? InitActions;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when VoiceAttack closes.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
protected event Action<VoiceAttackProxyClass>? ExitActions;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when VoiceAttack stops all commands.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
protected event Action? StopActions;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the Actions to be run when the plugin is invoked from a
|
|
|
|
|
/// VoiceAttack command. Only Actions with a matching “Context”
|
|
|
|
|
/// attribute will be invoked.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
protected HandlerList<Action<VoiceAttackInvokeProxyClass>> Contexts { get; set; } = new ();
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the Actions to be run when a <see cref="bool"/>
|
|
|
|
|
/// variable changed.
|
|
|
|
|
/// </summary>
|
2022-07-11 01:46:42 +02:00
|
|
|
|
protected HandlerList<Action<string, bool?, bool?>> BoolChangedHandlers { get; set; } = new ();
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the Actions to be run when a <see cref="DateTime"/>
|
|
|
|
|
/// variable changed.
|
|
|
|
|
/// </summary>
|
2022-07-11 01:46:42 +02:00
|
|
|
|
protected HandlerList<Action<string, DateTime?, DateTime?>> DateTimeChangedHandlers { get; set; } = new ();
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the Actions to be run when a <see cref="decimal"/>
|
|
|
|
|
/// variable changed.
|
|
|
|
|
/// </summary>
|
2022-07-11 01:46:42 +02:00
|
|
|
|
protected HandlerList<Action<string, decimal?, decimal?>> DecimalChangedHandlers { get; set; } = new ();
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the Actions to be run when a <see cref="int"/>
|
|
|
|
|
/// variable changed.
|
|
|
|
|
/// </summary>
|
2022-07-11 01:46:42 +02:00
|
|
|
|
protected HandlerList<Action<string, int?, int?>> IntChangedHandlers { get; set; } = new ();
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the Actions to be run when a <see cref="string"/>
|
|
|
|
|
/// variable changed.
|
|
|
|
|
/// </summary>
|
2022-07-11 01:46:42 +02:00
|
|
|
|
protected HandlerList<Action<string, string?, string?>> StringChangedHandlers { get; set; } = new ();
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the currently stored VoiceAttackInitProxyClass object which is
|
|
|
|
|
/// used to interface with VoiceAttack.
|
|
|
|
|
///
|
|
|
|
|
/// You will usually want to use the provided methods and Properties
|
|
|
|
|
/// instead.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
protected VoiceAttackInitProxyClass Proxy
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-08 20:22:50 +02:00
|
|
|
|
get => this.vaProxy!;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
/// Gets or sets the name of the plugin.
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// </summary>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected string? Name { get; set; }
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
/// Gets or sets the current version of the plugin.
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// </summary>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected string? Version { get; set; }
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
/// Gets or sets the description of the plugin.
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// </summary>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected string? Info { get; set; }
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
/// Gets or sets the GUID of the plugin.
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// </summary>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected string? Guid { get; set; }
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the <see cref="VoiceAttackLog"/> instance the plugin uses to
|
|
|
|
|
/// log to the VoiceAttack event log.
|
2022-07-09 00:30:51 +02:00
|
|
|
|
///
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// You can use this to log your own messages.
|
|
|
|
|
/// </summary>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected VoiceAttackLog Log
|
2022-07-08 20:22:50 +02:00
|
|
|
|
{
|
2022-07-09 00:30:51 +02:00
|
|
|
|
get => this.log ??= new VoiceAttackLog(this.Proxy, this.Name!);
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the value of a variable from VoiceAttack.
|
|
|
|
|
///
|
|
|
|
|
/// Valid varible types are <see cref="bool"/>, <see cref="DateTime"/>,
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <see cref="decimal"/>, <see cref="int"/> and <see cref="string"/>.
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of the variable.</typeparam>
|
|
|
|
|
/// <param name="name">The name of the variable.</param>
|
|
|
|
|
/// <returns>The value of the variable. Can be null.</returns>
|
|
|
|
|
/// <exception cref="InvalidDataException">Thrown when the variable is of an invalid type.</exception>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected T? Get<T>(string name)
|
2022-07-08 20:22:50 +02:00
|
|
|
|
{
|
2022-07-11 10:25:06 +02:00
|
|
|
|
if (name.StartsWith("~"))
|
2022-07-08 20:22:50 +02:00
|
|
|
|
{
|
2022-07-11 10:25:06 +02:00
|
|
|
|
this.Log.Warn(
|
|
|
|
|
$"Accessing command scoped variable '{name}' outside of its context proxy object. This might lead to race conditions.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.Proxy.Get<T>(name);
|
2022-07-08 20:22:50 +02:00
|
|
|
|
}
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets a variable for use in VoiceAttack.
|
|
|
|
|
///
|
|
|
|
|
/// Valid varible types are <see cref="bool"/>, <see cref="DateTime"/>,
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <see cref="decimal"/>, <see cref="int"/> and <see cref="string"/>.
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of the variable.</typeparam>
|
|
|
|
|
/// <param name="name">The name of the variable.</param>
|
|
|
|
|
/// <param name="value">The value of the variable. Can not be null.</param>
|
|
|
|
|
/// <exception cref="InvalidDataException">Thrown when the variable is of an invalid type.</exception>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected void Set<T>(string name, T? value)
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 10:25:06 +02:00
|
|
|
|
if (name.StartsWith("~"))
|
2022-07-08 20:22:50 +02:00
|
|
|
|
{
|
2022-07-11 10:25:06 +02:00
|
|
|
|
this.Log.Warn(
|
|
|
|
|
$"Accessing command scoped variable '{name}' outside of its context proxy object. This might lead to race conditions.");
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-11 10:25:06 +02:00
|
|
|
|
|
|
|
|
|
this.Proxy.Set<T>(name, value);
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Unsets a variable for use in VoiceAttack (= sets it to null).
|
|
|
|
|
///
|
|
|
|
|
/// Valid varible types are <see cref="bool"/>, <see cref="DateTime"/>,
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <see cref="decimal"/>, <see cref="int"/> and <see cref="string"/>.
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of the variable.</typeparam>
|
|
|
|
|
/// <param name="name">The name of the variable.</param>
|
|
|
|
|
/// <exception cref="InvalidDataException">Thrown when the variable is of an invalid type.</exception>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected void Unset<T>(string name)
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 10:25:06 +02:00
|
|
|
|
if (name.StartsWith("~"))
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 10:25:06 +02:00
|
|
|
|
this.Log.Warn(
|
|
|
|
|
$"Accessing command scoped variable '{name}' outside of its context proxy object. This might lead to race conditions.");
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-11 10:25:06 +02:00
|
|
|
|
|
|
|
|
|
this.Proxy.Unset<T>(name);
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The plugin’s display name, as required by the VoiceAttack plugin API.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The display name.</returns>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected string VaDisplayName() => $"{this.Name} v{this.Version}";
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The plugin’s description, as required by the VoiceAttack plugin API.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The description.</returns>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected string VaDisplayInfo() => this.Info!;
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The plugin’s GUID, as required by the VoiceAttack plugin API.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The GUID.</returns>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected Guid VaId() => new (this.Guid);
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The Init method, as required by the VoiceAttack plugin API.
|
|
|
|
|
/// Runs when the plugin is initially loaded.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected void VaInit1(VoiceAttackInitProxyClass vaProxy)
|
2022-07-05 00:19:04 +02:00
|
|
|
|
{
|
|
|
|
|
this.vaProxy = vaProxy;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
|
|
|
|
this.Set<string>($"{this.Name}.version", this.Version);
|
|
|
|
|
this.Log.Debug($"Initializing v{this.Version} …");
|
|
|
|
|
|
|
|
|
|
this.vaProxy.BooleanVariableChanged += this.BooleanVariableChanged;
|
|
|
|
|
this.vaProxy.DateVariableChanged += this.DateVariableChanged;
|
2022-07-09 00:30:51 +02:00
|
|
|
|
this.vaProxy.DecimalVariableChanged += this.DecimalVariableChanged;
|
|
|
|
|
this.vaProxy.IntegerVariableChanged += this.IntegerVariableChanged;
|
|
|
|
|
this.vaProxy.TextVariableChanged += this.TextVariableChanged;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<InitAttribute>().Any()).ToList().ForEach(
|
|
|
|
|
m => this.InitActions += (Action<VoiceAttackInitProxyClass>)m.CreateDelegate(typeof(Action<VoiceAttackInitProxyClass>)));
|
2022-07-08 22:31:25 +02:00
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<ExitAttribute>().Any()).ToList().ForEach(
|
|
|
|
|
m => this.ExitActions += (Action<VoiceAttackProxyClass>)m.CreateDelegate(typeof(Action<VoiceAttackProxyClass>)));
|
2022-07-08 22:31:25 +02:00
|
|
|
|
|
2022-07-11 01:46:42 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<StopCommandAttribute>().Any()).ToList().ForEach(
|
2022-07-09 16:33:32 +02:00
|
|
|
|
m => this.StopActions += (Action)m.CreateDelegate(typeof(Action)));
|
2022-07-08 22:31:25 +02:00
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<ContextAttribute>().Any()).ToList().ForEach(
|
|
|
|
|
m => this.Contexts += (Action<VoiceAttackInvokeProxyClass>)m.CreateDelegate(typeof(Action<VoiceAttackInvokeProxyClass>)));
|
2022-07-08 22:31:25 +02:00
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<BoolAttribute>().Any()).ToList().ForEach(
|
2022-07-11 01:46:42 +02:00
|
|
|
|
m => this.BoolChangedHandlers += (Action<string, bool?, bool?>)m.CreateDelegate(typeof(Action<string, bool?, bool?>)));
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<DateTimeAttribute>().Any()).ToList().ForEach(
|
2022-07-11 01:46:42 +02:00
|
|
|
|
m => this.DateTimeChangedHandlers += (Action<string, DateTime?, DateTime?>)m.CreateDelegate(typeof(Action<string, DateTime?, DateTime?>)));
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<DecimalAttribute>().Any()).ToList().ForEach(
|
2022-07-11 01:46:42 +02:00
|
|
|
|
m => this.DecimalChangedHandlers += (Action<string, decimal?, decimal?>)m.CreateDelegate(typeof(Action<string, decimal?, decimal?>)));
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<IntAttribute>().Any()).ToList().ForEach(
|
2022-07-11 01:46:42 +02:00
|
|
|
|
m => this.IntChangedHandlers += (Action<string, int?, int?>)m.CreateDelegate(typeof(Action<string, int?, int?>)));
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
this.GetType().GetMethods().Where(m => m.GetCustomAttributes<StringAttribute>().Any()).ToList().ForEach(
|
2022-07-11 01:46:42 +02:00
|
|
|
|
m => this.StringChangedHandlers += (Action<string, string?, string?>)m.CreateDelegate(typeof(Action<string, string?, string?>)));
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
2022-07-07 14:58:12 +02:00
|
|
|
|
this.Log.Debug("Running Init handlers …");
|
2022-07-08 22:31:25 +02:00
|
|
|
|
this.InitActions?.Invoke(vaProxy);
|
2022-07-07 14:58:12 +02:00
|
|
|
|
this.Log.Debug("Finished running Init handlers.");
|
|
|
|
|
|
|
|
|
|
this.Set<bool>($"{this.Name}.initialized", true);
|
|
|
|
|
this.Log.Debug("Initialized.");
|
2022-07-05 00:19:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The Invoke method, as required by the VoiceAttack plugin API.
|
|
|
|
|
/// Runs whenever a plugin context is invoked.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected void VaInvoke1(VoiceAttackInvokeProxyClass vaProxy)
|
2022-07-05 00:19:04 +02:00
|
|
|
|
{
|
|
|
|
|
this.vaProxy = vaProxy;
|
2022-07-07 14:58:12 +02:00
|
|
|
|
|
|
|
|
|
string context = vaProxy.Context.ToLower();
|
|
|
|
|
|
2022-07-11 01:46:42 +02:00
|
|
|
|
if (context.StartsWith("log."))
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
try
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
string message = this.Get<string>("~message") ?? throw new ArgumentNullException("~message");
|
|
|
|
|
switch (context)
|
2022-07-09 00:30:51 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
case "log.error":
|
|
|
|
|
this.Log.Error(message);
|
|
|
|
|
break;
|
|
|
|
|
case "log.warn":
|
|
|
|
|
this.Log.Warn(message);
|
|
|
|
|
break;
|
|
|
|
|
case "log.notice":
|
|
|
|
|
this.Log.Notice(message);
|
|
|
|
|
break;
|
|
|
|
|
case "log.info":
|
|
|
|
|
this.Log.Info(message);
|
|
|
|
|
break;
|
|
|
|
|
case "log.debug":
|
|
|
|
|
this.Log.Debug(message);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw new ArgumentException("invalid context", "context");
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-11 01:46:42 +02:00
|
|
|
|
catch (ArgumentNullException e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
|
|
|
|
}
|
|
|
|
|
catch (ArgumentException e) when (e.ParamName == "context")
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Unhandled exception while executing plugin context '{context}': {e.Message}");
|
|
|
|
|
}
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-09 00:30:51 +02:00
|
|
|
|
else
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
List<Action<VoiceAttackInvokeProxyClass>> actions = this.Contexts.Where(
|
|
|
|
|
action => action.Method.GetCustomAttributes<ContextAttribute>().Where(
|
|
|
|
|
attr => attr.Name == context ||
|
|
|
|
|
(attr.Name.StartsWith("^") && Regex.Match(context, attr.Name).Success))
|
|
|
|
|
.Any()).ToList();
|
|
|
|
|
|
|
|
|
|
if (actions.Any())
|
|
|
|
|
{
|
|
|
|
|
foreach (Action<VoiceAttackInvokeProxyClass> action in actions)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
action.Invoke(vaProxy);
|
|
|
|
|
}
|
|
|
|
|
catch (ArgumentNullException e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
|
|
|
|
}
|
|
|
|
|
catch (ArgumentException e) when (e.ParamName == "context")
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Unhandled exception while executing plugin context '{context}': {e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
|
|
|
|
}
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-05 00:19:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The Exit method, as required by the VoiceAttack plugin API.
|
|
|
|
|
/// Runs when VoiceAttack is shut down.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected void VaExit1(VoiceAttackProxyClass vaProxy)
|
2022-07-05 00:19:04 +02:00
|
|
|
|
{
|
2022-07-08 22:31:25 +02:00
|
|
|
|
this.ExitActions?.Invoke(vaProxy);
|
2022-07-05 00:19:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 20:22:50 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The StopCommand method, as required by the VoiceAttack plugin API.
|
|
|
|
|
/// Runs whenever all commands are stopped using the “Stop All Commands”
|
|
|
|
|
/// button or action.
|
|
|
|
|
/// </summary>
|
2022-07-09 00:30:51 +02:00
|
|
|
|
protected void VaStopCommand()
|
2022-07-05 00:19:04 +02:00
|
|
|
|
{
|
2022-07-08 22:31:25 +02:00
|
|
|
|
this.StopActions?.Invoke();
|
2022-07-05 00:19:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when a <see cref="bool"/> variable changed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of the variable.</param>
|
|
|
|
|
/// <param name="from">The old value of the variable.</param>
|
|
|
|
|
/// <param name="to">The new value of the variable.</param>
|
|
|
|
|
/// <param name="internalID">The internal GUID of the variable.</param>
|
|
|
|
|
private void BooleanVariableChanged(string name, bool? from, bool? to, Guid? internalID = null)
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
foreach (Action<string, bool?, bool?> action in this.BoolChangedHandlers.Where(
|
2022-07-09 00:30:51 +02:00
|
|
|
|
action => action.Method.GetCustomAttributes<BoolAttribute>().Where(
|
|
|
|
|
attr => attr.Name == name ||
|
2022-07-09 00:42:57 +02:00
|
|
|
|
(attr.Name.StartsWith("^") && Regex.Match(name, attr.Name).Success))
|
|
|
|
|
.Any()).ToList())
|
2022-07-09 00:30:51 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
action.Invoke(name, from, to);
|
2022-07-09 00:30:51 +02:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Unhandled exception while handling changed bool variable '{name}': {e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when a <see cref="DateTime"/> variable changed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of the variable.</param>
|
|
|
|
|
/// <param name="from">The old value of the variable.</param>
|
|
|
|
|
/// <param name="to">The new value of the variable.</param>
|
|
|
|
|
/// <param name="internalID">The internal GUID of the variable.</param>
|
|
|
|
|
private void DateVariableChanged(string name, DateTime? from, DateTime? to, Guid? internalID = null)
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
foreach (Action<string, DateTime?, DateTime?> action in this.DateTimeChangedHandlers.Where(
|
2022-07-09 00:30:51 +02:00
|
|
|
|
action => action.Method.GetCustomAttributes<DateTimeAttribute>().Where(
|
|
|
|
|
attr => attr.Name == name ||
|
2022-07-09 00:42:57 +02:00
|
|
|
|
(attr.Name.StartsWith("^") && Regex.Match(name, attr.Name).Success))
|
|
|
|
|
.Any()).ToList())
|
2022-07-09 00:30:51 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
action.Invoke(name, from, to);
|
2022-07-09 00:30:51 +02:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Unhandled exception while handling changed DateTime variable '{name}': {e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when a <see cref="decimal"/> variable changed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of the variable.</param>
|
|
|
|
|
/// <param name="from">The old value of the variable.</param>
|
|
|
|
|
/// <param name="to">The new value of the variable.</param>
|
|
|
|
|
/// <param name="internalID">The internal GUID of the variable.</param>
|
|
|
|
|
private void DecimalVariableChanged(string name, decimal? from, decimal? to, Guid? internalID = null)
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
foreach (Action<string, decimal?, decimal?> action in this.DecimalChangedHandlers.Where(
|
2022-07-09 00:30:51 +02:00
|
|
|
|
action => action.Method.GetCustomAttributes<DecimalAttribute>().Where(
|
|
|
|
|
attr => attr.Name == name ||
|
2022-07-09 00:42:57 +02:00
|
|
|
|
(attr.Name.StartsWith("^") && Regex.Match(name, attr.Name).Success))
|
|
|
|
|
.Any()).ToList())
|
2022-07-09 00:30:51 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
action.Invoke(name, from, to);
|
2022-07-09 00:30:51 +02:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Unhandled exception while handling changed decimal variable '{name}': {e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when a <see cref="int"/> variable changed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of the variable.</param>
|
|
|
|
|
/// <param name="from">The old value of the variable.</param>
|
|
|
|
|
/// <param name="to">The new value of the variable.</param>
|
|
|
|
|
/// <param name="internalID">The internal GUID of the variable.</param>
|
|
|
|
|
private void IntegerVariableChanged(string name, int? from, int? to, Guid? internalID = null)
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
foreach (Action<string, int?, int?> action in this.IntChangedHandlers.Where(
|
2022-07-09 00:30:51 +02:00
|
|
|
|
action => action.Method.GetCustomAttributes<IntAttribute>().Where(
|
|
|
|
|
attr => attr.Name == name ||
|
2022-07-09 00:42:57 +02:00
|
|
|
|
(attr.Name.StartsWith("^") && Regex.Match(name, attr.Name).Success))
|
|
|
|
|
.Any()).ToList())
|
2022-07-09 00:30:51 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
action.Invoke(name, from, to);
|
2022-07-09 00:30:51 +02:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Unhandled exception while handling changed int variable '{name}': {e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when a <see cref="string"/> variable changed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of the variable.</param>
|
|
|
|
|
/// <param name="from">The old value of the variable.</param>
|
|
|
|
|
/// <param name="to">The new value of the variable.</param>
|
|
|
|
|
/// <param name="internalID">The internal GUID of the variable.</param>
|
|
|
|
|
private void TextVariableChanged(string name, string? from, string? to, Guid? internalID = null)
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
if (name == $"{this.Name}.loglevel#")
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
this.Log.SetLogLevel(to);
|
|
|
|
|
}
|
|
|
|
|
catch (ArgumentException)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Error setting log level: '{to!}' is not a valid log level.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (Action<string, string?, string?> action in this.StringChangedHandlers.Where(
|
2022-07-09 00:30:51 +02:00
|
|
|
|
action => action.Method.GetCustomAttributes<StringAttribute>().Where(
|
|
|
|
|
attr => attr.Name == name ||
|
2022-07-09 00:42:57 +02:00
|
|
|
|
(attr.Name.StartsWith("^") && Regex.Match(name, attr.Name).Success))
|
|
|
|
|
.Any()).ToList())
|
2022-07-09 00:30:51 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
action.Invoke(name, from, to);
|
2022-07-09 00:30:51 +02:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
this.Log.Error($"Unhandled exception while handling changed string variable '{name}': {e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// A list of event handlers (Actions). Basically just a list that
|
|
|
|
|
/// implements the + and - operators because they look nice.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of the list.</typeparam>
|
|
|
|
|
protected class HandlerList<T> : List<T>
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-09 16:33:32 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds a handler to the list.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="handlers">The list to add to.</param>
|
|
|
|
|
/// <param name="item">The handler to add.</param>
|
|
|
|
|
/// <returns>The sum of both.</returns>
|
2022-07-07 14:58:12 +02:00
|
|
|
|
public static HandlerList<T> operator +(HandlerList<T> handlers, T item)
|
|
|
|
|
{
|
|
|
|
|
handlers.Add(item);
|
|
|
|
|
return handlers;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 16:33:32 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Removes a handler from the list.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="handlers">The list to remove from.</param>
|
|
|
|
|
/// <param name="item">The handler to remove.</param>
|
|
|
|
|
/// <returns>The list without the handler.</returns>
|
2022-07-07 14:58:12 +02:00
|
|
|
|
public static HandlerList<T> operator -(HandlerList<T> handlers, T item)
|
|
|
|
|
{
|
|
|
|
|
handlers.Remove(item);
|
|
|
|
|
return handlers;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for <see
|
|
|
|
|
/// cref="VaInit1(VoiceAttackInitProxyClass)"/>.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[AttributeUsage(AttributeTargets.Method)]
|
2022-07-08 22:31:25 +02:00
|
|
|
|
protected class InitAttribute : Attribute
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for <see
|
2022-07-09 00:42:57 +02:00
|
|
|
|
/// cref="VaExit1(VoiceAttackProxyClass)"/>.
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
[AttributeUsage(AttributeTargets.Method)]
|
2022-07-08 22:31:25 +02:00
|
|
|
|
protected class ExitAttribute : Attribute
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for <see cref="VaStopCommand()"/>.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[AttributeUsage(AttributeTargets.Method)]
|
2022-07-11 01:46:42 +02:00
|
|
|
|
protected class StopCommandAttribute : Attribute
|
2022-07-08 22:31:25 +02:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for a plugin contexts.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
|
|
|
|
protected class ContextAttribute : Attribute
|
|
|
|
|
{
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="ContextAttribute"/>
|
|
|
|
|
/// class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of or regex for the context.</param>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
public ContextAttribute(string name)
|
|
|
|
|
{
|
2022-07-11 01:46:42 +02:00
|
|
|
|
this.Name = name.ToLower();
|
2022-07-08 22:31:25 +02:00
|
|
|
|
}
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="ContextAttribute"/>
|
|
|
|
|
/// class that will be invoked for all contexts.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ContextAttribute()
|
|
|
|
|
{
|
|
|
|
|
this.Name = "^.*";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the name of or regex for the context.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; }
|
2022-07-08 22:31:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for changed <see cref="bool"/> variables.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
|
|
|
|
protected class BoolAttribute : Attribute
|
|
|
|
|
{
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="BoolAttribute"/>
|
|
|
|
|
/// class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of or regex for the variable.</param>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
public BoolAttribute(string name)
|
|
|
|
|
{
|
|
|
|
|
this.Name = name;
|
|
|
|
|
}
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="BoolAttribute"/>
|
|
|
|
|
/// class that will be invoked for all variables.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public BoolAttribute()
|
|
|
|
|
{
|
|
|
|
|
this.Name = "^.*";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the name of or regex for the variable name.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; }
|
2022-07-08 22:31:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for changed <see cref="DateTime"/> variables.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
|
|
|
|
protected class DateTimeAttribute : Attribute
|
|
|
|
|
{
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see
|
|
|
|
|
/// cref="DateTimeAttribute"/> class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of or regex for the variable.</param>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
public DateTimeAttribute(string name)
|
|
|
|
|
{
|
|
|
|
|
this.Name = name;
|
|
|
|
|
}
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see
|
|
|
|
|
/// cref="DateTimeAttribute"/> class that will be invoked for all
|
|
|
|
|
/// variables.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public DateTimeAttribute()
|
|
|
|
|
{
|
|
|
|
|
this.Name = "^.*";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the name of or regex for the variable.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; }
|
2022-07-08 22:31:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for changed <see cref="decimal"/> variables.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
|
|
|
|
protected class DecimalAttribute : Attribute
|
|
|
|
|
{
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="DecimalAttribute"/>
|
|
|
|
|
/// class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of or regex for the variable.</param>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
public DecimalAttribute(string name)
|
|
|
|
|
{
|
|
|
|
|
this.Name = name;
|
|
|
|
|
}
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="DecimalAttribute"/>
|
|
|
|
|
/// class that will be invoked for all variables.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public DecimalAttribute()
|
|
|
|
|
{
|
|
|
|
|
this.Name = "^.*";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the name of or regex for the variable.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; }
|
2022-07-08 22:31:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for changed <see cref="int"/> variables.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
|
|
|
|
protected class IntAttribute : Attribute
|
|
|
|
|
{
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="IntAttribute"/>
|
|
|
|
|
/// class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of or regex for the variable.</param>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
public IntAttribute(string name)
|
|
|
|
|
{
|
|
|
|
|
this.Name = name;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="IntAttribute"/>
|
|
|
|
|
/// class that will be invoked for all variables.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IntAttribute()
|
2022-07-08 22:31:25 +02:00
|
|
|
|
{
|
2022-07-09 00:30:51 +02:00
|
|
|
|
this.Name = "^.*";
|
2022-07-08 22:31:25 +02:00
|
|
|
|
}
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the name of or regex for the variable.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; }
|
2022-07-08 22:31:25 +02:00
|
|
|
|
}
|
2022-07-05 00:19:04 +02:00
|
|
|
|
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Denotes a handler for changed <see cref="string"/> variables.
|
|
|
|
|
/// </summary>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
|
|
|
|
protected class StringAttribute : Attribute
|
2022-07-07 14:58:12 +02:00
|
|
|
|
{
|
2022-07-09 00:30:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="StringAttribute"/>
|
|
|
|
|
/// class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of or regex for the variable.</param>
|
2022-07-08 22:31:25 +02:00
|
|
|
|
public StringAttribute(string name)
|
|
|
|
|
{
|
|
|
|
|
this.Name = name;
|
|
|
|
|
}
|
2022-07-09 00:30:51 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="StringAttribute"/>
|
|
|
|
|
/// class that is invoked for all variables.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public StringAttribute()
|
|
|
|
|
{
|
|
|
|
|
this.Name = "^.*";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the name of or regex for the variable.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; }
|
2022-07-07 14:58:12 +02:00
|
|
|
|
}
|
2022-07-05 00:19:04 +02:00
|
|
|
|
}
|
|
|
|
|
}
|