Merge branch 'devel' into release
This commit is contained in:
commit
9beb6dfa41
32 changed files with 2140 additions and 1559 deletions
|
@ -1,4 +1,4 @@
|
||||||
[*]
|
[*]
|
||||||
guidelines = 80
|
guidelines = 80
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
@ -6,3 +6,9 @@ charset = utf-8-bom
|
||||||
|
|
||||||
[*.cs]
|
[*.cs]
|
||||||
guidelines = 80, 120
|
guidelines = 80, 120
|
||||||
|
|
||||||
|
# IDE0021: Use block body for constructors
|
||||||
|
csharp_style_expression_bodied_constructors = when_on_single_line
|
||||||
|
|
||||||
|
# IDE0024: Use block body for operators
|
||||||
|
csharp_style_expression_bodied_operators = when_on_single_line
|
||||||
|
|
19
.github/workflows/create-release.yaml
vendored
Normal file
19
.github/workflows/create-release.yaml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
name: Create release on tag push
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'releases/*.*'
|
||||||
|
- 'releases/*.*.*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Create draft release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Draft release
|
||||||
|
uses: ncipollo/release-action@v1
|
||||||
|
with:
|
||||||
|
bodyFile: "CHANGELOG.md"
|
||||||
|
draft: true
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -358,3 +358,4 @@ MigrationBackup/
|
||||||
/Makefile
|
/Makefile
|
||||||
/site
|
/site
|
||||||
/src
|
/src
|
||||||
|
/build.csproj
|
||||||
|
|
42
CHANGELOG.md
42
CHANGELOG.md
|
@ -1,4 +1,42 @@
|
||||||
# 4.3 (2022-05-19)
|
# 4.4 (2022-05-31)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* The Configuration GUI now has an “Apply” button.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* Configuration GUI now `.Activate()`s immediately to prevent it from hiding
|
||||||
|
behind other windows.
|
||||||
|
|
||||||
|
## EliteAttack 8.4
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* `auto retract landing gear` setting: Automatically retract landing gear when
|
||||||
|
lifting off a planet / undocking from a station. Default: true. (#133)
|
||||||
|
* `auto disable s r v lights` setting: Automatically turn SRV lights off when
|
||||||
|
deploying one. Default: true. (#133)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* `auto enter station services` option. (#142)
|
||||||
|
|
||||||
|
## RatAttack 6.3.1
|
||||||
|
|
||||||
|
* Added error message to the CLI tool for running VoiceAttack with elevated
|
||||||
|
privileges which will cause an `UnAuthorizedAccessException` trying to
|
||||||
|
communicate with the plugin. (#138)
|
||||||
|
* Added warning to VoiceAttack when running it with elevated privileges. (#138)
|
||||||
|
|
||||||
|
## SpashAttack 7.2.2
|
||||||
|
|
||||||
|
* Fixed getting current jump range from EDDI; no longer fails on the first try,
|
||||||
|
no longer sometimes reports the last requested range instead of current.
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
# 4.3 (2022-05-19)
|
||||||
|
|
||||||
**NOTE**: Further development is on hold and Odyssey compatibility will not be
|
**NOTE**: Further development is on hold and Odyssey compatibility will not be
|
||||||
worked on for the time being. See [the corresponding issue on
|
worked on for the time being. See [the corresponding issue on
|
||||||
|
@ -52,7 +90,7 @@ the job.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Now gives feedback after asking for call confirmation: “Call aborted.”
|
* Now gives feedback after asking for call confirmation: “Call aborted.” /
|
||||||
“Calling <…>.”.
|
“Calling <…>.”.
|
||||||
* `auto copy rat case system` setting: Automatically copy the client’s system to
|
* `auto copy rat case system` setting: Automatically copy the client’s system to
|
||||||
the clipboard when you open a rat case. Default: true.
|
the clipboard when you open a rat case. Default: true.
|
||||||
|
|
25
Directory.build.props
Normal file
25
Directory.build.props
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<LangVersion>10.0</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
<!-- StyleCop Analyzers configuration -->
|
||||||
|
<PropertyGroup>
|
||||||
|
<CodeAnalysisRuleSet>$(SolutionDir)StyleCop.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="StyleCop.Analyzers.Error" Version="1.0.2">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="StyleCop.CSharp.Async.Rules" Version="6.1.41">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<AdditionalFiles Include="$(SolutionDir)stylecop.json" Link="stylecop.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
4.3
|
4.4
|
||||||
|
|
|
@ -18,6 +18,10 @@ Toggles:
|
||||||
at a station. Default: true.
|
at a station. Default: true.
|
||||||
* `auto enter station services`: Automatically enter the Station Services menu
|
* `auto enter station services`: Automatically enter the Station Services menu
|
||||||
after docking at a station. Default: true.
|
after docking at a station. Default: true.
|
||||||
|
* `auto retract landing gear`: Automatically retract landing gear when lifting
|
||||||
|
off a planet / undocking from a station. Default: true. (#133)
|
||||||
|
* `auto disable s r v lights`: Automatically turn SRV lights off when deploying
|
||||||
|
one. Default: true. (#133)
|
||||||
* `edsm system status`: Pull system data from EDSM and compare it
|
* `edsm system status`: Pull system data from EDSM and compare it
|
||||||
against your discovery scan. Default: true.
|
against your discovery scan. Default: true.
|
||||||
* `discovery scan on primary fire`: Use primary fire for honking instead of
|
* `discovery scan on primary fire`: Use primary fire for honking instead of
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The base profile provides voice commands for changing the profiles settings.
|
The base profile provides voice commands for changing the profiles settings.
|
||||||
See [the configuration section](../configuration/general#settings).
|
See [the configuration section](../configuration/general#settings).
|
||||||
|
|
||||||
## Chat
|
## Chat
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Upgrading
|
# Upgrading
|
||||||
|
|
||||||
To upgrade to the latest version, follow these simple steps:
|
To upgrade to the latest version, follow these simple steps:
|
||||||
|
|
||||||
|
@ -29,6 +29,13 @@ Please do not fiddle with the configuration variables from your startup command
|
||||||
entirely unnecessary since configuration will be saved to and loaded from the
|
entirely unnecessary since configuration will be saved to and loaded from the
|
||||||
profile anyway.
|
profile anyway.
|
||||||
|
|
||||||
|
### EDDI Events
|
||||||
|
|
||||||
|
The process for adding your own handlers for EDDI events has changed. You no
|
||||||
|
longer have to check which of my profiles handle them and add the commands for
|
||||||
|
those manually; instead you need to [run the `eddi.event` context of the
|
||||||
|
`alterNERDtive-base` plugin](../configuration/general#eddi-events).
|
||||||
|
|
||||||
### bindED
|
### bindED
|
||||||
|
|
||||||
If you have done anything non-standard with bindED before, it might break. The
|
If you have done anything non-standard with bindED before, it might break. The
|
||||||
|
|
|
@ -4,7 +4,7 @@ repo_url: https://github.com/alterNERDtive/VoiceAttack-profiles
|
||||||
edit_uri: "edit/devel/docs/"
|
edit_uri: "edit/devel/docs/"
|
||||||
site_description: "alterNERDtive VoiceAttack profiles for Elite: Dangerous"
|
site_description: "alterNERDtive VoiceAttack profiles for Elite: Dangerous"
|
||||||
site_author: "alterNERDtive"
|
site_author: "alterNERDtive"
|
||||||
remote_name: "ssh-origin"
|
remote_name: "origin"
|
||||||
|
|
||||||
theme:
|
theme:
|
||||||
name: readthedocs
|
name: readthedocs
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.30413.136
|
VisualStudioVersion = 17.3.32519.111
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VoiceAttack-base", "plugins\VoiceAttack-base\VoiceAttack-base.csproj", "{1C05DB3F-3449-4664-B363-A379892995E5}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VoiceAttack-base", "plugins\VoiceAttack-base\VoiceAttack-base.csproj", "{1C05DB3F-3449-4664-B363-A379892995E5}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -16,8 +16,12 @@ EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C2B4D94B-8D73-431A-880B-B1E7ADF064B2}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C2B4D94B-8D73-431A-880B-B1E7ADF064B2}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
|
CHANGELOG.md = CHANGELOG.md
|
||||||
|
.github\workflows\create-release.yaml = .github\workflows\create-release.yaml
|
||||||
|
Directory.build.props = Directory.build.props
|
||||||
mkdocs.yml = mkdocs.yml
|
mkdocs.yml = mkdocs.yml
|
||||||
README.md = README.md
|
README.md = README.md
|
||||||
|
stylecop.json = stylecop.json
|
||||||
VERSION = VERSION
|
VERSION = VERSION
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
|
|
@ -1,113 +1,175 @@
|
||||||
#nullable enable
|
// <copyright file="EliteAttack.cs" company="alterNERDtive">
|
||||||
|
// Copyright 2019–2022 alterNERDtive.
|
||||||
using alterNERDtive.util;
|
//
|
||||||
using System;
|
// This file is part of alterNERDtive VoiceAttack profiles for Elite Dangerous.
|
||||||
using System.Collections.Generic;
|
//
|
||||||
using System.Linq;
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous is free software: you can redistribute it and/or modify
|
||||||
using System.Text;
|
// it under the terms of the GNU General Public License as published by
|
||||||
using System.Threading.Tasks;
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
namespace EliteAttack
|
//
|
||||||
{
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous is distributed in the hope that it will be useful,
|
||||||
public class EliteAttack {
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
private static dynamic? VA { get; set; }
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
private static VoiceAttackLog Log
|
//
|
||||||
=> log ??= new VoiceAttackLog(VA, "EliteAttack");
|
// You should have received a copy of the GNU General Public License
|
||||||
private static VoiceAttackLog? log;
|
// along with alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// </copyright>
|
||||||
private static VoiceAttackCommands Commands
|
|
||||||
=> commands ??= new VoiceAttackCommands(VA, Log);
|
#nullable enable
|
||||||
private static VoiceAttackCommands? commands;
|
|
||||||
|
using System;
|
||||||
/*================\
|
|
||||||
| plugin contexts |
|
using alterNERDtive.util;
|
||||||
\================*/
|
|
||||||
|
namespace EliteAttack
|
||||||
private static void Context_Log(dynamic vaProxy)
|
{
|
||||||
{
|
/// <summary>
|
||||||
string message = vaProxy.GetText("~message");
|
/// VoiceAttack plugin for the EliteAttack profile.
|
||||||
string level = vaProxy.GetText("~level");
|
/// </summary>
|
||||||
|
public class EliteAttack
|
||||||
if (level == null)
|
{
|
||||||
{
|
private static readonly Version VERSION = new ("8.4");
|
||||||
Log.Log(message);
|
|
||||||
}
|
private static VoiceAttackLog? log;
|
||||||
else
|
private static VoiceAttackCommands? commands;
|
||||||
{
|
|
||||||
try
|
private static dynamic? VA { get; set; }
|
||||||
{
|
|
||||||
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
|
private static VoiceAttackLog Log => log ??= new (VA, "EliteAttack");
|
||||||
}
|
|
||||||
catch (ArgumentNullException) { throw; }
|
private static VoiceAttackCommands Commands => commands ??= new (VA, Log);
|
||||||
catch (ArgumentException)
|
|
||||||
{
|
/*========================================\
|
||||||
Log.Error($"Invalid log level '{level}'.");
|
| required VoiceAttack plugin shenanigans |
|
||||||
}
|
\========================================*/
|
||||||
}
|
|
||||||
}
|
/// <summary>
|
||||||
|
/// The plugin’s GUID, as required by the VoiceAttack plugin API.
|
||||||
private static void Context_Startup(dynamic vaProxy)
|
/// </summary>
|
||||||
{
|
/// <returns>The GUID.</returns>
|
||||||
Log.Notice("Starting up …");
|
public static Guid VA_Id()
|
||||||
VA = vaProxy;
|
=> new ("{5B46321D-2935-4550-BEEA-36C2145547B8}");
|
||||||
Log.Notice("Finished startup.");
|
|
||||||
}
|
/// <summary>
|
||||||
|
/// The plugin’s display name, as required by the VoiceAttack plugin API.
|
||||||
/*========================================\
|
/// </summary>
|
||||||
| required VoiceAttack plugin shenanigans |
|
/// <returns>The display name.</returns>
|
||||||
\========================================*/
|
public static string VA_DisplayName()
|
||||||
|
=> $"EliteAttack {VERSION}";
|
||||||
static readonly Version VERSION = new Version("8.3");
|
|
||||||
|
/// <summary>
|
||||||
public static Guid VA_Id()
|
/// The plugin’s description, as required by the VoiceAttack plugin API.
|
||||||
=> new Guid("{5B46321D-2935-4550-BEEA-36C2145547B8}");
|
/// </summary>
|
||||||
public static string VA_DisplayName()
|
/// <returns>The description.</returns>
|
||||||
=> $"EliteAttack {VERSION}";
|
public static string VA_DisplayInfo()
|
||||||
public static string VA_DisplayInfo()
|
=> "EliteAttack: a plugin for doing Elite-y things.";
|
||||||
=> "EliteAttack: a plugin for doing Elite-y things.";
|
|
||||||
|
/// <summary>
|
||||||
public static void VA_Init1(dynamic vaProxy)
|
/// The Init method, as required by the VoiceAttack plugin API.
|
||||||
{
|
/// Runs when the plugin is initially loaded.
|
||||||
VA = vaProxy;
|
/// </summary>
|
||||||
Log.Notice("Initializing …");
|
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
|
||||||
VA.SetText("EliteAttack.version", VERSION.ToString());
|
public static void VA_Init1(dynamic vaProxy)
|
||||||
Log.Notice("Init successful.");
|
{
|
||||||
}
|
VA = vaProxy;
|
||||||
|
Log.Notice("Initializing …");
|
||||||
public static void VA_Invoke1(dynamic vaProxy)
|
VA.SetText("EliteAttack.version", VERSION.ToString());
|
||||||
{
|
Log.Notice("Init successful.");
|
||||||
string context = vaProxy.Context.ToLower();
|
}
|
||||||
Log.Debug($"Running context '{context}' …");
|
|
||||||
try
|
/// <summary>
|
||||||
{
|
/// The Invoke method, as required by the VoiceAttack plugin API.
|
||||||
switch (context)
|
/// Runs whenever a plugin context is invoked.
|
||||||
{
|
/// </summary>
|
||||||
case "startup":
|
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
|
||||||
Context_Startup(vaProxy);
|
public static void VA_Invoke1(dynamic vaProxy)
|
||||||
break;
|
{
|
||||||
// log
|
VA = vaProxy;
|
||||||
case "log.log":
|
|
||||||
Context_Log(vaProxy);
|
string context = vaProxy.Context.ToLower();
|
||||||
break;
|
Log.Debug($"Running context '{context}' …");
|
||||||
// invalid
|
try
|
||||||
default:
|
{
|
||||||
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
switch (context)
|
||||||
break;
|
{
|
||||||
}
|
case "startup":
|
||||||
}
|
Context_Startup();
|
||||||
catch (ArgumentNullException e)
|
break;
|
||||||
{
|
case "log.log":
|
||||||
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
// log
|
||||||
}
|
Context_Log();
|
||||||
catch (Exception e)
|
break;
|
||||||
{
|
default:
|
||||||
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
// invalid
|
||||||
}
|
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
public static void VA_Exit1(dynamic vaProxy) { }
|
}
|
||||||
|
catch (ArgumentNullException e)
|
||||||
public static void VA_StopCommand() { }
|
{
|
||||||
}
|
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
|
||||||
|
public static void VA_Exit1(dynamic vaProxy)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public static void VA_StopCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*================\
|
||||||
|
| plugin contexts |
|
||||||
|
\================*/
|
||||||
|
|
||||||
|
private static void Context_Log()
|
||||||
|
{
|
||||||
|
string message = VA!.GetText("~message");
|
||||||
|
string level = VA!.GetText("~level");
|
||||||
|
|
||||||
|
if (level == null)
|
||||||
|
{
|
||||||
|
Log.Log(message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
|
||||||
|
}
|
||||||
|
catch (ArgumentNullException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
Log.Error($"Invalid log level '{level}'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Context_Startup()
|
||||||
|
{
|
||||||
|
Log.Notice("Starting up …");
|
||||||
|
Log.Notice("Finished startup.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
|
@ -30,7 +29,6 @@
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
@ -53,4 +51,4 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Pipes;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace RatAttack
|
|
||||||
{
|
|
||||||
class RatAttack_cli
|
|
||||||
{
|
|
||||||
static string stripIrcCodes(string message)
|
|
||||||
{
|
|
||||||
return Regex.Replace(message, @"[\x02\x11\x0F\x1D\x1E\x1F\x16]|\x03(\d\d?(,\d\d?)?)?", String.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
RatAttack.Ratsignal ratsignal = new RatAttack.Ratsignal(stripIrcCodes(args[0]), args.Length > 1 && args[1].ToLower() == "true");
|
|
||||||
|
|
||||||
using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "RatAttack", PipeDirection.Out))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// try connecting for up to 2 minutes; then we’ll assume VoiceAttack just isn’t up and won’t come up
|
|
||||||
pipeClient.Connect(120000);
|
|
||||||
using (StreamWriter writer = new StreamWriter(pipeClient))
|
|
||||||
{
|
|
||||||
writer.WriteLine(ratsignal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (TimeoutException)
|
|
||||||
{
|
|
||||||
Console.Error.WriteLine("Connection to RatAttack pipe has timed out.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,7 +25,6 @@
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
@ -35,7 +34,6 @@
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
@ -50,8 +48,8 @@
|
||||||
<Reference Include="System.Xml.Serialization" />
|
<Reference Include="System.Xml.Serialization" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="RatAttack-cli.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="RatAttack_cli.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\RatAttack\RatAttack.csproj">
|
<ProjectReference Include="..\RatAttack\RatAttack.csproj">
|
||||||
|
|
68
plugins/RatAttack-cli/RatAttack_cli.cs
Normal file
68
plugins/RatAttack-cli/RatAttack_cli.cs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// <copyright file="RatAttack_cli.cs" company="alterNERDtive">
|
||||||
|
// Copyright 2019–2022 alterNERDtive.
|
||||||
|
//
|
||||||
|
// This file is part of alterNERDtive VoiceAttack profiles for Elite Dangerous.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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 alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// </copyright>
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Pipes;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace RatAttack
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// CLI helper tool for the RatAttack VoiceAttack plugin. Accepts RATSIGNALs
|
||||||
|
/// e.g. from an IRC client and passes them to the plugin via named pipe.
|
||||||
|
/// </summary>
|
||||||
|
public class RatAttack_cli
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Main entry point.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">The command line arguments.</param>
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
RatAttack.Ratsignal ratsignal = new (StripIrcCodes(args[0]), args.Length > 1 && args[1].ToLower() == "true");
|
||||||
|
|
||||||
|
using (NamedPipeClientStream pipeClient = new (".", "RatAttack", PipeDirection.Out))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// try connecting for up to 2 minutes; then we’ll assume VoiceAttack just isn’t up and won’t come up
|
||||||
|
pipeClient.Connect(120000);
|
||||||
|
using StreamWriter writer = new (pipeClient);
|
||||||
|
writer.WriteLine(ratsignal);
|
||||||
|
}
|
||||||
|
catch (TimeoutException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Connection to RatAttack pipe has timed out.");
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Cannot connect to RatAttack pipe. Are you running VoiceAttack as Admin?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string StripIrcCodes(string message)
|
||||||
|
{
|
||||||
|
return Regex.Replace(message, @"[\x02\x11\x0F\x1D\x1E\x1F\x16]|\x03(\d\d?(,\d\d?)?)?", string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,332 +1,445 @@
|
||||||
#nullable enable
|
// <copyright file="RatAttack.cs" company="alterNERDtive">
|
||||||
|
// Copyright 2019–2022 alterNERDtive.
|
||||||
using System;
|
//
|
||||||
using System.Collections.Generic;
|
// This file is part of alterNERDtive VoiceAttack profiles for Elite Dangerous.
|
||||||
using System.Diagnostics;
|
//
|
||||||
using System.Text.RegularExpressions;
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous is free software: you can redistribute it and/or modify
|
||||||
using alterNERDtive.util;
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
namespace RatAttack
|
// (at your option) any later version.
|
||||||
{
|
//
|
||||||
public class RatAttack
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous is distributed in the hope that it will be useful,
|
||||||
{
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
private static Dictionary<int,RatCase> CaseList { get; } = new Dictionary<int, RatCase>();
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
private static dynamic? VA { get; set; }
|
// GNU General Public License for more details.
|
||||||
private static alterNERDtive.util.PipeServer<Ratsignal> RatsignalPipe
|
//
|
||||||
=> ratsignalPipe ??= new alterNERDtive.util.PipeServer<Ratsignal>(Log, "RatAttack",
|
// You should have received a copy of the GNU General Public License
|
||||||
new alterNERDtive.util.PipeServer<Ratsignal>.SignalHandler(On_Ratsignal));
|
// along with alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see <https://www.gnu.org/licenses/>.
|
||||||
private static alterNERDtive.util.PipeServer<Ratsignal>? ratsignalPipe;
|
// </copyright>
|
||||||
|
|
||||||
private static readonly Regex RatsignalRegex = new Regex(
|
#nullable enable
|
||||||
@"^RATSIGNAL Case #(?<number>\d+) (?<platform>(PC|Xbox|Playstation))(?<oxygen> \(Code Red\))?(?<odyssey> \(Odyssey\))? – CMDR (?<cmdr>.+) – System: (None|u\u200bnknown system|""(?<system>.+)"" \((?<systemInfo>([a-zA-Z0-9\s\(\)\-/]*(~?[0-9,\.]+ LY (""[a-zA-Z\-]+"" of|from) [a-zA-Z0-9\s\*\-]+)?( \([a-zA-Z\s]+\))?|Not found in galaxy database|Invalid system name))\)(?<permit> \(((?<permitName>.*) )?Permit Required\))?) – Language: (?<language>[a-zA-z0-9\x7f-\xff\-\(\)&,\s\.]+)( – Nick: (?<nick>[a-zA-Z0-9_\[\]\-]+))? \((PC|XB|PS)_SIGNAL\)\v*$"
|
|
||||||
);
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
private static VoiceAttackLog Log
|
using System.Diagnostics;
|
||||||
=> log ??= new VoiceAttackLog(VA, "RatAttack");
|
using System.Text.RegularExpressions;
|
||||||
private static VoiceAttackLog? log;
|
|
||||||
|
using alterNERDtive.util;
|
||||||
private static VoiceAttackCommands Commands
|
|
||||||
=> commands ??= new VoiceAttackCommands(VA, Log);
|
namespace RatAttack
|
||||||
private static VoiceAttackCommands? commands;
|
{
|
||||||
|
/// <summary>
|
||||||
private class RatCase
|
/// VoiceAttack plugin for the RatAttack profile.
|
||||||
{
|
/// </summary>
|
||||||
public string Cmdr;
|
public class RatAttack
|
||||||
public string? Language;
|
{
|
||||||
public string? System;
|
private static readonly Version VERSION = new ("6.3.1");
|
||||||
public string? SystemInfo;
|
|
||||||
public bool PermitLocked;
|
private static readonly Regex RatsignalRegex = new (
|
||||||
public string? PermitName;
|
@"^RATSIGNAL Case #(?<number>\d+) (?<platform>(PC|Xbox|Playstation))(?<oxygen> \(Code Red\))?(?<odyssey> \(Odyssey\))? – CMDR (?<cmdr>.+) – System: (None|u\u200bnknown system|""(?<system>.+)"" \((?<systemInfo>([a-zA-Z0-9\s\(\)\-/]*(~?[0-9,\.]+ LY (""[a-zA-Z\-]+"" of|from) [a-zA-Z0-9\s\*\-]+)?( \([a-zA-Z\s]+\))?|Not found in galaxy database|Invalid system name))\)(?<permit> \(((?<permitName>.*) )?Permit Required\))?) – Language: (?<language>[a-zA-z0-9\x7f-\xff\-\(\)&,\s\.]+)( – Nick: (?<nick>[a-zA-Z0-9_\[\]\-]+))? \((PC|XB|PS)_SIGNAL\)\v*$");
|
||||||
public string Platform;
|
|
||||||
public bool Odyssey;
|
private static PipeServer<Ratsignal>? ratsignalPipe;
|
||||||
public bool CodeRed;
|
private static VoiceAttackLog? log;
|
||||||
public int Number;
|
private static VoiceAttackCommands? commands;
|
||||||
|
|
||||||
public RatCase(string cmdr, string? language, string? system, string? systemInfo, bool permitLocked, string? permitName, string platform, bool odyssey, bool codeRed, int number)
|
private static Dictionary<int, RatCase> CaseList { get; } = new ();
|
||||||
=> (Cmdr, Language, System, SystemInfo, PermitLocked, PermitName, Platform, Odyssey, CodeRed, Number) = (cmdr, language, system, systemInfo, permitLocked, permitName, platform, odyssey, codeRed, number);
|
|
||||||
|
private static dynamic? VA { get; set; }
|
||||||
public string ShortInfo
|
|
||||||
{
|
private static PipeServer<Ratsignal> RatsignalPipe
|
||||||
get => $"#{Number}, {Platform}{(Odyssey ? " (Odyssey)" : "")}{(CodeRed ? ", code red" : "")}, {System ?? "None"}{(SystemInfo != null ? $" ({SystemInfo}{(PermitLocked ? ", permit required" : "")})" : "")}";
|
=> ratsignalPipe ??= new (
|
||||||
}
|
Log,
|
||||||
|
"RatAttack",
|
||||||
public override string ToString()
|
new PipeServer<Ratsignal>.SignalHandler(On_Ratsignal));
|
||||||
=> ShortInfo;
|
|
||||||
}
|
private static VoiceAttackLog Log => log ??= new (VA, "RatAttack");
|
||||||
|
|
||||||
public class Ratsignal : IPipable
|
private static VoiceAttackCommands Commands => commands ??= new (VA, Log);
|
||||||
{
|
|
||||||
public string Signal { get; set; }
|
/*========================================\
|
||||||
public bool Announce { get; set; }
|
| required VoiceAttack plugin shenanigans |
|
||||||
private readonly char separator = '\x1F';
|
\========================================*/
|
||||||
|
|
||||||
public Ratsignal()
|
/// <summary>
|
||||||
=> (Signal, Announce) = ("", false);
|
/// The plugin’s GUID, as required by the VoiceAttack plugin API.
|
||||||
|
/// </summary>
|
||||||
public Ratsignal(string signal, bool announce)
|
/// <returns>The GUID.</returns>
|
||||||
=> (Signal, Announce) = (signal, announce);
|
public static Guid VA_Id()
|
||||||
|
=> new ("{F2ADF0AE-4837-4E4A-9C87-8A7E2FA63E5F}");
|
||||||
public void ParseString(string serialization)
|
|
||||||
{
|
/// <summary>
|
||||||
try
|
/// The plugin’s display name, as required by the VoiceAttack plugin API.
|
||||||
{
|
/// </summary>
|
||||||
string[] parts = serialization.Split(separator);
|
/// <returns>The display name.</returns>
|
||||||
Signal = parts[0];
|
public static string VA_DisplayName()
|
||||||
Announce = Boolean.Parse(parts[1]);
|
=> $"RatAttack {VERSION}";
|
||||||
}
|
|
||||||
catch (Exception e)
|
/// <summary>
|
||||||
{
|
/// The plugin’s description, as required by the VoiceAttack plugin API.
|
||||||
throw new ArgumentException($"Invalid serialized RATSIGNAL: '{serialization}'", e);
|
/// </summary>
|
||||||
}
|
/// <returns>The description.</returns>
|
||||||
}
|
public static string VA_DisplayInfo()
|
||||||
|
=> "RatAttack: a plugin to handle FuelRats cases.";
|
||||||
public override string ToString()
|
|
||||||
=> $"{Signal}{separator}{Announce}";
|
/// <summary>
|
||||||
}
|
/// The Init method, as required by the VoiceAttack plugin API.
|
||||||
|
/// Runs when the plugin is initially loaded.
|
||||||
private static int ParseRatsignal(string ratsignal)
|
/// </summary>
|
||||||
{
|
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
|
||||||
if (!RatsignalRegex.IsMatch(ratsignal))
|
public static void VA_Init1(dynamic vaProxy)
|
||||||
throw new ArgumentException($"Invalid RATSIGNAL format: '{ratsignal}'.", "ratsignal");
|
{
|
||||||
|
VA = vaProxy;
|
||||||
Match match = RatsignalRegex.Match(ratsignal);
|
Log.Notice("Initializing …");
|
||||||
|
VA.SetText("RatAttack.version", VERSION.ToString());
|
||||||
string cmdr = match.Groups["cmdr"].Value;
|
vaProxy.ProfileChanged += new Action<Guid?, Guid?, string, string>(On_ProfileChanged);
|
||||||
string? language = match.Groups["language"].Value;
|
Log.Notice("Init successful.");
|
||||||
string? system = match.Groups["system"].Value;
|
}
|
||||||
string? systemInfo = match.Groups["systemInfo"].Value;
|
|
||||||
bool permitLocked = match.Groups["permit"].Success;
|
/// <summary>
|
||||||
string? permitName = match.Groups["permitName"].Value;
|
/// The Invoke method, as required by the VoiceAttack plugin API.
|
||||||
string platform = match.Groups["platform"].Value;
|
/// Runs whenever a plugin context is invoked.
|
||||||
bool codeRed = match.Groups["oxygen"].Success;
|
/// </summary>
|
||||||
bool odyssey = match.Groups["odyssey"].Success;
|
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
|
||||||
|
public static void VA_Invoke1(dynamic vaProxy)
|
||||||
int number = int.Parse(match.Groups["number"].Value);
|
{
|
||||||
|
VA = vaProxy;
|
||||||
if (String.IsNullOrEmpty(system))
|
|
||||||
{
|
string context = vaProxy.Context.ToLower();
|
||||||
system = "None";
|
Log.Debug($"Running context '{context}' …");
|
||||||
}
|
try
|
||||||
|
{
|
||||||
Log.Debug($"New rat case: CMDR “{cmdr}” in “{system}”{(systemInfo != null ? $" ({systemInfo})" : "")} on {platform}{(odyssey ? " (Odyssey)" : "")}, permit locked: {permitLocked}{(permitLocked && permitName != null ? $" (permit name: {permitName})" : "")}, code red: {codeRed} (#{number}).");
|
switch (context)
|
||||||
|
{
|
||||||
CaseList[number] = new RatCase(cmdr, language, system, systemInfo, permitLocked, permitName, platform, odyssey, codeRed, number);
|
case "getcasedata":
|
||||||
|
// plugin methods
|
||||||
return number;
|
Context_GetCaseData();
|
||||||
}
|
break;
|
||||||
|
case "parseratsignal":
|
||||||
private static void On_Ratsignal(Ratsignal ratsignal)
|
Context_ParseRatsignal();
|
||||||
{
|
break;
|
||||||
try
|
case "startup":
|
||||||
{
|
Context_Startup();
|
||||||
int number = ParseRatsignal(ratsignal.Signal);
|
break;
|
||||||
Log.Notice($"New rat case: {CaseList[number]}.");
|
case "edsm.getnearestcmdr":
|
||||||
Commands.TriggerEvent("RatAttack.incomingCase", parameters: new dynamic[] { new int[] { number }, new bool[] { ratsignal.Announce } });
|
// EDSM
|
||||||
}
|
Context_EDSM_GetNearestCMDR();
|
||||||
catch (ArgumentException e)
|
break;
|
||||||
{
|
case "log.log":
|
||||||
Log.Error(e.Message);
|
// log
|
||||||
Commands.TriggerEvent("RatAttack.invalidRatsignal", parameters: new dynamic[] { new string[] { ratsignal.Signal } });
|
Context_Log();
|
||||||
}
|
break;
|
||||||
catch (Exception e)
|
default:
|
||||||
{
|
// invalid
|
||||||
Log.Error($"Unhandled exception while parsing RATSIGNAL: '{e.Message}'.");
|
Log.Error($"Invalid plugin context '{VA!.Context}'.");
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private static void On_ProfileChanged(Guid? from, Guid? to, string fromName, string toName)
|
catch (ArgumentNullException e)
|
||||||
=> VA_Exit1(VA);
|
{
|
||||||
|
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
||||||
/*================\
|
}
|
||||||
| plugin contexts |
|
catch (Exception e)
|
||||||
\================*/
|
{
|
||||||
|
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
||||||
private static void Context_EDSM_GetNearestCMDR(dynamic vaProxy)
|
}
|
||||||
{
|
}
|
||||||
int caseNo = vaProxy.GetInt("~caseNo") ?? throw new ArgumentNullException("~caseNo");
|
|
||||||
string cmdrList = vaProxy.GetText("~cmdrs") ?? throw new ArgumentNullException("~cmdrs");
|
/// <summary>
|
||||||
string[] cmdrs = cmdrList.Split(';');
|
/// The Exit method, as required by the VoiceAttack plugin API.
|
||||||
if (cmdrs.Length == 0)
|
/// Runs when VoiceAttack is shut down.
|
||||||
{
|
/// </summary>
|
||||||
throw new ArgumentNullException("~cmdrs");
|
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
|
||||||
}
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
|
||||||
string system = CaseList[caseNo]?.System ?? throw new ArgumentException($"Case #{caseNo} has no system information", "~caseNo");
|
public static void VA_Exit1(dynamic vaProxy)
|
||||||
|
{
|
||||||
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\edsm-getnearest.exe";
|
Log.Debug("Starting teardown …");
|
||||||
string arguments = $@"--short --text --system ""{system}"" ""{string.Join(@""" """, cmdrs)}""";
|
Log.Debug("Closing RATSIGNAL pipe …");
|
||||||
|
RatsignalPipe.Stop();
|
||||||
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
Log.Debug("Teardown finished.");
|
||||||
|
}
|
||||||
p.Start();
|
|
||||||
string stdout = p.StandardOutput.ReadToEnd();
|
/// <summary>
|
||||||
string stderr = p.StandardError.ReadToEnd();
|
/// The StopCommand method, as required by the VoiceAttack plugin API.
|
||||||
p.WaitForExit();
|
/// Runs whenever all commands are stopped using the “Stop All Commands”
|
||||||
|
/// button or action.
|
||||||
string message = stdout;
|
/// </summary>
|
||||||
string? errorMessage = null;
|
public static void VA_StopCommand()
|
||||||
bool error = true;
|
{
|
||||||
|
}
|
||||||
switch (p.ExitCode)
|
|
||||||
{
|
/// <summary>
|
||||||
case 0:
|
/// Parses a RATSIGNAL and extracts case data for storage.
|
||||||
error = false;
|
/// </summary>
|
||||||
Log.Info(message);
|
/// <param name="ratsignal">The incoming RATSIGNAL.</param>
|
||||||
break;
|
/// <returns>The case number.</returns>
|
||||||
case 1: // CMDR not found, Server Error, Api Exception (jeez, what a mess did I make there?)
|
/// <exception cref="ArgumentException">Thrown on invalid RATSIGNAL.</exception>
|
||||||
error = true;
|
private static int ParseRatsignal(string ratsignal)
|
||||||
Log.Error(message);
|
{
|
||||||
break;
|
if (!RatsignalRegex.IsMatch(ratsignal))
|
||||||
case 2: // System not found
|
{
|
||||||
error = true;
|
throw new ArgumentException($"Invalid RATSIGNAL format: '{ratsignal}'.", "ratsignal");
|
||||||
Log.Warn(message);
|
}
|
||||||
break;
|
|
||||||
default:
|
Match match = RatsignalRegex.Match(ratsignal);
|
||||||
error = true;
|
|
||||||
Log.Error(stderr);
|
string cmdr = match.Groups["cmdr"].Value;
|
||||||
errorMessage = "Unrecoverable error in plugin.";
|
string? language = match.Groups["language"].Value;
|
||||||
break;
|
string? system = match.Groups["system"].Value;
|
||||||
|
string? systemInfo = match.Groups["systemInfo"].Value;
|
||||||
}
|
bool permitLocked = match.Groups["permit"].Success;
|
||||||
|
string? permitName = match.Groups["permitName"].Value;
|
||||||
vaProxy.SetText("~message", message);
|
string platform = match.Groups["platform"].Value;
|
||||||
vaProxy.SetBoolean("~error", error);
|
bool codeRed = match.Groups["oxygen"].Success;
|
||||||
vaProxy.SetText("~errorMessage", errorMessage);
|
bool odyssey = match.Groups["odyssey"].Success;
|
||||||
vaProxy.SetInt("~exitCode", p.ExitCode);
|
|
||||||
}
|
int number = int.Parse(match.Groups["number"].Value);
|
||||||
|
|
||||||
private static void Context_GetCaseData(dynamic vaProxy)
|
if (string.IsNullOrEmpty(system))
|
||||||
{
|
{
|
||||||
int cn = vaProxy.GetInt("~caseNumber");
|
system = "None";
|
||||||
|
}
|
||||||
if (CaseList.ContainsKey(cn))
|
|
||||||
{
|
Log.Debug($"New rat case: CMDR “{cmdr}” in “{system}”{(systemInfo != null ? $" ({systemInfo})" : string.Empty)} on {platform}{(odyssey ? " (Odyssey)" : string.Empty)}, permit locked: {permitLocked}{(permitLocked && permitName != null ? $" (permit name: {permitName})" : string.Empty)}, code red: {codeRed} (#{number}).");
|
||||||
RatCase rc = CaseList[cn];
|
|
||||||
|
CaseList[number] = new RatCase(cmdr, language, system, systemInfo, permitLocked, permitName, platform, odyssey, codeRed, number);
|
||||||
vaProxy.SetInt("~~caseNumber", rc.Number);
|
|
||||||
vaProxy.SetText("~~cmdr", rc.Cmdr);
|
return number;
|
||||||
vaProxy.SetText("~~system", rc?.System?.ToLower());
|
}
|
||||||
vaProxy.SetText("~~systemInfo", rc?.SystemInfo);
|
|
||||||
vaProxy.SetBoolean("~~permitLocked", rc?.PermitLocked);
|
private static void On_Ratsignal(Ratsignal ratsignal)
|
||||||
vaProxy.SetText("~~permitName", rc?.PermitName);
|
{
|
||||||
vaProxy.SetText("~~platform", rc?.Platform);
|
try
|
||||||
vaProxy.SetBoolean("~~odyssey", rc?.Odyssey);
|
{
|
||||||
vaProxy.SetBoolean("~~codeRed", rc?.CodeRed);
|
int number = ParseRatsignal(ratsignal.Signal);
|
||||||
}
|
Log.Notice($"New rat case: {CaseList[number]}.");
|
||||||
else
|
Commands.TriggerEvent("RatAttack.incomingCase", parameters: new dynamic[] { new int[] { number }, new bool[] { ratsignal.Announce } });
|
||||||
{
|
}
|
||||||
Log.Warn($"Case #{cn} not found in the case list");
|
catch (ArgumentException e)
|
||||||
}
|
{
|
||||||
}
|
Log.Error(e.Message);
|
||||||
|
Commands.TriggerEvent("RatAttack.invalidRatsignal", parameters: new dynamic[] { new string[] { ratsignal.Signal } });
|
||||||
private static void Context_Log(dynamic vaProxy)
|
}
|
||||||
{
|
catch (Exception e)
|
||||||
string message = vaProxy.GetText("~message");
|
{
|
||||||
string level = vaProxy.GetText("~level");
|
Log.Error($"Unhandled exception while parsing RATSIGNAL: '{e.Message}'.");
|
||||||
|
}
|
||||||
if (level == null)
|
}
|
||||||
{
|
|
||||||
Log.Log(message);
|
private static void On_ProfileChanged(Guid? from, Guid? to, string fromName, string toName)
|
||||||
}
|
=> VA_Exit1(VA);
|
||||||
else
|
|
||||||
{
|
/*================\
|
||||||
try
|
| plugin contexts |
|
||||||
{
|
\================*/
|
||||||
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
|
|
||||||
}
|
private static void Context_EDSM_GetNearestCMDR()
|
||||||
catch (ArgumentNullException) { throw; }
|
{
|
||||||
catch (ArgumentException)
|
int caseNo = VA!.GetInt("~caseNo") ?? throw new ArgumentNullException("~caseNo");
|
||||||
{
|
string cmdrList = VA!.GetText("~cmdrs") ?? throw new ArgumentNullException("~cmdrs");
|
||||||
Log.Error($"Invalid log level '{level}'.");
|
string[] cmdrs = cmdrList.Split(';');
|
||||||
}
|
if (cmdrs.Length == 0)
|
||||||
}
|
{
|
||||||
}
|
throw new ArgumentNullException("~cmdrs");
|
||||||
|
}
|
||||||
private static void Context_Startup(dynamic vaProxy)
|
|
||||||
{
|
string system = CaseList[caseNo]?.System ?? throw new ArgumentException($"Case #{caseNo} has no system information", "~caseNo");
|
||||||
Log.Notice("Starting up …");
|
|
||||||
VA = vaProxy;
|
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\edsm-getnearest.exe";
|
||||||
_ = RatsignalPipe.Run();
|
string arguments = $@"--short --text --system ""{system}"" ""{string.Join(@""" """, cmdrs)}""";
|
||||||
Log.Notice("Finished startup.");
|
|
||||||
}
|
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
||||||
|
|
||||||
private static void Context_ParseRatsignal(dynamic vaProxy)
|
p.Start();
|
||||||
{
|
string stdout = p.StandardOutput.ReadToEnd();
|
||||||
Log.Warn("Passing a RATSIGNAL from VoiceAttack (through the clipboard or a file) is DEPRECATED and will no longer be supported in the future.");
|
string stderr = p.StandardError.ReadToEnd();
|
||||||
On_Ratsignal(new Ratsignal(vaProxy.GetText("~ratsignal"), vaProxy.GetBoolean("~announceRatsignal")));
|
p.WaitForExit();
|
||||||
}
|
|
||||||
|
string message = stdout;
|
||||||
/*========================================\
|
string? errorMessage = null;
|
||||||
| required VoiceAttack plugin shenanigans |
|
bool error;
|
||||||
\========================================*/
|
|
||||||
|
switch (p.ExitCode)
|
||||||
static readonly Version VERSION = new Version("6.3");
|
{
|
||||||
|
case 0:
|
||||||
public static Guid VA_Id()
|
error = false;
|
||||||
=> new Guid("{F2ADF0AE-4837-4E4A-9C87-8A7E2FA63E5F}");
|
Log.Info(message);
|
||||||
public static string VA_DisplayName()
|
break;
|
||||||
=> $"RatAttack {VERSION}";
|
case 1: // CMDR not found, Server Error, Api Exception (jeez, what a mess did I make there?)
|
||||||
public static string VA_DisplayInfo()
|
error = true;
|
||||||
=> "RatAttack: a plugin to handle FuelRats cases.";
|
Log.Error(message);
|
||||||
|
break;
|
||||||
public static void VA_Init1(dynamic vaProxy)
|
case 2: // System not found
|
||||||
{
|
error = true;
|
||||||
VA = vaProxy;
|
Log.Warn(message);
|
||||||
Log.Notice("Initializing …");
|
break;
|
||||||
VA.SetText("RatAttack.version", VERSION.ToString());
|
default:
|
||||||
vaProxy.ProfileChanged += new Action<Guid?, Guid?, String, String>(On_ProfileChanged);
|
error = true;
|
||||||
Log.Notice("Init successful.");
|
Log.Error(stderr);
|
||||||
}
|
errorMessage = "Unrecoverable error in plugin.";
|
||||||
|
break;
|
||||||
public static void VA_Invoke1(dynamic vaProxy)
|
}
|
||||||
{
|
|
||||||
string context = vaProxy.Context.ToLower();
|
VA!.SetText("~message", message);
|
||||||
Log.Debug($"Running context '{context}' …");
|
VA!.SetBoolean("~error", error);
|
||||||
try
|
VA!.SetText("~errorMessage", errorMessage);
|
||||||
{
|
VA!.SetInt("~exitCode", p.ExitCode);
|
||||||
switch (context)
|
}
|
||||||
{
|
|
||||||
// plugin methods
|
private static void Context_GetCaseData()
|
||||||
case "getcasedata":
|
{
|
||||||
Context_GetCaseData(vaProxy);
|
int cn = VA!.GetInt("~caseNumber");
|
||||||
break;
|
|
||||||
case "parseratsignal":
|
if (CaseList.ContainsKey(cn))
|
||||||
Context_ParseRatsignal(vaProxy);
|
{
|
||||||
break;
|
RatCase rc = CaseList[cn];
|
||||||
case "startup":
|
|
||||||
Context_Startup(vaProxy);
|
VA!.SetInt("~~caseNumber", rc.Number);
|
||||||
break;
|
VA!.SetText("~~cmdr", rc.Cmdr);
|
||||||
// EDSM
|
VA!.SetText("~~system", rc?.System?.ToLower());
|
||||||
case "edsm.getnearestcmdr":
|
VA!.SetText("~~systemInfo", rc?.SystemInfo);
|
||||||
Context_EDSM_GetNearestCMDR(vaProxy);
|
VA!.SetBoolean("~~permitLocked", rc?.PermitLocked);
|
||||||
break;
|
VA!.SetText("~~permitName", rc?.PermitName);
|
||||||
// log
|
VA!.SetText("~~platform", rc?.Platform);
|
||||||
case "log.log":
|
VA!.SetBoolean("~~odyssey", rc?.Odyssey);
|
||||||
Context_Log(vaProxy);
|
VA!.SetBoolean("~~codeRed", rc?.CodeRed);
|
||||||
break;
|
}
|
||||||
// invalid
|
else
|
||||||
default:
|
{
|
||||||
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
Log.Warn($"Case #{cn} not found in the case list");
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (ArgumentNullException e)
|
private static void Context_Log()
|
||||||
{
|
{
|
||||||
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
string message = VA!.GetText("~message");
|
||||||
}
|
string level = VA!.GetText("~level");
|
||||||
catch (Exception e)
|
|
||||||
{
|
if (level == null)
|
||||||
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
{
|
||||||
}
|
Log.Log(message);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public static void VA_Exit1(dynamic vaProxy)
|
{
|
||||||
{
|
try
|
||||||
Log.Debug("Starting teardown …");
|
{
|
||||||
Log.Debug("Closing RATSIGNAL pipe …");
|
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
|
||||||
RatsignalPipe.Stop();
|
}
|
||||||
Log.Debug("Teardown finished.");
|
catch (ArgumentNullException)
|
||||||
}
|
{
|
||||||
|
throw;
|
||||||
public static void VA_StopCommand() { }
|
}
|
||||||
}
|
catch (ArgumentException)
|
||||||
}
|
{
|
||||||
|
Log.Error($"Invalid log level '{level}'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Context_Startup()
|
||||||
|
{
|
||||||
|
Log.Notice("Starting up …");
|
||||||
|
_ = RatsignalPipe.Run();
|
||||||
|
Log.Notice("Finished startup.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Context_ParseRatsignal()
|
||||||
|
{
|
||||||
|
Log.Warn("Passing a RATSIGNAL to VoiceAttack through the clipboard or a file is DEPRECATED and will no longer be supported in the future.");
|
||||||
|
On_Ratsignal(new Ratsignal(VA!.GetText("~ratsignal"), VA!.GetBoolean("~announceRatsignal")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encapsulates a RATSIGNAL for sending between the CLI helper tool and
|
||||||
|
/// the plugin via named pipe.
|
||||||
|
/// </summary>
|
||||||
|
public class Ratsignal : IPipable
|
||||||
|
{
|
||||||
|
private readonly char separator = '\x1F';
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Ratsignal"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public Ratsignal()
|
||||||
|
=> (this.Signal, this.Announce) = (string.Empty, false);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Ratsignal"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="signal">The RATSIGNAL.</param>
|
||||||
|
/// <param name="announce">Whether or not to announce the new case.</param>
|
||||||
|
public Ratsignal(string signal, bool announce)
|
||||||
|
=> (this.Signal, this.Announce) = (signal, announce);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the RATSIGNAL.
|
||||||
|
/// </summary>
|
||||||
|
public string Signal { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets a value indicating whether to announce the incoming
|
||||||
|
/// case.
|
||||||
|
/// </summary>
|
||||||
|
public bool Announce { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the <see cref="Ratsignal"/> instance from a
|
||||||
|
/// serialized representation.
|
||||||
|
/// FIXXME: should probably make this a static factory method.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="serialization">The serialized <see cref="Ratsignal"/>.</param>
|
||||||
|
/// <exception cref="ArgumentException">Thrown on receiving an invalid signal.</exception>
|
||||||
|
public void ParseString(string serialization)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] parts = serialization.Split(this.separator);
|
||||||
|
this.Signal = parts[0];
|
||||||
|
this.Announce = bool.Parse(parts[1]);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Invalid serialized RATSIGNAL: '{serialization}'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override string ToString()
|
||||||
|
=> $"{this.Signal}{this.separator}{this.Announce}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RatCase
|
||||||
|
{
|
||||||
|
public RatCase(string cmdr, string? language, string? system, string? systemInfo, bool permitLocked, string? permitName, string platform, bool odyssey, bool codeRed, int number)
|
||||||
|
=> (this.Cmdr, this.Language, this.System, this.SystemInfo, this.PermitLocked, this.PermitName, this.Platform, this.Odyssey, this.CodeRed, this.Number)
|
||||||
|
= (cmdr, language, system, systemInfo, permitLocked, permitName, platform, odyssey, codeRed, number);
|
||||||
|
|
||||||
|
public string Cmdr { get; }
|
||||||
|
|
||||||
|
public string? Language { get; }
|
||||||
|
|
||||||
|
public string? System { get; }
|
||||||
|
|
||||||
|
public string? SystemInfo { get; }
|
||||||
|
|
||||||
|
public bool PermitLocked { get; }
|
||||||
|
|
||||||
|
public string? PermitName { get; }
|
||||||
|
|
||||||
|
public string Platform { get; }
|
||||||
|
|
||||||
|
public bool Odyssey { get; }
|
||||||
|
|
||||||
|
public bool CodeRed { get; }
|
||||||
|
|
||||||
|
public int Number { get; }
|
||||||
|
|
||||||
|
public string ShortInfo
|
||||||
|
{
|
||||||
|
get => $"#{this.Number}, {this.Platform}{(this.Odyssey ? " (Odyssey)" : string.Empty)}{(this.CodeRed ? ", code red" : string.Empty)}, {this.System ?? "None"}{(this.SystemInfo != null ? $" ({this.SystemInfo}{(this.PermitLocked ? ", permit required" : string.Empty)})" : string.Empty)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
=> this.ShortInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
|
@ -34,7 +33,6 @@
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
@ -59,4 +57,4 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,32 +1,162 @@
|
||||||
#nullable enable
|
// <copyright file="SpanshAttack.cs" company="alterNERDtive">
|
||||||
|
// Copyright 2019–2022 alterNERDtive.
|
||||||
|
//
|
||||||
|
// This file is part of alterNERDtive VoiceAttack profiles for Elite Dangerous.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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 alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// </copyright>
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
using alterNERDtive.util;
|
|
||||||
using alterNERDtive.edts;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using alterNERDtive.edts;
|
||||||
|
using alterNERDtive.util;
|
||||||
|
|
||||||
namespace SpanshAttack
|
namespace SpanshAttack
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// VoiceAttack plugin for the SpanshAttack profile.
|
||||||
|
/// </summary>
|
||||||
public class SpanshAttack
|
public class SpanshAttack
|
||||||
{
|
{
|
||||||
|
private static readonly Version VERSION = new ("7.2.2");
|
||||||
|
|
||||||
|
private static VoiceAttackLog? log;
|
||||||
|
private static VoiceAttackCommands? commands;
|
||||||
|
|
||||||
private static dynamic? VA { get; set; }
|
private static dynamic? VA { get; set; }
|
||||||
|
|
||||||
private static VoiceAttackLog Log
|
private static VoiceAttackLog Log => log ??= new (VA, "SpanshAttack");
|
||||||
=> log ??= new VoiceAttackLog(VA, "SpanshAttack");
|
|
||||||
private static VoiceAttackLog? log;
|
|
||||||
|
|
||||||
private static VoiceAttackCommands Commands
|
private static VoiceAttackCommands Commands => commands ??= new (VA, Log);
|
||||||
=> commands ??= new VoiceAttackCommands(VA, Log);
|
|
||||||
private static VoiceAttackCommands? commands;
|
/*========================================\
|
||||||
|
| required VoiceAttack plugin shenanigans |
|
||||||
|
\========================================*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The plugin’s GUID, as required by the VoiceAttack plugin API.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The GUID.</returns>
|
||||||
|
public static Guid VA_Id()
|
||||||
|
=> new ("{e722b29d-898e-47dd-a843-a409c87e0bd8}");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The plugin’s display name, as required by the VoiceAttack plugin API.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The display name.</returns>
|
||||||
|
public static string VA_DisplayName()
|
||||||
|
=> $"SpanshAttack {VERSION}";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The plugin’s description, as required by the VoiceAttack plugin API.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The description.</returns>
|
||||||
|
public static string VA_DisplayInfo()
|
||||||
|
=> "SpanshAttack: a plugin for doing routing with spansh.co.uk for Elite: Dangerous.";
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public static void VA_Init1(dynamic vaProxy)
|
||||||
|
{
|
||||||
|
VA = vaProxy;
|
||||||
|
Log.Notice("Initializing …");
|
||||||
|
VA.SetText("SpanshAttack.version", VERSION.ToString());
|
||||||
|
Log.Notice("Init successful.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public static void VA_Invoke1(dynamic vaProxy)
|
||||||
|
{
|
||||||
|
VA = vaProxy;
|
||||||
|
|
||||||
|
string context = vaProxy.Context.ToLower();
|
||||||
|
Log.Debug($"Running context '{context}' …");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (context)
|
||||||
|
{
|
||||||
|
case "startup":
|
||||||
|
Context_Startup();
|
||||||
|
break;
|
||||||
|
case "edts.getcoordinates":
|
||||||
|
// EDTS
|
||||||
|
Context_EDTS_GetCoordinates();
|
||||||
|
break;
|
||||||
|
case "log.log":
|
||||||
|
// log
|
||||||
|
Context_Log();
|
||||||
|
break;
|
||||||
|
case "spansh.systemexists":
|
||||||
|
// Spansh
|
||||||
|
Context_Spansh_SytemExists();
|
||||||
|
break;
|
||||||
|
case "spansh.nearestsystem":
|
||||||
|
Context_Spansh_Nearestsystem();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// invalid
|
||||||
|
Log.Error($"Invalid plugin context '{VA!.Context}'.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ArgumentNullException e)
|
||||||
|
{
|
||||||
|
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
|
||||||
|
public static void VA_Exit1(dynamic vaProxy)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public static void VA_StopCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*================\
|
/*================\
|
||||||
| plugin contexts |
|
| plugin contexts |
|
||||||
\================*/
|
\================*/
|
||||||
|
|
||||||
private static void Context_EDTS_GetCoordinates(dynamic vaProxy)
|
private static void Context_EDTS_GetCoordinates()
|
||||||
{
|
{
|
||||||
string name = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
|
string name = VA!.GetText("~system") ?? throw new ArgumentNullException("~system");
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
string? errorType = null;
|
string? errorType = null;
|
||||||
|
@ -45,35 +175,37 @@ namespace SpanshAttack
|
||||||
Log.Warn($@"Coordinates with low precision for ""{name}"": ({system.Coords.X}, {system.Coords.Y}, {system.Coords.Z}), precision: {system.Coords.Precision} ly");
|
Log.Warn($@"Coordinates with low precision for ""{name}"": ({system.Coords.X}, {system.Coords.Y}, {system.Coords.Z}), precision: {system.Coords.Precision} ly");
|
||||||
}
|
}
|
||||||
|
|
||||||
vaProxy.SetInt("~x", system.Coords.X);
|
VA!.SetInt("~x", system.Coords.X);
|
||||||
vaProxy.SetInt("~y", system.Coords.Y);
|
VA!.SetInt("~y", system.Coords.Y);
|
||||||
vaProxy.SetInt("~z", system.Coords.Z);
|
VA!.SetInt("~z", system.Coords.Z);
|
||||||
vaProxy.SetInt("~precision", system.Coords.Precision);
|
VA!.SetInt("~precision", system.Coords.Precision);
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
} catch (ArgumentException e)
|
}
|
||||||
|
catch (ArgumentException e)
|
||||||
{
|
{
|
||||||
errorType = "invalid name";
|
errorType = "invalid name";
|
||||||
errorMessage = e.Message;
|
errorMessage = e.Message;
|
||||||
} catch (Exception e)
|
}
|
||||||
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
errorType = "connection error";
|
errorType = "connection error";
|
||||||
errorMessage = e.Message;
|
errorMessage = e.Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
vaProxy.SetBoolean("~success", success);
|
VA!.SetBoolean("~success", success);
|
||||||
if (!string.IsNullOrWhiteSpace(errorType))
|
if (!string.IsNullOrWhiteSpace(errorType))
|
||||||
{
|
{
|
||||||
Log.Error(errorMessage!);
|
Log.Error(errorMessage!);
|
||||||
vaProxy.SetText("~errorType", errorType);
|
VA!.SetText("~errorType", errorType);
|
||||||
vaProxy.SetText("~errorMessage", errorMessage);
|
VA!.SetText("~errorMessage", errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Log(dynamic vaProxy)
|
private static void Context_Log()
|
||||||
{
|
{
|
||||||
string message = vaProxy.GetText("~message");
|
string message = VA!.GetText("~message");
|
||||||
string level = vaProxy.GetText("~level");
|
string level = VA!.GetText("~level");
|
||||||
|
|
||||||
if (level == null)
|
if (level == null)
|
||||||
{
|
{
|
||||||
|
@ -85,7 +217,10 @@ namespace SpanshAttack
|
||||||
{
|
{
|
||||||
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
|
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
|
||||||
}
|
}
|
||||||
catch (ArgumentNullException) { throw; }
|
catch (ArgumentNullException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
Log.Error($"Invalid log level '{level}'.");
|
Log.Error($"Invalid log level '{level}'.");
|
||||||
|
@ -93,22 +228,22 @@ namespace SpanshAttack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Spansh_Nearestsystem(dynamic vaProxy)
|
private static void Context_Spansh_Nearestsystem()
|
||||||
{
|
{
|
||||||
int x = vaProxy.GetInt("~x") ?? throw new ArgumentNullException("~x");
|
int x = VA!.GetInt("~x") ?? throw new ArgumentNullException("~x");
|
||||||
int y = vaProxy.GetInt("~y") ?? throw new ArgumentNullException("~y");
|
int y = VA!.GetInt("~y") ?? throw new ArgumentNullException("~y");
|
||||||
int z = vaProxy.GetInt("~z") ?? throw new ArgumentNullException("~z");
|
int z = VA!.GetInt("~z") ?? throw new ArgumentNullException("~z");
|
||||||
|
|
||||||
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
|
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
|
||||||
string arguments = $@"nearestsystem --parsable {x} {y} {z}";
|
string arguments = $@"nearestsystem --parsable {x} {y} {z}";
|
||||||
|
|
||||||
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
||||||
|
|
||||||
Dictionary<char, decimal> coords = new Dictionary<char, decimal> { { 'x', 0 }, { 'y', 0 }, { 'z', 0 } };
|
Dictionary<char, decimal> coords = new () { { 'x', 0 }, { 'y', 0 }, { 'z', 0 } };
|
||||||
string system = "";
|
string system = string.Empty;
|
||||||
decimal distance = 0;
|
decimal distance = 0;
|
||||||
bool error = false;
|
bool error = false;
|
||||||
string errorMessage = "";
|
string errorMessage = string.Empty;
|
||||||
|
|
||||||
p.Start();
|
p.Start();
|
||||||
string stdout = p.StandardOutput.ReadToEnd();
|
string stdout = p.StandardOutput.ReadToEnd();
|
||||||
|
@ -138,28 +273,28 @@ namespace SpanshAttack
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vaProxy.SetText("~system", system);
|
VA!.SetText("~system", system);
|
||||||
vaProxy.SetDecimal("~x", coords['x']);
|
VA!.SetDecimal("~x", coords['x']);
|
||||||
vaProxy.SetDecimal("~y", coords['y']);
|
VA!.SetDecimal("~y", coords['y']);
|
||||||
vaProxy.SetDecimal("~z", coords['z']);
|
VA!.SetDecimal("~z", coords['z']);
|
||||||
vaProxy.SetDecimal("~distance", distance);
|
VA!.SetDecimal("~distance", distance);
|
||||||
vaProxy.SetBoolean("~error", error);
|
VA!.SetBoolean("~error", error);
|
||||||
vaProxy.SetText("~errorMessage", errorMessage);
|
VA!.SetText("~errorMessage", errorMessage);
|
||||||
vaProxy.SetInt("~exitCode", p.ExitCode);
|
VA!.SetInt("~exitCode", p.ExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Spansh_SytemExists(dynamic vaProxy)
|
private static void Context_Spansh_SytemExists()
|
||||||
{
|
{
|
||||||
string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
|
string system = VA!.GetText("~system") ?? throw new ArgumentNullException("~system");
|
||||||
|
|
||||||
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
|
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
|
||||||
string arguments = $@"systemexists ""{system}""";
|
string arguments = $@"systemexists ""{system}""";
|
||||||
|
|
||||||
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
||||||
|
|
||||||
bool exists = true;
|
bool exists = true;
|
||||||
bool error = false;
|
bool error = false;
|
||||||
string errorMessage = "";
|
string errorMessage = string.Empty;
|
||||||
|
|
||||||
p.Start();
|
p.Start();
|
||||||
string stdout = p.StandardOutput.ReadToEnd();
|
string stdout = p.StandardOutput.ReadToEnd();
|
||||||
|
@ -186,84 +321,16 @@ namespace SpanshAttack
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vaProxy.SetBoolean("~systemExists", exists);
|
VA!.SetBoolean("~systemExists", exists);
|
||||||
vaProxy.SetBoolean("~error", error);
|
VA!.SetBoolean("~error", error);
|
||||||
vaProxy.SetText("~errorMessage", errorMessage);
|
VA!.SetText("~errorMessage", errorMessage);
|
||||||
vaProxy.SetInt("~exitCode", p.ExitCode);
|
VA!.SetInt("~exitCode", p.ExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Startup(dynamic vaProxy)
|
private static void Context_Startup()
|
||||||
{
|
{
|
||||||
Log.Notice("Starting up …");
|
Log.Notice("Starting up …");
|
||||||
VA = vaProxy;
|
|
||||||
Log.Notice("Finished startup.");
|
Log.Notice("Finished startup.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*========================================\
|
|
||||||
| required VoiceAttack plugin shenanigans |
|
|
||||||
\========================================*/
|
|
||||||
|
|
||||||
static readonly Version VERSION = new Version("7.2.1");
|
|
||||||
|
|
||||||
public static Guid VA_Id()
|
|
||||||
=> new Guid("{e722b29d-898e-47dd-a843-a409c87e0bd8}");
|
|
||||||
public static string VA_DisplayName()
|
|
||||||
=> $"SpanshAttack {VERSION}";
|
|
||||||
public static string VA_DisplayInfo()
|
|
||||||
=> "SpanshAttack: a plugin for doing routing with spansh.co.uk for Elite: Dangerous.";
|
|
||||||
|
|
||||||
public static void VA_Init1(dynamic vaProxy)
|
|
||||||
{
|
|
||||||
VA = vaProxy;
|
|
||||||
Log.Notice("Initializing …");
|
|
||||||
VA.SetText("SpanshAttack.version", VERSION.ToString());
|
|
||||||
Log.Notice("Init successful.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void VA_Invoke1(dynamic vaProxy)
|
|
||||||
{
|
|
||||||
string context = vaProxy.Context.ToLower();
|
|
||||||
Log.Debug($"Running context '{context}' …");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch (context)
|
|
||||||
{
|
|
||||||
case "startup":
|
|
||||||
Context_Startup(vaProxy);
|
|
||||||
break;
|
|
||||||
// EDTS
|
|
||||||
case "edts.getcoordinates":
|
|
||||||
Context_EDTS_GetCoordinates(vaProxy);
|
|
||||||
break;
|
|
||||||
// log
|
|
||||||
case "log.log":
|
|
||||||
Context_Log(vaProxy);
|
|
||||||
break;
|
|
||||||
// Spansh
|
|
||||||
case "spansh.systemexists":
|
|
||||||
Context_Spansh_SytemExists(vaProxy);
|
|
||||||
break;
|
|
||||||
case "spansh.nearestsystem":
|
|
||||||
Context_Spansh_Nearestsystem(vaProxy);
|
|
||||||
break;
|
|
||||||
// invalid
|
|
||||||
default:
|
|
||||||
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ArgumentNullException e)
|
|
||||||
{
|
|
||||||
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void VA_Exit1(dynamic vaProxy) { }
|
|
||||||
|
|
||||||
public static void VA_StopCommand() { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
|
@ -30,7 +29,6 @@
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
@ -53,4 +51,4 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
10
plugins/VoiceAttack-base/GlobalSuppressions.cs
Normal file
10
plugins/VoiceAttack-base/GlobalSuppressions.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// This file is used by Code Analysis to maintain SuppressMessage
|
||||||
|
// attributes that are applied to this project.
|
||||||
|
// Project-level suppressions either have no target or are given
|
||||||
|
// a specific target and scoped to a namespace, type, member, etc.
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "just cause", Scope = "namespace", Target = "~N:alterNERDtive")]
|
||||||
|
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "just cause", Scope = "namespace", Target = "~N:alterNERDtive.edts")]
|
||||||
|
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "just cause", Scope = "namespace", Target = "~N:alterNERDtive.util")]
|
|
@ -16,8 +16,9 @@
|
||||||
<TabItem Name="StreamAttack" Header="StreamAttack"></TabItem>
|
<TabItem Name="StreamAttack" Header="StreamAttack"></TabItem>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
<WrapPanel VerticalAlignment="Bottom" HorizontalAlignment="Right">
|
<WrapPanel VerticalAlignment="Bottom" HorizontalAlignment="Right">
|
||||||
<Button Name="cancelButton" Click="cancelButton_Click" Padding="5" Margin="5">Cancel</Button>
|
<Button Name="applyButton" Click="ApplyButton_Click" Padding="5" Margin="5" Width="100">Apply</Button>
|
||||||
<Button Name="okButton" Click="okButton_Click" Padding="5" Margin="5">OK</Button>
|
<Button Name="okButton" Click="OkButton_Click" Padding="5" Margin="5" Width="100">Done</Button>
|
||||||
|
<Button Name="cancelButton" Click="CancelButton_Click" Padding="5" Margin="5" Width="100">Cancel</Button>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -1,4 +1,23 @@
|
||||||
using System;
|
// <copyright file="SettingsDialog.xaml.cs" company="alterNERDtive">
|
||||||
|
// Copyright 2019–2022 alterNERDtive.
|
||||||
|
//
|
||||||
|
// This file is part of alterNERDtive VoiceAttack profiles for Elite Dangerous.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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 alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// </copyright>
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
@ -6,40 +25,34 @@ using System.Windows.Controls;
|
||||||
namespace alterNERDtive
|
namespace alterNERDtive
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for SettingsDialog.xaml
|
/// Interaction logic for SettingsDialog.xaml.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsDialog : UserControl
|
public partial class SettingsDialog : UserControl
|
||||||
{
|
{
|
||||||
private struct Setting
|
private readonly List<Setting> values = new List<Setting>();
|
||||||
{
|
|
||||||
public string Profile { get; }
|
|
||||||
public dynamic Option { get; }
|
|
||||||
public dynamic Value { get; }
|
|
||||||
public dynamic UiElement { get; }
|
|
||||||
|
|
||||||
public Setting(string profile, dynamic option, dynamic value, dynamic uiElement)
|
|
||||||
=> (Profile, Option, Value, UiElement) = (profile, option, value, uiElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Setting> values = new List<Setting>();
|
|
||||||
private util.Configuration config;
|
private util.Configuration config;
|
||||||
private util.VoiceAttackLog log;
|
private util.VoiceAttackLog log;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SettingsDialog"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">The plugin Configuration.</param>
|
||||||
|
/// <param name="log">The plugin Log.</param>
|
||||||
public SettingsDialog(util.Configuration config, util.VoiceAttackLog log)
|
public SettingsDialog(util.Configuration config, util.VoiceAttackLog log)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
this.InitializeComponent();
|
||||||
|
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.log = log;
|
this.log = log;
|
||||||
|
|
||||||
foreach (TabItem tab in tabs.Items)
|
foreach (TabItem tab in this.tabs.Items)
|
||||||
{
|
{
|
||||||
string profile = tab.Name;
|
string profile = tab.Name;
|
||||||
if (profile == "general")
|
if (profile == "general")
|
||||||
{
|
{
|
||||||
profile = "alterNERDtive-base";
|
profile = "alterNERDtive-base";
|
||||||
}
|
}
|
||||||
|
|
||||||
tab.IsEnabled = BasePlugin.IsProfileActive(profile);
|
tab.IsEnabled = BasePlugin.IsProfileActive(profile);
|
||||||
|
|
||||||
StackPanel panel = new StackPanel();
|
StackPanel panel = new StackPanel();
|
||||||
|
@ -57,7 +70,7 @@ namespace alterNERDtive
|
||||||
checkBox.IsChecked = value;
|
checkBox.IsChecked = value;
|
||||||
checkBox.VerticalAlignment = VerticalAlignment.Center;
|
checkBox.VerticalAlignment = VerticalAlignment.Center;
|
||||||
row.Children.Add(checkBox);
|
row.Children.Add(checkBox);
|
||||||
values.Add(new Setting(profile, option, value, checkBox));
|
this.values.Add(new Setting(profile, option, value, checkBox));
|
||||||
|
|
||||||
Label label = new Label();
|
Label label = new Label();
|
||||||
label.Content = option.Description;
|
label.Content = option.Description;
|
||||||
|
@ -76,7 +89,7 @@ namespace alterNERDtive
|
||||||
TextBox input = new TextBox();
|
TextBox input = new TextBox();
|
||||||
input.Text = value.ToString();
|
input.Text = value.ToString();
|
||||||
row.Children.Add(input);
|
row.Children.Add(input);
|
||||||
values.Add(new Setting(profile, option, value, input));
|
this.values.Add(new Setting(profile, option, value, input));
|
||||||
|
|
||||||
panel.Children.Add(row);
|
panel.Children.Add(row);
|
||||||
}
|
}
|
||||||
|
@ -86,17 +99,11 @@ namespace alterNERDtive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelButton_Click(object sender, RoutedEventArgs e)
|
private bool ApplySettings()
|
||||||
{
|
{
|
||||||
Window.GetWindow(this).Close();
|
bool success = true;
|
||||||
log.Log("Settings dialog cancelled.", util.LogLevel.DEBUG);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void okButton_Click(object sender, RoutedEventArgs reargs)
|
foreach (Setting setting in this.values)
|
||||||
{
|
|
||||||
bool error = false;
|
|
||||||
|
|
||||||
foreach (Setting setting in values)
|
|
||||||
{
|
{
|
||||||
dynamic state = null;
|
dynamic state = null;
|
||||||
|
|
||||||
|
@ -129,21 +136,51 @@ namespace alterNERDtive
|
||||||
|
|
||||||
if (state != setting.Value)
|
if (state != setting.Value)
|
||||||
{
|
{
|
||||||
log.Log($@"Configuration changed via settings dialog: ""{setting.Profile}.{setting.Option.Name}"" → ""{state}""", util.LogLevel.DEBUG);
|
this.log.Log($@"Configuration changed via settings dialog: ""{setting.Profile}.{setting.Option.Name}"" → ""{state}""", util.LogLevel.DEBUG);
|
||||||
config.SetConfig(setting.Profile, setting.Option.Name, state);
|
this.config.SetConfig(setting.Profile, setting.Option.Name, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) when (e is ArgumentNullException || e is FormatException || e is OverflowException)
|
catch (Exception e) when (e is ArgumentNullException || e is FormatException || e is OverflowException)
|
||||||
{
|
{
|
||||||
log.Log($@"Invalid value for ""{setting.Profile}.{setting.Option.Name}"": ""{((TextBox)setting.UiElement).Text}""", util.LogLevel.ERROR);
|
this.log.Log($@"Invalid value for ""{setting.Profile}.{setting.Option.Name}"": ""{((TextBox)setting.UiElement).Text}""", util.LogLevel.ERROR);
|
||||||
error = true;
|
success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error)
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Window.GetWindow(this).Close();
|
||||||
|
this.log.Log("Settings dialog cancelled.", util.LogLevel.DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OkButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (this.ApplySettings())
|
||||||
{
|
{
|
||||||
Window.GetWindow(this).Close();
|
Window.GetWindow(this).Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ApplyButton_Click(object sender, RoutedEventArgs reeargs)
|
||||||
|
{
|
||||||
|
this.ApplySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct Setting
|
||||||
|
{
|
||||||
|
public Setting(string profile, dynamic option, dynamic value, dynamic uiElement)
|
||||||
|
=> (this.Profile, this.Option, this.Value, this.UiElement) = (profile, option, value, uiElement);
|
||||||
|
|
||||||
|
public string Profile { get; }
|
||||||
|
|
||||||
|
public dynamic Option { get; }
|
||||||
|
|
||||||
|
public dynamic Value { get; }
|
||||||
|
|
||||||
|
public dynamic UiElement { get; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
|
@ -33,7 +32,6 @@
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
@ -58,7 +56,10 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="base.cs" />
|
<Compile Include="base.cs" />
|
||||||
<Compile Include="edts.cs" />
|
<Compile Include="edts.cs">
|
||||||
|
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="GlobalSuppressions.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="SettingsDialog.xaml.cs">
|
<Compile Include="SettingsDialog.xaml.cs">
|
||||||
<DependentUpon>SettingsDialog.xaml</DependentUpon>
|
<DependentUpon>SettingsDialog.xaml</DependentUpon>
|
||||||
|
@ -75,4 +76,4 @@
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,6 +1,24 @@
|
||||||
#nullable enable
|
// <copyright file="base.cs" company="alterNERDtive">
|
||||||
|
// Copyright 2019–2022 alterNERDtive.
|
||||||
|
//
|
||||||
|
// This file is part of alterNERDtive VoiceAttack profiles for Elite Dangerous.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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 alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// </copyright>
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
using alterNERDtive.util;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
@ -9,31 +27,192 @@ using System.Net;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
using alterNERDtive.util;
|
||||||
|
|
||||||
namespace alterNERDtive
|
namespace alterNERDtive
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the base plugin orchestrating all the profile-specific plugins
|
||||||
|
/// to work together properly. It handles things like configuration or
|
||||||
|
/// subscribing to VoiceAttack-triggered events.
|
||||||
|
/// </summary>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "F off :)")]
|
||||||
public class BasePlugin
|
public class BasePlugin
|
||||||
{
|
{
|
||||||
private static dynamic? VA { get; set; }
|
private static readonly Version VERSION = new ("4.4");
|
||||||
private static readonly Dictionary<Guid, string> Profiles = new Dictionary<Guid, string> {
|
|
||||||
|
private static readonly Dictionary<Guid, string> Profiles = new ()
|
||||||
|
{
|
||||||
{ new Guid("{F7F59CFD-1AE2-4A7E-8F62-C62372418BAC}"), "alterNERDtive-base" },
|
{ new Guid("{F7F59CFD-1AE2-4A7E-8F62-C62372418BAC}"), "alterNERDtive-base" },
|
||||||
{ new Guid("{f31b575b-6ce4-44eb-91fc-7459e55013cf}"), "EliteAttack" },
|
{ new Guid("{f31b575b-6ce4-44eb-91fc-7459e55013cf}"), "EliteAttack" },
|
||||||
{ new Guid("{87276668-2a6e-4d80-af77-80651daa58b7}"), "RatAttack" },
|
{ new Guid("{87276668-2a6e-4d80-af77-80651daa58b7}"), "RatAttack" },
|
||||||
{ new Guid("{e722b29d-898e-47dd-a843-a409c87e0bd8}"), "SpanshAttack" },
|
{ new Guid("{e722b29d-898e-47dd-a843-a409c87e0bd8}"), "SpanshAttack" },
|
||||||
{ new Guid("{05580e6c-442c-46cd-b36f-f5a1f967ec59}"), "StreamAttack" }
|
{ new Guid("{05580e6c-442c-46cd-b36f-f5a1f967ec59}"), "StreamAttack" },
|
||||||
};
|
};
|
||||||
private static readonly List<string> ActiveProfiles = new List<string>();
|
|
||||||
private static readonly List<string> InstalledProfiles = new List<string>();
|
|
||||||
|
|
||||||
private static readonly Regex ConfigurationVariableRegex = new Regex(@$"(?<id>({String.Join("|", Profiles.Values)}))\.(?<name>.+)#");
|
private static readonly List<string> ActiveProfiles = new ();
|
||||||
|
private static readonly List<string> InstalledProfiles = new ();
|
||||||
|
|
||||||
private static VoiceAttackLog Log => log ??= new VoiceAttackLog(VA, "alterNERDtive-base");
|
private static readonly Regex ConfigurationVariableRegex = new (@$"(?<id>({string.Join("|", Profiles.Values)}))\.(?<name>.+)#");
|
||||||
|
|
||||||
|
private static VoiceAttackCommands? commands;
|
||||||
|
private static Configuration? config;
|
||||||
private static VoiceAttackLog? log;
|
private static VoiceAttackLog? log;
|
||||||
|
|
||||||
private static VoiceAttackCommands Commands => commands ??= new VoiceAttackCommands(VA, Log);
|
private static VoiceAttackCommands Commands => commands ??= new (VA, Log);
|
||||||
private static VoiceAttackCommands? commands;
|
|
||||||
|
|
||||||
private static Configuration Config => config ??= new Configuration(VA, Log, Commands, "alterNERDtive-base");
|
private static Configuration Config => config ??= new (VA, Log, Commands, "alterNERDtive-base");
|
||||||
private static Configuration? config;
|
|
||||||
|
private static VoiceAttackLog Log => log ??= new (VA, "alterNERDtive-base");
|
||||||
|
|
||||||
|
private static dynamic? VA { get; set; }
|
||||||
|
|
||||||
|
/*========================================\
|
||||||
|
| required VoiceAttack plugin shenanigans |
|
||||||
|
\========================================*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The plugin’s GUID, as required by the VoiceAttack plugin API.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The GUID.</returns>
|
||||||
|
public static Guid VA_Id()
|
||||||
|
=> new ("{F7F59CFD-1AE2-4A7E-8F62-C62372418BAC}");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The plugin’s display name, as required by the VoiceAttack plugin API.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The display name.</returns>
|
||||||
|
public static string VA_DisplayName()
|
||||||
|
=> $"alterNERDtive-base {VERSION}";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The plugin’s description, as required by the VoiceAttack plugin API.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The description.</returns>
|
||||||
|
public static string VA_DisplayInfo()
|
||||||
|
=> "The alterNERDtive plugin to manage all the alterNERDtive profiles!";
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public static void VA_Init1(dynamic vaProxy)
|
||||||
|
{
|
||||||
|
VA = vaProxy;
|
||||||
|
Log.Notice("Initializing …");
|
||||||
|
VA.SetText("alterNERDtive-base.version", VERSION.ToString());
|
||||||
|
vaProxy.BooleanVariableChanged += new Action<string, bool?, bool?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
||||||
|
vaProxy.DateVariableChanged += new Action<string, DateTime?, DateTime?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
||||||
|
vaProxy.DecimalVariableChanged += new Action<string, decimal?, decimal?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
||||||
|
vaProxy.IntegerVariableChanged += new Action<string, int?, int?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
||||||
|
vaProxy.TextVariableChanged += new Action<string, string, string, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
||||||
|
VA.SetBoolean("alterNERDtive-base.initialized", true);
|
||||||
|
Commands.TriggerEvent("alterNERDtive-base.initialized", wait: false, logMissing: false);
|
||||||
|
Log.Notice("Init successful.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public static void VA_Invoke1(dynamic vaProxy)
|
||||||
|
{
|
||||||
|
VA = vaProxy;
|
||||||
|
|
||||||
|
string context = vaProxy.Context.ToLower();
|
||||||
|
Log.Debug($"Running context '{context}' …");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (context)
|
||||||
|
{
|
||||||
|
case "startup":
|
||||||
|
Context_Startup();
|
||||||
|
break;
|
||||||
|
case "config.dialog":
|
||||||
|
// config
|
||||||
|
Context_Config_Dialog();
|
||||||
|
break;
|
||||||
|
case "config.dump":
|
||||||
|
Context_Config_Dump();
|
||||||
|
break;
|
||||||
|
case "config.getvariables":
|
||||||
|
Context_Config_SetVariables();
|
||||||
|
break;
|
||||||
|
case "config.list":
|
||||||
|
Context_Config_List();
|
||||||
|
break;
|
||||||
|
case "config.setup":
|
||||||
|
Context_Config_Setup();
|
||||||
|
break;
|
||||||
|
case "config.versionmigration":
|
||||||
|
Context_Config_VersionMigration();
|
||||||
|
break;
|
||||||
|
case "edsm.bodycount":
|
||||||
|
// EDSM
|
||||||
|
Context_EDSM_BodyCount();
|
||||||
|
break;
|
||||||
|
case "edsm.distancebetween":
|
||||||
|
Context_EDSM_DistanceBetween();
|
||||||
|
break;
|
||||||
|
case "eddi.event":
|
||||||
|
// EDDI
|
||||||
|
Context_Eddi_Event();
|
||||||
|
break;
|
||||||
|
case "spansh.outdatedstations":
|
||||||
|
// Spansh
|
||||||
|
Context_Spansh_OutdatedStations();
|
||||||
|
break;
|
||||||
|
case "log.log":
|
||||||
|
// log
|
||||||
|
Context_Log();
|
||||||
|
break;
|
||||||
|
case "update.check":
|
||||||
|
// update
|
||||||
|
Context_Update_Check();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// invalid
|
||||||
|
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ArgumentNullException e)
|
||||||
|
{
|
||||||
|
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
|
||||||
|
public static void VA_Exit1(dynamic vaProxy)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public static void VA_StopCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether a given profile is currently active.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="profileName">The name of the profile in question.</param>
|
||||||
|
/// <returns>The state of the profile in question.</returns>
|
||||||
|
public static bool IsProfileActive(string profileName) => ActiveProfiles.Contains(profileName);
|
||||||
|
|
||||||
private static void CheckProfiles(dynamic vaProxy)
|
private static void CheckProfiles(dynamic vaProxy)
|
||||||
{
|
{
|
||||||
|
@ -43,20 +222,21 @@ namespace alterNERDtive
|
||||||
foreach (KeyValuePair<Guid, string> profile in Profiles)
|
foreach (KeyValuePair<Guid, string> profile in Profiles)
|
||||||
{
|
{
|
||||||
if (vaProxy.Command.Exists($"(({profile.Value}.startup))"))
|
if (vaProxy.Command.Exists($"(({profile.Value}.startup))"))
|
||||||
// Sadly there is no way to find _active_ profiles, so we have to check the one command that always is in them.
|
|
||||||
{
|
{
|
||||||
|
// Sadly there is no way to find _active_ profiles, so we have to check the one command that always is in them.
|
||||||
ActiveProfiles.Add(profile.Value);
|
ActiveProfiles.Add(profile.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vaProxy.Profile.Exists(profile.Key))
|
if (vaProxy.Profile.Exists(profile.Key))
|
||||||
{
|
{
|
||||||
InstalledProfiles.Add(profile.Value);
|
InstalledProfiles.Add(profile.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Debug($"Profiles found: {string.Join<string>(", ", ActiveProfiles)}");
|
Log.Debug($"Profiles found: {string.Join<string>(", ", ActiveProfiles)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsProfileActive(string profileName) => ActiveProfiles.Contains(profileName);
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
|
||||||
|
|
||||||
private static void ConfigurationChanged(string option, dynamic? from, dynamic? to, Guid? guid = null)
|
private static void ConfigurationChanged(string option, dynamic? from, dynamic? to, Guid? guid = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -69,6 +249,7 @@ namespace alterNERDtive
|
||||||
Log.Debug($"Configuration has changed, '{id}.{name}': '{from}' → '{to}'");
|
Log.Debug($"Configuration has changed, '{id}.{name}': '{from}' → '{to}'");
|
||||||
|
|
||||||
dynamic o = Config.GetOption(id, name);
|
dynamic o = Config.GetOption(id, name);
|
||||||
|
|
||||||
// When loaded from profile but not explicitly set, will be null.
|
// When loaded from profile but not explicitly set, will be null.
|
||||||
// Then load default.
|
// Then load default.
|
||||||
// Same applies to resetting a saved option (= saving null to the profile).
|
// Same applies to resetting a saved option (= saving null to the profile).
|
||||||
|
@ -105,7 +286,8 @@ namespace alterNERDtive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option == "alterNERDtive-base.eddi.quietMode#" && VA!.GetText("EDDI version") != null) // if null, EDDI isn’t up yet
|
// if null, EDDI isn’t up yet
|
||||||
|
if (option == "alterNERDtive-base.eddi.quietMode#" && VA!.GetText("EDDI version") != null)
|
||||||
{
|
{
|
||||||
Log.Debug($"Resetting speech responder ({(to ?? false ? "off" : "on")}) …");
|
Log.Debug($"Resetting speech responder ({(to ?? false ? "off" : "on")}) …");
|
||||||
Commands.Run("alterNERDtive-base.setEDDISpeechResponder");
|
Commands.Run("alterNERDtive-base.setEDDISpeechResponder");
|
||||||
|
@ -137,7 +319,8 @@ namespace alterNERDtive
|
||||||
|
|
||||||
Log.Notice($"Local version: {VERSION}, latest release: {latestVersion}.");
|
Log.Notice($"Local version: {VERSION}, latest release: {latestVersion}.");
|
||||||
|
|
||||||
Commands.TriggerEvent("alterNERDtive-base.updateCheck",
|
Commands.TriggerEvent(
|
||||||
|
"alterNERDtive-base.updateCheck",
|
||||||
parameters: new dynamic[] { new string[] { VERSION.ToString(), latestVersion.ToString() }, new bool[] { VERSION.CompareTo(latestVersion) < 0 } });
|
parameters: new dynamic[] { new string[] { VERSION.ToString(), latestVersion.ToString() }, new bool[] { VERSION.CompareTo(latestVersion) < 0 } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,35 +328,37 @@ namespace alterNERDtive
|
||||||
| plugin contexts |
|
| plugin contexts |
|
||||||
\================*/
|
\================*/
|
||||||
|
|
||||||
private static void Context_Config_Dialog(dynamic vaProxy)
|
private static void Context_Config_Dialog()
|
||||||
{
|
{
|
||||||
Thread dialogThread = new Thread(new ThreadStart(() =>
|
Thread dialogThread = new Thread(new ThreadStart(() =>
|
||||||
{
|
{
|
||||||
_ = new System.Windows.Window
|
System.Windows.Window options = new ()
|
||||||
{
|
{
|
||||||
Title = "alterNERDtive Profile Options",
|
Title = "alterNERDtive Profile Options",
|
||||||
Content = new SettingsDialog(Config, Log),
|
Content = new SettingsDialog(Config, Log),
|
||||||
SizeToContent = System.Windows.SizeToContent.WidthAndHeight,
|
SizeToContent = System.Windows.SizeToContent.WidthAndHeight,
|
||||||
ResizeMode = System.Windows.ResizeMode.NoResize,
|
ResizeMode = System.Windows.ResizeMode.NoResize,
|
||||||
WindowStyle = System.Windows.WindowStyle.ToolWindow
|
WindowStyle = System.Windows.WindowStyle.ToolWindow,
|
||||||
}.ShowDialog();
|
};
|
||||||
|
options.ShowDialog();
|
||||||
|
options.Activate();
|
||||||
}));
|
}));
|
||||||
dialogThread.SetApartmentState(ApartmentState.STA);
|
dialogThread.SetApartmentState(ApartmentState.STA);
|
||||||
dialogThread.IsBackground = true;
|
dialogThread.IsBackground = true;
|
||||||
dialogThread.Start();
|
dialogThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Config_Dump(dynamic vaProxy)
|
private static void Context_Config_Dump()
|
||||||
{
|
{
|
||||||
Config.DumpConfig();
|
Config.DumpConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Config_List(dynamic vaProxy)
|
private static void Context_Config_List()
|
||||||
{
|
{
|
||||||
Config.ListConfig();
|
Config.ListConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Config_Setup(dynamic vaProxy)
|
private static void Context_Config_Setup()
|
||||||
{
|
{
|
||||||
Log.Debug("Loading default configuration …");
|
Log.Debug("Loading default configuration …");
|
||||||
Config.ApplyAllDefaults();
|
Config.ApplyAllDefaults();
|
||||||
|
@ -181,25 +366,45 @@ namespace alterNERDtive
|
||||||
{
|
{
|
||||||
Config.SetVoiceTriggers(type);
|
Config.SetVoiceTriggers(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.LoadFromProfile();
|
Config.LoadFromProfile();
|
||||||
Log.Debug("Finished loading configuration.");
|
Log.Debug("Finished loading configuration.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Config_SetVariables(dynamic vaProxy)
|
private static void Context_Config_SetVariables()
|
||||||
{
|
{
|
||||||
string trigger = vaProxy.GetText("~trigger") ?? throw new ArgumentNullException("~trigger");
|
string trigger = VA!.GetText("~trigger") ?? throw new ArgumentNullException("~trigger");
|
||||||
Log.Debug($"Loading variables for trigger '{trigger}' …");
|
Log.Debug($"Loading variables for trigger '{trigger}' …");
|
||||||
Config.SetVariablesForTrigger(vaProxy, trigger);
|
Config.SetVariablesForTrigger(VA!, trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Config_VersionMigration(dynamic vaProxy)
|
private static void Context_Config_VersionMigration()
|
||||||
{
|
{
|
||||||
|
// =============
|
||||||
|
// === 4.3.1 ===
|
||||||
|
// =============
|
||||||
|
|
||||||
|
// EliteAttack
|
||||||
|
foreach (string option in new string[] { "autoStationService" })
|
||||||
|
{
|
||||||
|
string name = $"EliteAttack.{option}s#";
|
||||||
|
string oldName = $"EliteAttack.{option}#";
|
||||||
|
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } });
|
||||||
|
bool? value = VA!.GetBoolean(oldName);
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
Log.Info($"Migrating option {oldName} …");
|
||||||
|
Commands.Run("alterNERDtive-base.saveVariableToProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}" }, new bool[] { (bool)value } });
|
||||||
|
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ===========
|
// ===========
|
||||||
// === 4.2 ===
|
// === 4.2 ===
|
||||||
// ===========
|
// ===========
|
||||||
|
|
||||||
// SpanshAttack
|
// SpanshAttack
|
||||||
string edtsPath = $@"{vaProxy.SessionState["VA_SOUNDS"]}\scripts\edts.exe";
|
string edtsPath = $@"{VA!.SessionState["VA_SOUNDS"]}\scripts\edts.exe";
|
||||||
if (File.Exists(edtsPath))
|
if (File.Exists(edtsPath))
|
||||||
{
|
{
|
||||||
File.Delete(edtsPath);
|
File.Delete(edtsPath);
|
||||||
|
@ -240,6 +445,7 @@ namespace alterNERDtive
|
||||||
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
|
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string option in new string[] { "CMDRs", "platforms" })
|
foreach (string option in new string[] { "CMDRs", "platforms" })
|
||||||
{
|
{
|
||||||
string name = $"{prefix}.{option}";
|
string name = $"{prefix}.{option}";
|
||||||
|
@ -267,6 +473,7 @@ namespace alterNERDtive
|
||||||
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
|
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string option in new string[] { "announceJumpsLeft" })
|
foreach (string option in new string[] { "announceJumpsLeft" })
|
||||||
{
|
{
|
||||||
string name = $"{prefix}.{option}";
|
string name = $"{prefix}.{option}";
|
||||||
|
@ -296,26 +503,26 @@ namespace alterNERDtive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Eddi_Event(dynamic vaProxy)
|
private static void Context_Eddi_Event()
|
||||||
{
|
{
|
||||||
string eddiEvent = vaProxy.Command.Name();
|
string eddiEvent = VA!.Command.Name();
|
||||||
string command = eddiEvent.Substring(2, eddiEvent.Length - 4);
|
string command = eddiEvent.Substring(2, eddiEvent.Length - 4);
|
||||||
Log.Debug($"Running EDDI event '{command}' …");
|
Log.Debug($"Running EDDI event '{command}' …");
|
||||||
Commands.RunAll(ActiveProfiles, command, logMissing: false, subcommand: true); // FIXXME: a) triggerAll or something, b) change all profiles to use "((<name>.<event>))" over "<name>.<event>"
|
Commands.RunAll(ActiveProfiles, command, logMissing: false, subcommand: true); // FIXXME: a) triggerAll or something, b) change all profiles to use "((<name>.<event>))" over "<name>.<event>"
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_EDSM_BodyCount(dynamic vaProxy)
|
private static void Context_EDSM_BodyCount()
|
||||||
{
|
{
|
||||||
string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
|
string system = VA!.GetText("~system") ?? throw new ArgumentNullException("~system");
|
||||||
|
|
||||||
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\scripts\explorationtools.exe";
|
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\scripts\explorationtools.exe";
|
||||||
string arguments = $@"bodycount ""{system}""";
|
string arguments = $@"bodycount ""{system}""";
|
||||||
|
|
||||||
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
||||||
|
|
||||||
int bodyCount = 0;
|
int bodyCount = 0;
|
||||||
bool error = false;
|
bool error = false;
|
||||||
string errorMessage = "";
|
string errorMessage = string.Empty;
|
||||||
|
|
||||||
p.Start();
|
p.Start();
|
||||||
string stdout = p.StandardOutput.ReadToEnd();
|
string stdout = p.StandardOutput.ReadToEnd();
|
||||||
|
@ -344,26 +551,26 @@ namespace alterNERDtive
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vaProxy.SetInt("~bodyCount", bodyCount);
|
VA!.SetInt("~bodyCount", bodyCount);
|
||||||
vaProxy.SetBoolean("~error", error);
|
VA!.SetBoolean("~error", error);
|
||||||
vaProxy.SetText("~errorMessage", errorMessage);
|
VA!.SetText("~errorMessage", errorMessage);
|
||||||
vaProxy.SetInt("~exitCode", p.ExitCode);
|
VA!.SetInt("~exitCode", p.ExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_EDSM_DistanceBetween(dynamic vaProxy)
|
private static void Context_EDSM_DistanceBetween()
|
||||||
{
|
{
|
||||||
string fromSystem = vaProxy.GetText("~fromSystem") ?? throw new ArgumentNullException("~fromSystem");
|
string fromSystem = VA!.GetText("~fromSystem") ?? throw new ArgumentNullException("~fromSystem");
|
||||||
string toSystem = vaProxy.GetText("~toSystem") ?? throw new ArgumentNullException("~toSystem");
|
string toSystem = VA!.GetText("~toSystem") ?? throw new ArgumentNullException("~toSystem");
|
||||||
int roundTo = vaProxy.GetInt("~roundTo") ?? 2;
|
int roundTo = VA!.GetInt("~roundTo") ?? 2;
|
||||||
|
|
||||||
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\explorationtools.exe";
|
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\explorationtools.exe";
|
||||||
string arguments = $@"distancebetween --roundto {roundTo} ""{fromSystem}"" ""{toSystem}""";
|
string arguments = $@"distancebetween --roundto {roundTo} ""{fromSystem}"" ""{toSystem}""";
|
||||||
|
|
||||||
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
||||||
|
|
||||||
decimal distance = 0;
|
decimal distance = 0;
|
||||||
bool error = false;
|
bool error = false;
|
||||||
string errorMessage = "";
|
string errorMessage = string.Empty;
|
||||||
|
|
||||||
p.Start();
|
p.Start();
|
||||||
string stdout = p.StandardOutput.ReadToEnd();
|
string stdout = p.StandardOutput.ReadToEnd();
|
||||||
|
@ -386,19 +593,18 @@ namespace alterNERDtive
|
||||||
Log.Error(stderr);
|
Log.Error(stderr);
|
||||||
errorMessage = "Unrecoverable error in plugin.";
|
errorMessage = "Unrecoverable error in plugin.";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vaProxy.SetDecimal("~distance", distance);
|
VA!.SetDecimal("~distance", distance);
|
||||||
vaProxy.SetBoolean("~error", error);
|
VA!.SetBoolean("~error", error);
|
||||||
vaProxy.SetText("~errorMessage", errorMessage);
|
VA!.SetText("~errorMessage", errorMessage);
|
||||||
vaProxy.SetInt("~exitCode", p.ExitCode);
|
VA!.SetInt("~exitCode", p.ExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Log(dynamic vaProxy)
|
private static void Context_Log()
|
||||||
{
|
{
|
||||||
string message = vaProxy.GetText("~message");
|
string message = VA!.GetText("~message");
|
||||||
string level = vaProxy.GetText("~level");
|
string level = VA!.GetText("~level");
|
||||||
|
|
||||||
if (level == null)
|
if (level == null)
|
||||||
{
|
{
|
||||||
|
@ -410,7 +616,10 @@ namespace alterNERDtive
|
||||||
{
|
{
|
||||||
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
|
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
|
||||||
}
|
}
|
||||||
catch (ArgumentNullException) { throw; }
|
catch (ArgumentNullException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
Log.Error($"Invalid log level '{level}'.");
|
Log.Error($"Invalid log level '{level}'.");
|
||||||
|
@ -418,17 +627,16 @@ namespace alterNERDtive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Spansh_OutdatedStations(dynamic vaProxy)
|
private static void Context_Spansh_OutdatedStations()
|
||||||
{
|
{
|
||||||
string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
|
string system = VA!.GetText("~system") ?? throw new ArgumentNullException("~system");
|
||||||
int minage = vaProxy.GetInt("~minage") ?? throw new ArgumentNullException("~minage");
|
int minage = VA!.GetInt("~minage") ?? throw new ArgumentNullException("~minage");
|
||||||
|
|
||||||
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
|
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
|
||||||
string arguments = $@"oldstations --system ""{system}"" --minage {minage}";
|
string arguments = $@"oldstations --system ""{system}"" --minage {minage}";
|
||||||
|
|
||||||
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
Process p = PythonProxy.SetupPythonScript(path, arguments);
|
||||||
|
|
||||||
|
|
||||||
p.Start();
|
p.Start();
|
||||||
string stdout = p.StandardOutput.ReadToEnd();
|
string stdout = p.StandardOutput.ReadToEnd();
|
||||||
string stderr = p.StandardError.ReadToEnd();
|
string stderr = p.StandardError.ReadToEnd();
|
||||||
|
@ -457,16 +665,15 @@ namespace alterNERDtive
|
||||||
Log.Error(stderr);
|
Log.Error(stderr);
|
||||||
errorMessage = "Unrecoverable error in plugin.";
|
errorMessage = "Unrecoverable error in plugin.";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vaProxy.SetText("~message", message);
|
VA!.SetText("~message", message);
|
||||||
vaProxy.SetBoolean("~error", error);
|
VA!.SetBoolean("~error", error);
|
||||||
vaProxy.SetText("~errorMessage", errorMessage);
|
VA!.SetText("~errorMessage", errorMessage);
|
||||||
vaProxy.SetInt("~exitCode", p.ExitCode);
|
VA!.SetInt("~exitCode", p.ExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Startup(dynamic vaProxy)
|
private static void Context_Startup()
|
||||||
{
|
{
|
||||||
Log.Notice("Starting up …");
|
Log.Notice("Starting up …");
|
||||||
CheckProfiles(VA);
|
CheckProfiles(VA);
|
||||||
|
@ -475,112 +682,9 @@ namespace alterNERDtive
|
||||||
Log.Notice("Finished startup.");
|
Log.Notice("Finished startup.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Context_Update_Check(dynamic vaProxy)
|
private static void Context_Update_Check()
|
||||||
{
|
{
|
||||||
UpdateCheck();
|
UpdateCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*========================================\
|
|
||||||
| required VoiceAttack plugin shenanigans |
|
|
||||||
\========================================*/
|
|
||||||
|
|
||||||
static readonly Version VERSION = new Version("4.3");
|
|
||||||
|
|
||||||
public static Guid VA_Id()
|
|
||||||
=> new Guid("{F7F59CFD-1AE2-4A7E-8F62-C62372418BAC}");
|
|
||||||
public static string VA_DisplayName()
|
|
||||||
=> $"alterNERDtive-base {VERSION}";
|
|
||||||
public static string VA_DisplayInfo()
|
|
||||||
=> "The alterNERDtive plugin to manage all the alterNERDtive profiles!";
|
|
||||||
|
|
||||||
public static void VA_Init1(dynamic vaProxy)
|
|
||||||
{
|
|
||||||
VA = vaProxy;
|
|
||||||
Log.Notice("Initializing …");
|
|
||||||
VA.SetText("alterNERDtive-base.version", VERSION.ToString());
|
|
||||||
vaProxy.BooleanVariableChanged += new Action<String, Boolean?, Boolean?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
|
||||||
vaProxy.DateVariableChanged += new Action<String, DateTime?, DateTime?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
|
||||||
vaProxy.DecimalVariableChanged += new Action<String, decimal?, decimal?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
|
||||||
vaProxy.IntegerVariableChanged += new Action<String, int?, int?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
|
||||||
vaProxy.TextVariableChanged += new Action<String, String, String, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
|
|
||||||
VA.SetBoolean("alterNERDtive-base.initialized", true);
|
|
||||||
Commands.TriggerEvent("alterNERDtive-base.initialized", wait: false, logMissing: false);
|
|
||||||
Log.Notice("Init successful.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void VA_Invoke1(dynamic vaProxy)
|
|
||||||
{
|
|
||||||
VA = vaProxy;
|
|
||||||
|
|
||||||
string context = vaProxy.Context.ToLower();
|
|
||||||
Log.Debug($"Running context '{context}' …");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch (context)
|
|
||||||
{
|
|
||||||
case "startup":
|
|
||||||
Context_Startup(vaProxy);
|
|
||||||
break;
|
|
||||||
// config
|
|
||||||
case "config.dialog":
|
|
||||||
Context_Config_Dialog(vaProxy);
|
|
||||||
break;
|
|
||||||
case "config.dump":
|
|
||||||
Context_Config_Dump(vaProxy);
|
|
||||||
break;
|
|
||||||
case "config.getvariables":
|
|
||||||
Context_Config_SetVariables(vaProxy);
|
|
||||||
break;
|
|
||||||
case "config.list":
|
|
||||||
Context_Config_List(vaProxy);
|
|
||||||
break;
|
|
||||||
case "config.setup":
|
|
||||||
Context_Config_Setup(vaProxy);
|
|
||||||
break;
|
|
||||||
case "config.versionmigration":
|
|
||||||
Context_Config_VersionMigration(vaProxy);
|
|
||||||
break;
|
|
||||||
// EDSM
|
|
||||||
case "edsm.bodycount":
|
|
||||||
Context_EDSM_BodyCount(vaProxy);
|
|
||||||
break;
|
|
||||||
case "edsm.distancebetween":
|
|
||||||
Context_EDSM_DistanceBetween(vaProxy);
|
|
||||||
break;
|
|
||||||
// EDDI
|
|
||||||
case "eddi.event":
|
|
||||||
Context_Eddi_Event(vaProxy);
|
|
||||||
break;
|
|
||||||
// Spansh
|
|
||||||
case "spansh.outdatedstations":
|
|
||||||
Context_Spansh_OutdatedStations(vaProxy);
|
|
||||||
break;
|
|
||||||
// log
|
|
||||||
case "log.log":
|
|
||||||
Context_Log(vaProxy);
|
|
||||||
break;
|
|
||||||
// update
|
|
||||||
case "update.check":
|
|
||||||
Context_Update_Check(vaProxy);
|
|
||||||
break;
|
|
||||||
// invalid
|
|
||||||
default:
|
|
||||||
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ArgumentNullException e)
|
|
||||||
{
|
|
||||||
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void VA_Exit1(dynamic vaProxy) { }
|
|
||||||
|
|
||||||
public static void VA_StopCommand() { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,31 @@
|
||||||
#nullable enable
|
// <auto-generated/>
|
||||||
|
// Not really, but this file will not bow to StyleCop tyranny.
|
||||||
|
// Why? Because it will be obsolete mid term anyway ;)
|
||||||
|
|
||||||
|
// <copyright file="edts.cs" company="alterNERDtive">
|
||||||
|
// Copyright 2019–2022 alterNERDtive.
|
||||||
|
//
|
||||||
|
// This file is part of alterNERDtive VoiceAttack profiles for Elite Dangerous.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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.
|
||||||
|
//
|
||||||
|
// alterNERDtive VoiceAttack profiles for Elite Dangerous 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 alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// </copyright>
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace alterNERDtive.edts
|
namespace alterNERDtive.edts
|
||||||
{
|
{
|
||||||
|
@ -57,4 +78,4 @@ namespace alterNERDtive.edts
|
||||||
return new StarSystem { Name=name, Coords=new Position { X=x, Y=y, Z=z, Precision=uncertainty } };
|
return new StarSystem { Name=name, Coords=new Position { X=x, Y=y, Z=z, Precision=uncertainty } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
16
stylecop.json
Normal file
16
stylecop.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
|
||||||
|
"settings": {
|
||||||
|
"orderingRules": {
|
||||||
|
"usingDirectivesPlacement": "outsideNamespace"
|
||||||
|
},
|
||||||
|
"documentationRules": {
|
||||||
|
"companyName": "alterNERDtive",
|
||||||
|
"copyrightText": "Copyright {year} {companyName}.\n\nThis file is part of {application}.\n\n{application} is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\n{application} is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with {application}. If not, see <https://www.gnu.org/licenses/>.",
|
||||||
|
"variables": {
|
||||||
|
"application": "alterNERDtive VoiceAttack profiles for Elite Dangerous",
|
||||||
|
"year": "2019–2022"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue