Compare commits

...

42 commits

Author SHA1 Message Date
f034ae4220
4.5! 2022-09-19 18:08:43 +02:00
d97499778c
docs: clarified when StreamAttack updates information
fixes #155
2022-09-15 15:17:39 +02:00
d78cf17b6b
docs: added reloading the profile / restarting VA to installation instructions
fixes #154
2022-09-15 15:15:41 +02:00
0d44828422
docs: clarified that neutron router plugin is optional
fixes #153
2022-09-15 15:13:20 +02:00
022c3ac25c
fixed VERSION 2022-09-15 15:08:54 +02:00
fd0bbaa3a9
added StyleCop.ruleset to make that one shut up 2022-09-15 15:07:15 +02:00
cc2694fc49
RatAttack: support for new Horizons 3.8 / 4.0 / Odyssey RATSIGNALs
fixes #159
2022-09-15 15:06:49 +02:00
9db6785ef1
RatAttack: fixed RATSIGNAL regex
Apparently `^` can be part of both CMDR names and IRC nicks.
2022-09-10 03:43:19 +02:00
1135efd761
EliteAttack: fixed potential race condition in the discovery scan event command queue 2022-09-06 00:29:51 +02:00
7c361e9bf7
EliteAttack: added option to exclude settlements from the outdated stations list
fixes #119
2022-09-05 19:21:12 +02:00
54cd1e6fa2
EliteAttack: target nearest […] commands now log the result 2022-08-31 10:26:12 +02:00
3775d3f911
docs: added troubleshooting section about Geforce Now 2022-08-23 22:26:11 +02:00
alterNERDtive
1357bde807
Merge pull request #151 from alterNERDtive/feature/auto-pull-request 2022-07-13 22:26:07 +02:00
db85c2b793
auto-pull-request workflow: fixed branch name 2022-07-13 22:25:13 +02:00
4f9e4799bf
workflows: open pr on branch push 2022-07-13 22:23:45 +02:00
5af0aff95c
workflows: fixed release author 2022-07-13 21:15:35 +02:00
e2789623cd
cleaned up dependency mess 2022-07-12 00:40:55 +02:00
c615af5324
updated CHANGELOG 2022-07-11 19:52:39 +02:00
Ant
4e9a9b4517
Black out the grey censory block 2022-07-11 19:45:29 +02:00
Ant
38ea143ea7
SpanshAttack.md: fix column width 2022-07-11 19:45:25 +02:00
Ant
0ee7701590
EliteAttack: hyperlink path fix - DOH 2022-07-11 19:45:21 +02:00
Ant
05a56d5d85
index.md: correction to hyperlink markdown syntax 2022-07-11 19:45:05 +02:00
Ant
2ec9c2afbe
EliteAttack.md: correction to hyperlink markdown syntax 2022-07-11 19:44:49 +02:00
Ant
3cbfe62ae1
docs markdown fixes & author privacy on screenshot 2022-07-11 19:44:19 +02:00
dependabot[bot]
9cc9965d7c Bump Newtonsoft.Json from 6.0.4 to 13.0.1 in /plugins/VoiceAttack-base
Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 6.0.4 to 13.0.1.
- [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/6.0.4...13.0.1)

---
updated-dependencies:
- dependency-name: Newtonsoft.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-08 17:52:13 +02:00
acf43b42a0 added .github as solution items 2022-07-08 17:52:09 +02:00
55fa3579cf fixed gh-pages workflow 2022-07-08 17:45:39 +02:00
d1af3ebdcc Merge branch 'release' into devel 2022-07-04 01:32:38 +02:00
b10e2bb2c4 added ko-fi / sponsors 2022-07-04 01:32:29 +02:00
91c47efbef fixed create-release workflow
fixes #148
2022-07-04 00:33:28 +02:00
1cdd9c98bd EliteAttack: fixed Docked event for Oddity settlements
fixes #145
2022-06-16 12:10:49 +02:00
35c26e930f mics fixes 2022-06-16 12:06:28 +02:00
bb8d1067b5 RatAttack: made case list thread safe
My specific setup leads to lots of incoming cases at once when starting VA after boot, when the IRC backlog is parsed.

Probably not relevant in the wild, but still a huge 🤦.
2022-06-03 16:45:12 +02:00
6ec8d7c35e stylecop compliance, round 3 of >3 2022-06-02 17:41:49 +02:00
55f10a1117 all plugins: fixed possible race condition introduced in 4.4 2022-06-02 15:28:17 +02:00
35057b3f35 dependabot 2022-06-01 09:12:01 +02:00
a2f6cc864c auto-deploy gh-pages 2022-06-01 09:11:57 +02:00
9beb6dfa41 Merge branch 'devel' into release 2022-05-31 19:31:28 +02:00
2dae2abc4c workflows: fixed(?) release glob 2022-05-31 19:29:08 +02:00
c00c1d9bbe Merge branch 'devel' into release 2022-05-19 12:49:30 +02:00
3c46b20a23 Merge branch 'devel' into release 2021-05-23 20:36:24 +02:00
1d6ee3953e updated .editorconfig 2021-05-23 20:26:54 +02:00
44 changed files with 1381 additions and 640 deletions

2
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,2 @@
github: alterNERDtive
ko_fi: alterNERDtive

12
.github/dependabot.yaml vendored Normal file
View file

@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/"
target-branch: "develop"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "develop"
schedule:
interval: "daily"

View file

@ -0,0 +1,20 @@
name: Pull Request on Branch Push
on:
push:
branches-ignore:
- devel
- release
jobs:
auto-pull-request:
name: Open pull request
runs-on: ubuntu-latest
steps:
- name: pull-request-action
uses: vsoch/pull-request-action@1.0.19
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PULL_REQUEST_BRANCH: "devel"
PULL_REQUEST_DRAFT: true
PASS_IF_EXISTS: true

View file

@ -3,16 +3,21 @@
on: on:
push: push:
tags: tags:
- 'releases/*' - 'releases/*.*'
- 'releases/*.*.*'
jobs: jobs:
release: build:
name: Create draft release name: Create draft release
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Draft release - name: Draft release
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
bodyFile: "CHANGELOG.md" bodyFile: "CHANGELOG.md"
draft: true draft: true
token: ${{ secrets.RELEASE_TOKEN }}

22
.github/workflows/gh-pages.yaml vendored Normal file
View file

@ -0,0 +1,22 @@
name: Deploy github pages on tag push
on:
push:
tags:
- 'release/*.*'
- 'release/*.*.*'
jobs:
build:
name: Deploy documentation
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Deploy docs
uses: mhausenblas/mkdocs-deploy-gh-pages@nomaterial
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REQUIREMENTS: requirements.txt

View file

@ -1,4 +1,56 @@
# 4.4 (2022-05-31) # 4.5 (2022-09-19)
This might very well be the last release of this. With how the “Horizons 4.0”
launch went, Frontiers communication around it, and just _how_ horrible 4.0 is,
I currently do not see me being motivated to actually port stuff to 4.0. And,
lets face it, 3.8 will go EoL eventually.
Anyway, I still have some programming pet projects around this stuff that I
might continue with and adapt this for, so I might sneak some fixes / updates
in, and Im not going to say never because who knows how Ill feel about this in
the future. Obviously theres also still the option to _pay_ me to do stuff =p
### Fixed
* Race condition in all plugins that might lead to commands using command-scoped
variables (`~<name>`) not working as intended. This was introduced in
refactoring work that was done for 4.4.
* Documentation proof read and fixed by @ACyprus. Thanks!
### Changed
* Some behind the scenes things regarding how builds work. This will make it
possible to build this entirely on Github (= less potential for human error)
once I have dealt with #62 (see #143 as well).
## EliteAttack 8.5
### Added
* `target nearest […]` commands now log the result (with log level “INFO”).
* `include outdated settlements` option: Include Odyssey settlements in the
outdated stations list. Default: true.
### Fixed
* `Docked` event now handles Odyssey settlements properly (they have no hangar).
(#145)
* Fixed potential race condition with the discovery scan event command queue.
Might have an impact on #64.
## RatAttack 6.4
### Fixed
* Support for new Horizons 3 / Horizons 4 / Odyssey RATSIGNALs. (#159)
* Made case list thread safe. Probably only ever impacted my own specific setup,
but still a huge 🤦.
* Apparently `^` can be part of both CMDR names and IRC nicks (fixed RATSIGNAL
regex).
-----
# 4.4 (2022-05-31)
### Added ### Added
@ -1083,8 +1135,7 @@ up to date in EDDN.
* Added `open [rat;] dispatch board` command. Opens the web dispatch board in * Added `open [rat;] dispatch board` command. Opens the web dispatch board in
your default browser. your default browser.
* Added proper handling for multiple ratsignals hitting at once. Thats mainly * Added proper handling for multiple ratsignals hitting at once. Thats mainly
an IRC client config thing, an IRC client config thing, [see the docs](docs/configuration/RatAttack.md).
[see the docs](docs/RatAttack.md#getting-case-data-from-irc).
* Renamed `RatAttack.getInfoFromRatsignal` to * Renamed `RatAttack.getInfoFromRatsignal` to
`RatAttack.announceCaseFromRatsignal`. Removed the “open case?” voice input `RatAttack.announceCaseFromRatsignal`. Removed the “open case?” voice input
prompt. prompt.

View file

@ -37,3 +37,6 @@ issue](https://github.com/alterNERDtive/VoiceAttack-profiles/issues). Thanks! :)
You can also [say “Hi” on Discord](https://discord.gg/kXtXm54) if that is your You can also [say “Hi” on Discord](https://discord.gg/kXtXm54) if that is your
thing. thing.
[![GitHub Sponsors](https://img.shields.io/github/sponsors/alterNERDtive?style=for-the-badge)](https://github.com/sponsors/alterNERDtive)
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/S6S1DLYBS)

2
StyleCop.ruleset Normal file
View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="StyleCop.Analyzers rules with default action" Description="StyleCop.Analyzers with default action. Rules with IsEnabledByDefault = false are disabled." ToolsVersion="17.0" />

View file

@ -1 +1 @@
4.4 4.5

View file

@ -35,7 +35,7 @@ the edit window ready to send. They will _not_ hit Enter on their own.
## Navigation ## Navigation
There are so many navigation-focused commands now, they deserve there own There are so many navigation-focused commands now, they deserve their own
category. Basically anything that helps you plot anywhere. A lot of those are category. Basically anything that helps you plot anywhere. A lot of those are
powered by awesome EDDI so I dont have to do the work myself! powered by awesome EDDI so I dont have to do the work myself!
@ -72,10 +72,9 @@ Basically anything that is related to directly doing something with your ship.
* `[close;deploy;extend;open;retract;] [cargo scoop;hard points; landing gear] [up;down;]`: * `[close;deploy;extend;open;retract;] [cargo scoop;hard points; landing gear] [up;down;]`:
Overly complicated command to handle everything related to Cargo Scoop, Hard Overly complicated command to handle everything related to Cargo Scoop, Hard
Points, Landing Gear. You get the gist, I guess. Works in SRV too. Points, Landing Gear. You get the gist, I guess. Works in SRV too.
* `[dis;]engage silent running`: Handles silent running.
* `[disco;discovery scan]`: Executes a discovery scan. Expects the Discovery * `[disco;discovery scan]`: Executes a discovery scan. Expects the Discovery
Scanner in your first fire group, secondary fire. [You can change Scanner in your first fire group, secondary fire. [You can change
that](/configuration/EliteAttack/#settings). that](configuration/EliteAttack.md#settings).
* `[dis;]engage silent running`: Turns silent running on and off. * `[dis;]engage silent running`: Turns silent running on and off.
* `[head;spot;] lights [on;off]`: Turns your lights on and off. Works in SRV * `[head;spot;] lights [on;off]`: Turns your lights on and off. Works in SRV
too, kinda; turning lights off there relies on the state updating fast enough, too, kinda; turning lights off there relies on the state updating fast enough,
@ -96,7 +95,7 @@ Basically anything that is related to directly doing something with your ship.
given “when ready” will wait for mass lock to clear and your FSD to cool down given “when ready” will wait for mass lock to clear and your FSD to cool down
first. first.
## SRV controls ## SRV Controls
Things relevant to your SRV, but not your ship. Things relevant to your SRV, but not your ship.
@ -107,13 +106,12 @@ Things relevant to your SRV, but not your ship.
## Targeting ## Targeting
Well … targeting stuff, I guess. Not really sure why I made that its own Well … targeting stuff, I guess. Not really sure why I made that its own
category, but oh well :) category, but oh well :)
* `target the [drive;drives;power plant;frame shift drive;f s d;shield * `target the [drive;drives;power plant;frame shift drive;f s d;shield
generator]`:* generator]`: Targets the given submodule on your current target, or your next
Targets the given submodule on your current target, or your next target if you target if you dont have one currently. Does not persist between targets.
dont have one currently. Does not persist between targets.
* `clear sub [module;system] target`: Clears the current submodule target. * `clear sub [module;system] target`: Clears the current submodule target.
* `target next system`: Selects the next system on your route. * `target next system`: Selects the next system on your route.
* `target wing man [1;2;3]`: Targets your wingmen. * `target wing man [1;2;3]`: Targets your wingmen.
@ -272,7 +270,7 @@ the (rough) range you still have on the fumes left in your tank.
### Material Threshold ### Material Threshold
Warns you when a monitored material falls below its minimum stock level and Warns you when a monitored material falls below its minimum stock level and
tells you when you reach your desired level or fill up. tells you when you reach your desired level or fill up.
You will have to set minimum and desired amounts in EDDIs material monitor You will have to set minimum and desired amounts in EDDIs material monitor
@ -308,7 +306,7 @@ Reports on the synthesis type and quality.
### System Scan Complete ### System Scan Complete
Lists you all bodies EDDI considers worth mapping in the current system. Lists all bodies EDDI considers worth mapping in the current system.
### Undocked ### Undocked

View file

@ -66,7 +66,7 @@ client or use the “General IRC Integration”, see below.
login to the game or have to take off from your current login to the game or have to take off from your current
station/port/outpost/planet. station/port/outpost/planet.
* `call jumps [left;]`: Calls jumps for the currently open case based on a * `call jumps [left;]`: Calls jumps for the currently open case based on a
neutron trip (requires Spanshattack) or a plotted ingame route. neutron trip (requires SpanshAttack) or a plotted ingame route.
* `call friend [positive;negative] [in pg;in private group;in solo;in main menu;sysconf;system confirmed;]`: * `call friend [positive;negative] [in pg;in private group;in solo;in main menu;sysconf;system confirmed;]`:
Friend request confirmations, with all the Friend request confirmations, with all the
things you might want to / should call with it. things you might want to / should call with it.

View file

@ -1,10 +1,10 @@
# SpanshAttack # SpanshAttack
This profile uses the This profile uses the
[ED-NeutronRouter](https://github.com/sc-pulgan/ED-NeutronRouter) plugin to plot [ED-NeutronRouter](https://github.com/sc-pulgan/ED-NeutronRouter) plugin to
neutron jumps using [spansh](https://spansh.co.uk/plotter). It fully does plot neutron jumps using [Spansh](https://spansh.co.uk/plotter). It does
everything you need from within the game and VoiceAttack, you wont have to everything you need fully from within the game and VoiceAttack, you wont have
visit the site at any point. to visit the site at any point.
## Plotting a Route ## Plotting a Route

View file

@ -1,4 +1,4 @@
# StreamAttack # StreamAttack
This profile uses the [EDDI](https://github.com/EDCD/EDDI) plugin to write This profile uses the [EDDI](https://github.com/EDCD/EDDI) plugin to write
a bunch of information about your commander, your current location and your ship a bunch of information about your commander, your current location and your ship
@ -23,6 +23,10 @@ Default folder is `%appdata%\StreamAttack\`.
### Elite ### Elite
Please do note that information in the output files is only updated when a
journal event that contains the information is detected. E.g. the distance to
your jump target is not constantly calculated, but only updated after a jump.
#### Commander #### Commander
* `Elite\cmdr\name`: The current commanders name. * `Elite\cmdr\name`: The current commanders name.
@ -45,4 +49,4 @@ Default folder is `%appdata%\StreamAttack\`.
* `Elite\ship\build`: Your current ships loadout (link to coriolis). * `Elite\ship\build`: Your current ships loadout (link to coriolis).
* `Elite\ship\full`: `“<name>” | <model> | <build>`. * `Elite\ship\full`: `“<name>” | <model> | <build>`.
* `Elite\ship\model`: Your current ships model. * `Elite\ship\model`: Your current ships model.
* `Elite\ship\name`: Your current ships name. * `Elite\ship\name`: Your current ships name.

View file

@ -14,7 +14,7 @@ Toggles:
true. true.
* `auto restock`: Automatically restock after docking at a station. Default: * `auto restock`: Automatically restock after docking at a station. Default:
true. true.
* `auto move to hangar`: Automatically move the ship to the hanger after docking * `auto move to hangar`: Automatically move the ship to the hangar after docking
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.
@ -37,6 +37,8 @@ Toggles:
Ammonia Worlds that have not been mapped yet.) Default: true. Ammonia Worlds that have not been mapped yet.) Default: true.
* `outdated stations`: Announce stations with outdated data in the online * `outdated stations`: Announce stations with outdated data in the online
databases. Default: true. databases. Default: true.
* `include outdated settlements` option: Include Odyssey settlements in the
outdated stations list. Default: true.
* `repair reports`: Report on AFMU repairs. Default: true. * `repair reports`: Report on AFMU repairs. Default: true.
* `road to riches`: Announce bodies worth scanning if you are looking for some * `road to riches`: Announce bodies worth scanning if you are looking for some
starting cash on the Road to Riches. Default: false. starting cash on the Road to Riches. Default: false.

View file

@ -13,7 +13,7 @@ For any ships that you regularly use for neutron jumping, e.g. long range Fuel
Rat ships, I recommend telling SpanshAttack about the range they are supposed to Rat ships, I recommend telling SpanshAttack about the range they are supposed to
have with full fuel and your preferred amount of cargo/limpets. have with full fuel and your preferred amount of cargo/limpets.
In oder to do that, copy the `SpanshAttack.getShipRange` command from In order to do that, copy the `SpanshAttack.getShipRange` command from
SpanshAttack or the example profile to your custom profile and add your ships. SpanshAttack or the example profile to your custom profile and add your ships.
Any ship listed in there will automatically have its jump range used instead of Any ship listed in there will automatically have its jump range used instead of
EDDIs reported laden range or VoiceAttack prompting you to manually supply it. EDDIs reported laden range or VoiceAttack prompting you to manually supply it.

View file

@ -7,8 +7,8 @@ configuration is stored in a bunch of VoiceAttack variables which in turn are
stored in your custom profile. You could even have different custom profiles stored in your custom profile. You could even have different custom profiles
with their own distinct settings. with their own distinct settings.
The easiest way to change setings is to say `customize settings`. That will The easiest way to change settings is to say `customize settings`. That will
bring up a rudminteary settings UI. bring up a rudimentary settings UI.
You change also change the configuration directly via voice commands: You change also change the configuration directly via voice commands:

View file

@ -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
@ -10,7 +10,7 @@ See [the configuration section](../configuration/general#settings).
* `paste text`: Pastes the contents of your current clipboard. Note that this * `paste text`: Pastes the contents of your current clipboard. Note that this
command is supposed to be used for pasting _into Elite_ and hence uses the command is supposed to be used for pasting _into Elite_ and hence uses the
configured paste key. If youre using a non-standard layout that means that configured paste key. If youre using a non-standard layout that means that
you can _not_ use this command to paste text into other applications. you _cannot_ use this command to paste text into other applications.
## Updating ## Updating

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View file

@ -8,9 +8,9 @@ Rats](https://fuelrats.com) and [Hull Seals](https://hullseals.space) work.
**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
Github](https://github.com/alterNERDtive/VoiceAttack-profiles/issues/113). This Github](https://github.com/alterNERDtive/VoiceAttack-profiles/issues/113). This
might or might not change after the Horizons/Odyssey merge when console release might or might not change after the Horizons/Odyssey merge. Feel free to file
is upon us. Feel free to file issues for anything that is broken on Odyssey and issues for anything that is broken on Odyssey and it will be worked on when it
it will be worked on when it is worked on. is worked on.
## Available Profiles ## Available Profiles
@ -31,10 +31,13 @@ Well, you are in the right place. You can find comprehensive documentation right
here. here.
If you run into any errors, please make sure you are running the latest version If you run into any errors, please make sure you are running the latest version
of the profiles and all requirements. of the profiles and all [requirements](requirements.md).
If your problem persists, please [file an If your problem persists, please [file an
issue](https://github.com/alterNERDtive/VoiceAttack-profiles/issues). Thanks! :) issue](https://github.com/alterNERDtive/VoiceAttack-profiles/issues). Thanks! :)
You can also [say “Hi” on Discord](https://discord.gg/kXtXm54) if that is your You can also [say “Hi” on Discord](https://discord.gg/kXtXm54) if that is your
thing. thing.
[![GitHub Sponsors](https://img.shields.io/github/sponsors/alterNERDtive?style=for-the-badge)](https://github.com/sponsors/alterNERDtive)
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/S6S1DLYBS)

View file

@ -7,9 +7,7 @@ version](https://voiceattack.com/#download-1) off the official site and install
it. it.
If you are using the standalone version you should probably download the If you are using the standalone version you should probably download the
executable installer. If you are using the Steam version of VoiceAttack, you executable installer.
will have to download the zipped folder and replace your installed version with
its contents.
![[VoiceAttack-download.png]] ![[VoiceAttack-download.png]]
@ -55,12 +53,12 @@ hit `Enter`) and do
``` ```
If you have installed the non-Steam version of VoiceAttack to the default folder If you have installed the non-Steam version of VoiceAttack to the default folder
within “ProgramFiles” you will have to run the command prompt as admin (Windows within “Program Files” you will have to run the command prompt as admin (Windows
key + `R`, enter “cmd”, hit `Control` + `Shift` + `Enter`). key + `R`, enter “cmd”, hit `Control` + `Shift` + `Enter`).
## Install ED-NeutronRouter ## Install ED-NeutronRouter
[Grab the latest release release from Grab [the latest release release from
Github](https://github.com/sc-pulgan/ED-NeutronRouter/releases/latest) (The Github](https://github.com/sc-pulgan/ED-NeutronRouter/releases/latest) (The
`EDNeutronRouter.vX.YZ.zip` under “Assets”). You will have to extract the `EDNeutronRouter.vX.YZ.zip` under “Assets”). You will have to extract the
contents of the release .zip file to your VoiceAttack Apps folder: contents of the release .zip file to your VoiceAttack Apps folder:
@ -99,7 +97,7 @@ the profiles that you want to change and add voice triggers or hotkeys.
You can either use an existing profile, create a new one or use the provided You can either use an existing profile, create a new one or use the provided
profile example as a basis. Regardless of which way you choose, make sure to profile example as a basis. Regardless of which way you choose, make sure to
read the [[#Include Profiles]] section and follow the instructions there! read the [Include Profiles](#include-profiles) section and follow the instructions there!
### Option 1: Create a New Profile Or Use an Existing One ### Option 1: Create a New Profile Or Use an Existing One
@ -123,7 +121,7 @@ will now have to create the startup command. Hit the “New Command” button.
![[VoiceAttack-edit-new-command.png]] ![[VoiceAttack-edit-new-command.png]]
You can name it anything you want but I recommend calling it “startup” or You can name it anything you want but I recommend calling it “startup” or
similar, and to deactivate the “when i say”checkbox in the command options to similar, and to deactivate the “when I say” checkbox in the command options to
make sure you do not accidentally run it via voice. make sure you do not accidentally run it via voice.
![[VoiceAttack-edit-startup.png]] ![[VoiceAttack-edit-startup.png]]
@ -148,7 +146,7 @@ action. You do not have to set any configuration options, this can be done way
more elegantly! More on this [later on](general.md#settings). more elegantly! More on this [later on](general.md#settings).
After adding the startup command you will have to right click VoiceAttacks After adding the startup command you will have to right click VoiceAttacks
title bar and choose “Reload Active Profile” or restart VoiceAttack to it title bar and choose “Reload Active Profile” or restart VoiceAttack to see it
executed for the first time. executed for the first time.
### Option 2: Use the Profile Example ### Option 2: Use the Profile Example
@ -185,8 +183,8 @@ button.
![[VoiceAttack-profile-options-include.png]] ![[VoiceAttack-profile-options-include.png]]
Add all my profiles (“alterNERDtive-base”, “EliteDangerous”, “RatAttack”, Add all my profiles (“alterNERDtive-base”, “EliteAttack”, “RatAttack”,
“SpanshAttack”,“StreamAttack”). “SpanshAttack”, “StreamAttack”).
![[VoiceAttack-profile-options-includelist.png]] ![[VoiceAttack-profile-options-includelist.png]]
@ -202,6 +200,14 @@ earlier.
![[VoiceAttack-profile-options-startup.png]] ![[VoiceAttack-profile-options-startup.png]]
## Reload the Profile
To make sure everything is loaded correctly, you now need to either reload the
profile by right clicking on VoiceAttacks title bar → “Reset Active Profile” or
by simply restarting VoiceAttack.
You should see a bunch of initialization messages pop up in the VoiceAttack log.
## Set Elite Keyboard Binds ## Set Elite Keyboard Binds
You need to have keyboard binds setup at least as secondary bindings in Elites You need to have keyboard binds setup at least as secondary bindings in Elites

View file

@ -1,68 +1,69 @@
# Requirements # Requirements
## VoiceAttack ## VoiceAttack
Obviously you will need to install [VoiceAttack](https://voiceattack.com). There Obviously you will need to install [VoiceAttack](https://voiceattack.com). There
is a free trial version available, but that one is limited to a single profile is a free trial version available, but that one is limited to a single profile
and a few commands. This is 5 profiles and … a lot of commands. You will need the and a few commands. This is 5 profiles and … a lot of commands. You will need the
full version, available for $10 (official site) or €11.99 (Steam, IIRC $14.99 full version, available for $10 (official site) or €11.99 (Steam, IIRC $14.99
for our US-based friends). for our US-based friends).
I recommend buying on the site. Why? Because on Steam, Valve gets a 30% cut. I recommend buying on the site. Why? Because on Steam, Valve gets a 30% cut.
Unlike many other developers Gary (the developer of VoiceAttack) remedies that Unlike many other developers Gary (the developer of VoiceAttack) remedies that
by having a price on Steam that ends up paying $10 to him. So basically, you are by having a price on Steam that ends up paying $10 to him. So basically, you are
paying Valve out of your own pocket. Many other developers do not do that, and paying Valve out of your own pocket. Many other developers do not do that, and
by buying from them directly instead of on Steam you are literally giving them by buying from them directly instead of on Steam you are literally giving them
extra money. Please do keep that in mind in the future! extra money. Please do keep that in mind in the future!
You also will generally need to opt into the beta version. I am usually at the You also will generally need to opt into the beta version. I am usually at the
forefront of bug reports and feature requests, and I do rely on the forefront of bug reports and feature requests, and I do rely on the
fixes/additions in beta versions quite often. fixes/additions in beta versions quite often.
## EDDI ## EDDI
[EDDI](https://github.com/EDCD/EDDI) is a companion application for Elite: [EDDI](https://github.com/EDCD/EDDI) is a companion application for Elite:
Dangerous, providing responses to events that occur in-game using data from the Dangerous, providing responses to events that occur in-game using data from the
game as well as various third-party tools. In this case, you will need to run it game as well as various third-party tools. In this case, you will need to run it
as a VoiceAttack plugin. as a VoiceAttack plugin.
EDDI also regularly publishes beta versions. Unless a profiles release EDDI also regularly publishes beta versions. Unless a profiles release
explicitly states it you will _not_ have to run EDDI beta. explicitly states it you will _not_ have to run EDDI beta.
Do note that the profiles put EDDI into quiet mode by default, disabling the Do note that the profiles put EDDI into quiet mode by default, disabling the
built-in speech responders. This can be changed built-in speech responders. This can be changed
[via the `EDDI quiet mode` setting](configuration/general.md#general-settings-for-all-profiles). [via the `EDDI quiet mode` setting](configuration/general.md#general-settings-for-all-profiles).
## bindED ## bindED
[bindED](https://alterNERDtive.github.io/bindED) reads your Elite Dangerous [bindED](https://alterNERDtive.github.io/bindED) reads your Elite Dangerous
binding files and makes them available to VoiceAttack as variables. That way binding files and makes them available to VoiceAttack as variables. That way
commands can be portable and you do not have to manually go through them and commands can be portable and you do not have to manually go through them and
change any actions that you happen to not have the standard binds for. change any actions that you happen to not have the standard binds for.
This plugin is _included_ in the release package. You do _not_ have to download This plugin is _included_ in the release package. You do _not_ have to download
and install it manually, but you _can_ independently update it if a newer and install it manually, but you _can_ independently update it if a newer
version is available. version is available.
## Elite Scripts ## Elite Scripts
I have written a [collection of Python I have written a [collection of Python
scripts](https://github.com/alterNERDtive/elite-scripts) to interface with scripts](https://github.com/alterNERDtive/elite-scripts) to interface with
various 3ʳᵈ party services like EDSM or Spansh. Those are called by the profiles various 3ʳᵈ party services like EDSM or Spansh. Those are called by the profiles
for various tasks, like checking a systems body count. for various tasks, like checking a systems body count.
In the future they will be replaced by VoiceAttack plugin code. In the future they will be replaced by VoiceAttack plugin code.
The scripts are _included_ in the release package. You do _not_ have to download The scripts are _included_ in the release package. You do _not_ have to download
and install them manually, but you _can_ independently update them if a newer and install them manually, but you _can_ independently update them if a newer
version is available. version is available.
## ED-NeutronRouter ## ED-NeutronRouter
(required for SpanshAttack) [ED-NeutronRouter](https://github.com/sc-pulgan/ED-NeutronRouter) interfaces
with [Spanshs neutron plotter](https://spansh.uk/plotter) and makes the result
[ED-NeutronRouter](https://github.com/sc-pulgan/ED-NeutronRouter) interfaces
with [Spanshs neutron plotter](https://spansh.uk/plotter) and makes the result
available to VoiceAttack. available to VoiceAttack.
This will also eventually be replaced by my own plugins. This plugin is _only_ required if you intend to use the SpanshAttack profile for
neutron routing. Otherwise you do not have to install it.
This will also eventually be replaced by my own plugins.

View file

@ -1,91 +1,100 @@
# Troubleshooting # Troubleshooting
This will fill up gradually with Troubleshooting tips as people run into common This will fill up gradually with Troubleshooting tips as people run into common
ones. ones.
## VoiceAttack does not understand me / mishears me / fires random commands ## VoiceAttack does not understand me / mishears me / fires random commands
There is [a thread on the VoiceAttack There is [a thread on the VoiceAttack
forums](https://forum.voiceattack.com/smf/index.php?topic=2667.msg12197#msg12197) forums](https://forum.voiceattack.com/smf/index.php?topic=2667.msg12197#msg12197)
on how to set up your microphone and the speech recognition engine to work best. on how to set up your microphone and the speech recognition engine to work best.
If your microphone is bad and you still get erroneous recognitions when you are If your microphone is bad and you still get erroneous recognitions when you are
not speaking it is probably going to recognize the same command every time. You not speaking it is probably going to recognize the same command every time. You
can remedy that by blocking the voice trigger. One-syllable triggers are can remedy that by blocking the voice trigger. One-syllable triggers are
especially prone to misrecognition. especially prone to misrecognition.
1. Create a new command in your custom profile. 1. Create a new command in your custom profile.
1. Set the “when I say” field to the trigger that gets misrecognized. 1. Set the “when I say” field to the trigger that gets misrecognized.
Adding the “Other” → “VoiceAttack Action” → “Ignore an Unrecognized Word or Adding the “Other” → “VoiceAttack Action” → “Ignore an Unrecognized Word or
Phrase” action will also hide it from the VoiceAttack log when it is (wrongly) Phrase” action will also hide it from the VoiceAttack log when it is (wrongly)
recognized. You might or might not want that. recognized. You might or might not want that.
Example for the “cruise” voice trigger of the Supercruise command: Example for the “cruise” voice trigger of the Supercruise command:
![[troubleshooting-remove-trigger.png]] ![[troubleshooting-remove-trigger.png]]
Alternatively you can raise the minimum confidence level and call the underlying Alternatively you can raise the minimum confidence level and call the underlying
command to make misfires less likely: command to make misfires less likely:
![[troubleshooting-raise-min-confidence.png]] ![[troubleshooting-raise-min-confidence.png]]
There are a few examples in the [Custom Profile There are a few examples in the [Custom Profile
Example](../installing#use-the-profile-example). Example](../installing#use-the-profile-example).
## VoiceAttack recognizes a command, but doesnt do anything in game ## VoiceAttack recognizes a command, but doesnt do anything in game
Make sure you have a keyboard bind for whatever the command is supposed to do as Make sure you have a keyboard bind for whatever the command is supposed to do as
outlined in [[Installing#Set Elite Keyboard Binds]]. outlined in [[Installing#Set Elite Keyboard Binds]].
## VoiceAttack talks over the COVAS voice ## VoiceAttack talks over the COVAS voice
There is no way to know for sure when the ingame COVAS is talking to you, so There is no way to know for sure when the ingame COVAS is talking to you, so
there is no way to always prevent the two from speaking over each other. there is no way to always prevent the two from speaking over each other.
You can however either disable TTS responses for events that you know will clash You can however either disable TTS responses for events that you know will clash
(or [file a feature (or [file a feature
request](https://github.com/alterNERDtive/VoiceAttack-profiles/issues/) if one request](https://github.com/alterNERDtive/VoiceAttack-profiles/issues/) if one
is not optional yet). Alternatively, if you prefer the info given by VoiceAttack is not optional yet). Alternatively, if you prefer the info given by VoiceAttack
over the ingame COVAS, you can deactivate its response to these events in the over the ingame COVAS, you can deactivate its response to these events in the
ingame Audo settings: ingame Audo settings:
![[Elite-COVAS.png]] ![[Elite-COVAS.png]]
While youre in there you might as well get rid of the spoken FSD countdown that While youre in there you might as well get rid of the spoken FSD countdown that
is off by one second … is off by one second …
## This doesnt work (well) with my HCS pack ## This doesnt work (well) with my HCS pack
My profiles are designed from the ground up to work with whatever else you are My profiles are designed from the ground up to work with whatever else you are
doing with VoiceAttack; that is the reason for importing them into your own doing with VoiceAttack; that is the reason for importing them into your own
custom profile instead of selecting e.g. `EliteAttack` as your active profile. custom profile instead of selecting e.g. `EliteAttack` as your active profile.
HCS on the contrary explicitly expects you do exclusively use HCS with HCS on the contrary explicitly expects you do exclusively use HCS with
VoiceAttack. There is the rudimentary way of including simple profiles into VoiceAttack. There is the rudimentary way of including simple profiles into
theirs, but the mechanism falls flat in many places. For example you cannot tell theirs, but the mechanism falls flat in many places. For example you cannot tell
HCS to run an included profiles startup command. HCS to run an included profiles startup command.
So, in order to mostly make stuff work, you need to treat the HCS profile as So, in order to mostly make stuff work, you need to treat the HCS profile as
your “custom” profile as per this documentation. your “custom” profile as per this documentation.
1. Include `alterNERDtive-base` and all profiles you want to use into the active 1. Include `alterNERDtive-base` and all profiles you want to use into the active
HCS profile. HCS profile.
1. Include a custom profile that has a startup command with a voice trigger of 1. Include a custom profile that has a startup command with a voice trigger of
your choosing, e.g. “load included profiles”. your choosing, e.g. “load included profiles”.
1. Set up said startup command as you would normally. 1. Set up said startup command as you would normally.
1. Every time you start VA or change profiles, you will have to manually say 1. Every time you start VA or change profiles, you will have to manually say
“load included profiles”. “load included profiles”.
That will make most things work. Conflicts may arise if HCS happens to have That will make most things work. Conflicts may arise if HCS happens to have
voice triggers that are the same as mine, in which case their command will take voice triggers that are the same as mine, in which case their command will take
priority. priority.
**Note on TTS**: EDDIs TTS (used by my profiles) and HCS TTS / recorded voice **Note on TTS**: EDDIs TTS (used by my profiles) and HCS TTS / recorded voice
lines act 100% independently. That means they will frequently “speak over each lines act 100% independently. That means they will frequently “speak over each
other”. There is no way to alleviate this. other”. There is no way to alleviate this.
EDDI does have a mechanism to detect if it is currently speaking it sets a EDDI does have a mechanism to detect if it is currently speaking it sets a
corresponding VoiceAttack variable. HCS neither does anything similar nor checks corresponding VoiceAttack variable. HCS neither does anything similar nor checks
if EDDI is speaking to prevent conflicts. Refer to them if you want that if EDDI is speaking to prevent conflicts. Refer to them if you want that
changed. changed.
## This does not work with Geforce Now
Nope. Just wont. Geforce Now obviously has Elites files, journals and keybinds
stored on some random PC in the cloud. Your local VoiceAttack has no way of
accessing those.
If you can get VoiceAttack to run _on Geforce Now_ in parallel to Elite, I dont
see why it wouldnt work.

View file

@ -49,6 +49,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "configuration", "configurat
docs\configuration\StreamAttack.md = docs\configuration\StreamAttack.md docs\configuration\StreamAttack.md = docs\configuration\StreamAttack.md
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{A68BA76B-47FA-4D25-805E-66EBDD8C5223}"
ProjectSection(SolutionItems) = preProject
.github\dependabot.yaml = .github\dependabot.yaml
.github\FUNDING.yml = .github\FUNDING.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{0147AF7E-BB7F-4D5F-96EC-8734393DFF56}"
ProjectSection(SolutionItems) = preProject
.github\workflows\create-release.yaml = .github\workflows\create-release.yaml
.github\workflows\gh-pages.yaml = .github\workflows\gh-pages.yaml
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -82,6 +94,8 @@ Global
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{5401ADF7-CB6D-448B-A4AC-D8A17B2D841F} = {C2B4D94B-8D73-431A-880B-B1E7ADF064B2} {5401ADF7-CB6D-448B-A4AC-D8A17B2D841F} = {C2B4D94B-8D73-431A-880B-B1E7ADF064B2}
{1AFD9AE6-7D22-4EF4-B0DE-51C9E91370FB} = {5401ADF7-CB6D-448B-A4AC-D8A17B2D841F} {1AFD9AE6-7D22-4EF4-B0DE-51C9E91370FB} = {5401ADF7-CB6D-448B-A4AC-D8A17B2D841F}
{A68BA76B-47FA-4D25-805E-66EBDD8C5223} = {C2B4D94B-8D73-431A-880B-B1E7ADF064B2}
{0147AF7E-BB7F-4D5F-96EC-8734393DFF56} = {A68BA76B-47FA-4D25-805E-66EBDD8C5223}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {339E6747-C7BF-43C3-99C6-9249C9849A84} SolutionGuid = {339E6747-C7BF-43C3-99C6-9249C9849A84}

View file

@ -30,7 +30,7 @@ namespace EliteAttack
/// </summary> /// </summary>
public class EliteAttack public class EliteAttack
{ {
private static readonly Version VERSION = new ("8.4"); private static readonly Version VERSION = new ("8.5");
private static VoiceAttackLog? log; private static VoiceAttackLog? log;
private static VoiceAttackCommands? commands; private static VoiceAttackCommands? commands;
@ -86,8 +86,6 @@ namespace EliteAttack
/// <param name="vaProxy">The VoiceAttack proxy object.</param> /// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy) public static void VA_Invoke1(dynamic vaProxy)
{ {
VA = vaProxy;
string context = vaProxy.Context.ToLower(); string context = vaProxy.Context.ToLower();
Log.Debug($"Running context '{context}' …"); Log.Debug($"Running context '{context}' …");
try try
@ -95,11 +93,11 @@ namespace EliteAttack
switch (context) switch (context)
{ {
case "startup": case "startup":
Context_Startup(); Context_Startup(vaProxy);
break; break;
case "log.log": case "log.log":
// log // log
Context_Log(); Context_Log(vaProxy);
break; break;
default: default:
// invalid // invalid
@ -140,10 +138,11 @@ namespace EliteAttack
| plugin contexts | | plugin contexts |
\================*/ \================*/
private static void Context_Log() #pragma warning disable IDE0060 // Remove unused parameter
private static void Context_Log(dynamic vaProxy)
{ {
string message = VA!.GetText("~message"); string message = vaProxy.GetText("~message");
string level = VA!.GetText("~level"); string level = vaProxy.GetText("~level");
if (level == null) if (level == null)
{ {
@ -166,10 +165,11 @@ namespace EliteAttack
} }
} }
private static void Context_Startup() private static void Context_Startup(dynamic vaProxy)
{ {
Log.Notice("Starting up …"); Log.Notice("Starting up …");
Log.Notice("Finished startup."); Log.Notice("Finished startup.");
} }
#pragma warning restore IDE0060 // Remove unused parameter
} }
} }

View file

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\EliteAttack.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
@ -29,6 +30,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\EliteAttack.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
@ -51,4 +53,4 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -1,4 +1,23 @@
using System.Reflection; // <copyright file="AssemblyInfo.cs" company="alterNERDtive">
// Copyright 20192022 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 &lt;https://www.gnu.org/licenses/&gt;.
// </copyright>
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View file

@ -1,4 +1,23 @@
using System.Reflection; // <copyright file="AssemblyInfo.cs" company="alterNERDtive">
// Copyright 20192022 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 &lt;https://www.gnu.org/licenses/&gt;.
// </copyright>
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View file

@ -25,6 +25,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\RatAttack-cli.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@ -34,6 +35,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\RatAttack-cli.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />

View file

@ -1,4 +1,23 @@
using System.Reflection; // <copyright file="AssemblyInfo.cs" company="alterNERDtive">
// Copyright 20192022 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 &lt;https://www.gnu.org/licenses/&gt;.
// </copyright>
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View file

@ -20,7 +20,7 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Concurrent;
using System.Diagnostics; using System.Diagnostics;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -33,16 +33,16 @@ namespace RatAttack
/// </summary> /// </summary>
public class RatAttack public class RatAttack
{ {
private static readonly Version VERSION = new ("6.3.1"); private static readonly Version VERSION = new ("6.4");
private static readonly Regex RatsignalRegex = new ( private static readonly Regex RatsignalRegex = new (
@"^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*$"); @"^RATSIGNAL Case #(?<number>\d+) (?<platform>(PC|Xbox|Playstation))( )?(?<mode>H3.8|H4.0|ODY)?(?<oxygen> \(Code Red\))? 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_\[\]\-\^]+))? \((H3|H4|ODY|XB|PS)_SIGNAL\)\v*$");
private static PipeServer<Ratsignal>? ratsignalPipe; private static PipeServer<Ratsignal>? ratsignalPipe;
private static VoiceAttackLog? log; private static VoiceAttackLog? log;
private static VoiceAttackCommands? commands; private static VoiceAttackCommands? commands;
private static Dictionary<int, RatCase> CaseList { get; } = new (); private static ConcurrentDictionary<int, RatCase> CaseList { get; } = new ();
private static dynamic? VA { get; set; } private static dynamic? VA { get; set; }
@ -102,8 +102,6 @@ namespace RatAttack
/// <param name="vaProxy">The VoiceAttack proxy object.</param> /// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy) public static void VA_Invoke1(dynamic vaProxy)
{ {
VA = vaProxy;
string context = vaProxy.Context.ToLower(); string context = vaProxy.Context.ToLower();
Log.Debug($"Running context '{context}' …"); Log.Debug($"Running context '{context}' …");
try try
@ -112,25 +110,25 @@ namespace RatAttack
{ {
case "getcasedata": case "getcasedata":
// plugin methods // plugin methods
Context_GetCaseData(); Context_GetCaseData(vaProxy);
break; break;
case "parseratsignal": case "parseratsignal":
Context_ParseRatsignal(); Context_ParseRatsignal(vaProxy);
break; break;
case "startup": case "startup":
Context_Startup(); Context_Startup(vaProxy);
break; break;
case "edsm.getnearestcmdr": case "edsm.getnearestcmdr":
// EDSM // EDSM
Context_EDSM_GetNearestCMDR(); Context_EDSM_GetNearestCMDR(vaProxy);
break; break;
case "log.log": case "log.log":
// log // log
Context_Log(); Context_Log(vaProxy);
break; break;
default: default:
// invalid // invalid
Log.Error($"Invalid plugin context '{VA!.Context}'."); Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
break; break;
} }
} }
@ -190,7 +188,7 @@ namespace RatAttack
string? permitName = match.Groups["permitName"].Value; string? permitName = match.Groups["permitName"].Value;
string platform = match.Groups["platform"].Value; string platform = match.Groups["platform"].Value;
bool codeRed = match.Groups["oxygen"].Success; bool codeRed = match.Groups["oxygen"].Success;
bool odyssey = match.Groups["odyssey"].Success; string? mode = match.Groups["mode"].Value;
int number = int.Parse(match.Groups["number"].Value); int number = int.Parse(match.Groups["number"].Value);
@ -199,9 +197,9 @@ namespace RatAttack
system = "None"; system = "None";
} }
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})."); Log.Debug($"New rat case: CMDR “{cmdr}” in “{system}”{(!string.IsNullOrEmpty(systemInfo) ? $" ({systemInfo})" : string.Empty)} on {platform}{(!string.IsNullOrEmpty(mode) ? $" ({mode})" : string.Empty)}, permit locked: {permitLocked}{(permitLocked && !string.IsNullOrEmpty(permitName) ? $" (permit name: {permitName})" : string.Empty)}, code red: {codeRed} (#{number}).");
CaseList[number] = new RatCase(cmdr, language, system, systemInfo, permitLocked, permitName, platform, odyssey, codeRed, number); CaseList[number] = new RatCase(cmdr, language, system, systemInfo, permitLocked, permitName, platform, mode, codeRed, number);
return number; return number;
} }
@ -232,10 +230,11 @@ namespace RatAttack
| plugin contexts | | plugin contexts |
\================*/ \================*/
private static void Context_EDSM_GetNearestCMDR() #pragma warning disable IDE0060 // Remove unused parameter
private static void Context_EDSM_GetNearestCMDR(dynamic vaProxy)
{ {
int caseNo = VA!.GetInt("~caseNo") ?? throw new ArgumentNullException("~caseNo"); int caseNo = vaProxy.GetInt("~caseNo") ?? throw new ArgumentNullException("~caseNo");
string cmdrList = VA!.GetText("~cmdrs") ?? throw new ArgumentNullException("~cmdrs"); string cmdrList = vaProxy.GetText("~cmdrs") ?? throw new ArgumentNullException("~cmdrs");
string[] cmdrs = cmdrList.Split(';'); string[] cmdrs = cmdrList.Split(';');
if (cmdrs.Length == 0) if (cmdrs.Length == 0)
{ {
@ -244,7 +243,7 @@ namespace RatAttack
string system = CaseList[caseNo]?.System ?? throw new ArgumentException($"Case #{caseNo} has no system information", "~caseNo"); string system = CaseList[caseNo]?.System ?? throw new ArgumentException($"Case #{caseNo} has no system information", "~caseNo");
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\edsm-getnearest.exe"; string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\edsm-getnearest.exe";
string arguments = $@"--short --text --system ""{system}"" ""{string.Join(@""" """, cmdrs)}"""; string arguments = $@"--short --text --system ""{system}"" ""{string.Join(@""" """, cmdrs)}""";
Process p = PythonProxy.SetupPythonScript(path, arguments); Process p = PythonProxy.SetupPythonScript(path, arguments);
@ -279,29 +278,29 @@ namespace RatAttack
break; break;
} }
VA!.SetText("~message", message); vaProxy.SetText("~message", message);
VA!.SetBoolean("~error", error); vaProxy.SetBoolean("~error", error);
VA!.SetText("~errorMessage", errorMessage); vaProxy.SetText("~errorMessage", errorMessage);
VA!.SetInt("~exitCode", p.ExitCode); vaProxy.SetInt("~exitCode", p.ExitCode);
} }
private static void Context_GetCaseData() private static void Context_GetCaseData(dynamic vaProxy)
{ {
int cn = VA!.GetInt("~caseNumber"); int cn = vaProxy.GetInt("~caseNumber");
if (CaseList.ContainsKey(cn)) if (CaseList.ContainsKey(cn))
{ {
RatCase rc = CaseList[cn]; RatCase rc = CaseList[cn];
VA!.SetInt("~~caseNumber", rc.Number); vaProxy.SetInt("~~caseNumber", rc.Number);
VA!.SetText("~~cmdr", rc.Cmdr); vaProxy.SetText("~~cmdr", rc.Cmdr);
VA!.SetText("~~system", rc?.System?.ToLower()); vaProxy.SetText("~~system", rc?.System?.ToLower());
VA!.SetText("~~systemInfo", rc?.SystemInfo); vaProxy.SetText("~~systemInfo", rc?.SystemInfo);
VA!.SetBoolean("~~permitLocked", rc?.PermitLocked); vaProxy.SetBoolean("~~permitLocked", rc?.PermitLocked);
VA!.SetText("~~permitName", rc?.PermitName); vaProxy.SetText("~~permitName", rc?.PermitName);
VA!.SetText("~~platform", rc?.Platform); vaProxy.SetText("~~platform", rc?.Platform);
VA!.SetBoolean("~~odyssey", rc?.Odyssey); vaProxy.SetText("~~mode", rc?.Mode);
VA!.SetBoolean("~~codeRed", rc?.CodeRed); vaProxy.SetBoolean("~~codeRed", rc?.CodeRed);
} }
else else
{ {
@ -309,10 +308,10 @@ namespace RatAttack
} }
} }
private static void Context_Log() private static void Context_Log(dynamic vaProxy)
{ {
string message = VA!.GetText("~message"); string message = vaProxy.GetText("~message");
string level = VA!.GetText("~level"); string level = vaProxy.GetText("~level");
if (level == null) if (level == null)
{ {
@ -335,18 +334,19 @@ namespace RatAttack
} }
} }
private static void Context_Startup() private static void Context_Startup(dynamic vaProxy)
{ {
Log.Notice("Starting up …"); Log.Notice("Starting up …");
_ = RatsignalPipe.Run(); _ = RatsignalPipe.Run();
Log.Notice("Finished startup."); Log.Notice("Finished startup.");
} }
private static void Context_ParseRatsignal() private static void Context_ParseRatsignal(dynamic vaProxy)
{ {
Log.Warn("Passing a RATSIGNAL to VoiceAttack through the clipboard or a file is DEPRECATED and will no longer be supported in the future."); 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"))); On_Ratsignal(new Ratsignal(vaProxy.GetText("~ratsignal"), vaProxy.GetBoolean("~announceRatsignal") ?? false));
} }
#pragma warning restore IDE0060 // Remove unused parameter
/// <summary> /// <summary>
/// Encapsulates a RATSIGNAL for sending between the CLI helper tool and /// Encapsulates a RATSIGNAL for sending between the CLI helper tool and
@ -409,9 +409,9 @@ namespace RatAttack
private class RatCase 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) public RatCase(string cmdr, string? language, string? system, string? systemInfo, bool permitLocked, string? permitName, string platform, string mode, bool codeRed, int number)
=> (this.Cmdr, this.Language, this.System, this.SystemInfo, this.PermitLocked, this.PermitName, this.Platform, this.Odyssey, this.CodeRed, this.Number) => (this.Cmdr, this.Language, this.System, this.SystemInfo, this.PermitLocked, this.PermitName, this.Platform, this.Mode, this.CodeRed, this.Number)
= (cmdr, language, system, systemInfo, permitLocked, permitName, platform, odyssey, codeRed, number); = (cmdr, language, system, systemInfo, permitLocked, permitName, platform, mode, codeRed, number);
public string Cmdr { get; } public string Cmdr { get; }
@ -427,7 +427,7 @@ namespace RatAttack
public string Platform { get; } public string Platform { get; }
public bool Odyssey { get; } public string? Mode { get; }
public bool CodeRed { get; } public bool CodeRed { get; }
@ -435,7 +435,7 @@ namespace RatAttack
public string ShortInfo 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)}"; get => $"#{this.Number}, {this.Platform}{(!string.IsNullOrEmpty(this.Mode) ? $" ({this.Mode})" : string.Empty)}{(this.CodeRed ? ", code red" : string.Empty)}, {this.System ?? "None"}{(!string.IsNullOrEmpty(this.SystemInfo) ? $" ({this.SystemInfo}{(this.PermitLocked ? ", permit required" : string.Empty)})" : string.Empty)}";
} }
public override string ToString() public override string ToString()

View file

@ -25,6 +25,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\RatAttack.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
@ -33,6 +34,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\RatAttack.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
@ -57,4 +59,4 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -1,4 +1,23 @@
using System.Reflection; // <copyright file="AssemblyInfo.cs" company="alterNERDtive">
// Copyright 20192022 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 &lt;https://www.gnu.org/licenses/&gt;.
// </copyright>
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;

View file

@ -89,8 +89,6 @@ namespace SpanshAttack
/// <param name="vaProxy">The VoiceAttack proxy object.</param> /// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy) public static void VA_Invoke1(dynamic vaProxy)
{ {
VA = vaProxy;
string context = vaProxy.Context.ToLower(); string context = vaProxy.Context.ToLower();
Log.Debug($"Running context '{context}' …"); Log.Debug($"Running context '{context}' …");
try try
@ -98,26 +96,26 @@ namespace SpanshAttack
switch (context) switch (context)
{ {
case "startup": case "startup":
Context_Startup(); Context_Startup(vaProxy);
break; break;
case "edts.getcoordinates": case "edts.getcoordinates":
// EDTS // EDTS
Context_EDTS_GetCoordinates(); Context_EDTS_GetCoordinates(vaProxy);
break; break;
case "log.log": case "log.log":
// log // log
Context_Log(); Context_Log(vaProxy);
break; break;
case "spansh.systemexists": case "spansh.systemexists":
// Spansh // Spansh
Context_Spansh_SytemExists(); Context_Spansh_SytemExists(vaProxy);
break; break;
case "spansh.nearestsystem": case "spansh.nearestsystem":
Context_Spansh_Nearestsystem(); Context_Spansh_Nearestsystem(vaProxy);
break; break;
default: default:
// invalid // invalid
Log.Error($"Invalid plugin context '{VA!.Context}'."); Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
break; break;
} }
} }
@ -154,9 +152,10 @@ namespace SpanshAttack
| plugin contexts | | plugin contexts |
\================*/ \================*/
private static void Context_EDTS_GetCoordinates() #pragma warning disable IDE0060 // Remove unused parameter
private static void Context_EDTS_GetCoordinates(dynamic vaProxy)
{ {
string name = VA!.GetText("~system") ?? throw new ArgumentNullException("~system"); string name = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
bool success = false; bool success = false;
string? errorType = null; string? errorType = null;
@ -175,10 +174,10 @@ 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");
} }
VA!.SetInt("~x", system.Coords.X); vaProxy.SetInt("~x", system.Coords.X);
VA!.SetInt("~y", system.Coords.Y); vaProxy.SetInt("~y", system.Coords.Y);
VA!.SetInt("~z", system.Coords.Z); vaProxy.SetInt("~z", system.Coords.Z);
VA!.SetInt("~precision", system.Coords.Precision); vaProxy.SetInt("~precision", system.Coords.Precision);
success = true; success = true;
} }
@ -193,19 +192,19 @@ namespace SpanshAttack
errorMessage = e.Message; errorMessage = e.Message;
} }
VA!.SetBoolean("~success", success); vaProxy.SetBoolean("~success", success);
if (!string.IsNullOrWhiteSpace(errorType)) if (!string.IsNullOrWhiteSpace(errorType))
{ {
Log.Error(errorMessage!); Log.Error(errorMessage!);
VA!.SetText("~errorType", errorType); vaProxy.SetText("~errorType", errorType);
VA!.SetText("~errorMessage", errorMessage); vaProxy.SetText("~errorMessage", errorMessage);
} }
} }
private static void Context_Log() private static void Context_Log(dynamic vaProxy)
{ {
string message = VA!.GetText("~message"); string message = vaProxy.GetText("~message");
string level = VA!.GetText("~level"); string level = vaProxy.GetText("~level");
if (level == null) if (level == null)
{ {
@ -228,13 +227,13 @@ namespace SpanshAttack
} }
} }
private static void Context_Spansh_Nearestsystem() private static void Context_Spansh_Nearestsystem(dynamic vaProxy)
{ {
int x = VA!.GetInt("~x") ?? throw new ArgumentNullException("~x"); int x = vaProxy.GetInt("~x") ?? throw new ArgumentNullException("~x");
int y = VA!.GetInt("~y") ?? throw new ArgumentNullException("~y"); int y = vaProxy.GetInt("~y") ?? throw new ArgumentNullException("~y");
int z = VA!.GetInt("~z") ?? throw new ArgumentNullException("~z"); int z = vaProxy.GetInt("~z") ?? throw new ArgumentNullException("~z");
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe"; string path = $@"{vaProxy.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);
@ -273,21 +272,21 @@ namespace SpanshAttack
break; break;
} }
VA!.SetText("~system", system); vaProxy.SetText("~system", system);
VA!.SetDecimal("~x", coords['x']); vaProxy.SetDecimal("~x", coords['x']);
VA!.SetDecimal("~y", coords['y']); vaProxy.SetDecimal("~y", coords['y']);
VA!.SetDecimal("~z", coords['z']); vaProxy.SetDecimal("~z", coords['z']);
VA!.SetDecimal("~distance", distance); vaProxy.SetDecimal("~distance", distance);
VA!.SetBoolean("~error", error); vaProxy.SetBoolean("~error", error);
VA!.SetText("~errorMessage", errorMessage); vaProxy.SetText("~errorMessage", errorMessage);
VA!.SetInt("~exitCode", p.ExitCode); vaProxy.SetInt("~exitCode", p.ExitCode);
} }
private static void Context_Spansh_SytemExists() private static void Context_Spansh_SytemExists(dynamic vaProxy)
{ {
string system = VA!.GetText("~system") ?? throw new ArgumentNullException("~system"); string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe"; string path = $@"{vaProxy.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);
@ -321,16 +320,17 @@ namespace SpanshAttack
break; break;
} }
VA!.SetBoolean("~systemExists", exists); vaProxy.SetBoolean("~systemExists", exists);
VA!.SetBoolean("~error", error); vaProxy.SetBoolean("~error", error);
VA!.SetText("~errorMessage", errorMessage); vaProxy.SetText("~errorMessage", errorMessage);
VA!.SetInt("~exitCode", p.ExitCode); vaProxy.SetInt("~exitCode", p.ExitCode);
} }
private static void Context_Startup() private static void Context_Startup(dynamic vaProxy)
{ {
Log.Notice("Starting up …"); Log.Notice("Starting up …");
Log.Notice("Finished startup."); Log.Notice("Finished startup.");
} }
#pragma warning restore IDE0060 // Remove unused parameter
} }
} }

View file

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\SpanshAttack.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@ -29,6 +30,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\SpanshAttack.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
@ -51,4 +53,4 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -1,10 +1,28 @@
// This file is used by Code Analysis to maintain SuppressMessage // <copyright file="GlobalSuppressions.cs" company="alterNERDtive">
// attributes that are applied to this project. // Copyright 20192022 alterNERDtive.
// Project-level suppressions either have no target or are given //
// a specific target and scoped to a namespace, type, member, etc. // 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 &lt;https://www.gnu.org/licenses/&gt;.
// </copyright>
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
// 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.
[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")]
[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.edts")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "just cause", Scope = "namespace", Target = "~N:alterNERDtive.util")] [assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "just cause", Scope = "namespace", Target = "~N:alterNERDtive.util")]

View file

@ -1,4 +1,23 @@
using System.Reflection; // <copyright file="AssemblyInfo.cs" company="alterNERDtive">
// Copyright 20192022 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 &lt;https://www.gnu.org/licenses/&gt;.
// </copyright>
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -10,7 +29,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VoiceAttack-base")] [assembly: AssemblyProduct("VoiceAttack-base")]
[assembly: AssemblyCopyright("Copyright © 2020")] [assembly: AssemblyCopyright("Copyright © 20202022")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]

View file

@ -17,6 +17,8 @@
// along with alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see &lt;https://www.gnu.org/licenses/&gt;. // along with alterNERDtive VoiceAttack profiles for Elite Dangerous. If not, see &lt;https://www.gnu.org/licenses/&gt;.
// </copyright> // </copyright>
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows; using System.Windows;
@ -56,7 +58,7 @@ namespace alterNERDtive
tab.IsEnabled = BasePlugin.IsProfileActive(profile); tab.IsEnabled = BasePlugin.IsProfileActive(profile);
StackPanel panel = new StackPanel(); StackPanel panel = new StackPanel();
util.Configuration.OptDict<string, util.Configuration.Option> options = config.GetOptions(profile); util.Configuration.OptDict<string, util.Configuration.Option> options = util.Configuration.GetOptions(profile);
foreach (dynamic option in options.Values) foreach (dynamic option in options.Values)
{ {
@ -105,7 +107,7 @@ namespace alterNERDtive
foreach (Setting setting in this.values) foreach (Setting setting in this.values)
{ {
dynamic state = null; dynamic? state = null;
try try
{ {

View file

@ -24,6 +24,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\base.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
@ -32,25 +33,19 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\base.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" /> <Reference Include="System.Numerics" />
<Reference Include="System.Xaml" /> <Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
</ItemGroup> </ItemGroup>
@ -66,14 +61,22 @@
</Compile> </Compile>
<Compile Include="util.cs" /> <Compile Include="util.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Page Include="SettingsDialog.xaml"> <Page Include="SettingsDialog.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client">
<Version>5.2.9</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="System.Net.Http">
<Version>4.3.4</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -39,7 +39,7 @@ namespace alterNERDtive
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "F off :)")] [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 readonly Version VERSION = new ("4.4"); private static readonly Version VERSION = new ("4.5");
private static readonly Dictionary<Guid, string> Profiles = new () private static readonly Dictionary<Guid, string> Profiles = new ()
{ {
@ -119,8 +119,6 @@ namespace alterNERDtive
/// <param name="vaProxy">The VoiceAttack proxy object.</param> /// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy) public static void VA_Invoke1(dynamic vaProxy)
{ {
VA = vaProxy;
string context = vaProxy.Context.ToLower(); string context = vaProxy.Context.ToLower();
Log.Debug($"Running context '{context}' …"); Log.Debug($"Running context '{context}' …");
try try
@ -128,49 +126,49 @@ namespace alterNERDtive
switch (context) switch (context)
{ {
case "startup": case "startup":
Context_Startup(); Context_Startup(vaProxy);
break; break;
case "config.dialog": case "config.dialog":
// config // config
Context_Config_Dialog(); Context_Config_Dialog(vaProxy);
break; break;
case "config.dump": case "config.dump":
Context_Config_Dump(); Context_Config_Dump(vaProxy);
break; break;
case "config.getvariables": case "config.getvariables":
Context_Config_SetVariables(); Context_Config_SetVariables(vaProxy);
break; break;
case "config.list": case "config.list":
Context_Config_List(); Context_Config_List(vaProxy);
break; break;
case "config.setup": case "config.setup":
Context_Config_Setup(); Context_Config_Setup(vaProxy);
break; break;
case "config.versionmigration": case "config.versionmigration":
Context_Config_VersionMigration(); Context_Config_VersionMigration(vaProxy);
break; break;
case "edsm.bodycount": case "edsm.bodycount":
// EDSM // EDSM
Context_EDSM_BodyCount(); Context_EDSM_BodyCount(vaProxy);
break; break;
case "edsm.distancebetween": case "edsm.distancebetween":
Context_EDSM_DistanceBetween(); Context_EDSM_DistanceBetween(vaProxy);
break; break;
case "eddi.event": case "eddi.event":
// EDDI // EDDI
Context_Eddi_Event(); Context_Eddi_Event(vaProxy);
break; break;
case "spansh.outdatedstations": case "spansh.outdatedstations":
// Spansh // Spansh
Context_Spansh_OutdatedStations(); Context_Spansh_OutdatedStations(vaProxy);
break; break;
case "log.log": case "log.log":
// log // log
Context_Log(); Context_Log(vaProxy);
break; break;
case "update.check": case "update.check":
// update // update
Context_Update_Check(); Context_Update_Check(vaProxy);
break; break;
default: default:
// invalid // invalid
@ -248,7 +246,7 @@ namespace alterNERDtive
string name = match.Groups["name"].Value; string name = match.Groups["name"].Value;
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 = Configuration.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.
@ -328,7 +326,8 @@ namespace alterNERDtive
| plugin contexts | | plugin contexts |
\================*/ \================*/
private static void Context_Config_Dialog() #pragma warning disable IDE0060 // Remove unused parameter
private static void Context_Config_Dialog(dynamic vaProxy)
{ {
Thread dialogThread = new Thread(new ThreadStart(() => Thread dialogThread = new Thread(new ThreadStart(() =>
{ {
@ -348,17 +347,17 @@ namespace alterNERDtive
dialogThread.Start(); dialogThread.Start();
} }
private static void Context_Config_Dump() private static void Context_Config_Dump(dynamic vaProxy)
{ {
Config.DumpConfig(); Config.DumpConfig();
} }
private static void Context_Config_List() private static void Context_Config_List(dynamic vaProxy)
{ {
Config.ListConfig(); Config.ListConfig();
} }
private static void Context_Config_Setup() private static void Context_Config_Setup(dynamic vaProxy)
{ {
Log.Debug("Loading default configuration …"); Log.Debug("Loading default configuration …");
Config.ApplyAllDefaults(); Config.ApplyAllDefaults();
@ -371,14 +370,14 @@ namespace alterNERDtive
Log.Debug("Finished loading configuration."); Log.Debug("Finished loading configuration.");
} }
private static void Context_Config_SetVariables() private static void Context_Config_SetVariables(dynamic vaProxy)
{ {
string trigger = VA!.GetText("~trigger") ?? throw new ArgumentNullException("~trigger"); string trigger = vaProxy.GetText("~trigger") ?? throw new ArgumentNullException("~trigger");
Log.Debug($"Loading variables for trigger '{trigger}' …"); Log.Debug($"Loading variables for trigger '{trigger}' …");
Config.SetVariablesForTrigger(VA!, trigger); Config.SetVariablesForTrigger(vaProxy, trigger);
} }
private static void Context_Config_VersionMigration() private static void Context_Config_VersionMigration(dynamic vaProxy)
{ {
// ============= // =============
// === 4.3.1 === // === 4.3.1 ===
@ -390,7 +389,7 @@ namespace alterNERDtive
string name = $"EliteAttack.{option}s#"; string name = $"EliteAttack.{option}s#";
string oldName = $"EliteAttack.{option}#"; string oldName = $"EliteAttack.{option}#";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } }); Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } });
bool? value = VA!.GetBoolean(oldName); bool? value = vaProxy.GetBoolean(oldName);
if (value != null) if (value != null)
{ {
Log.Info($"Migrating option {oldName} …"); Log.Info($"Migrating option {oldName} …");
@ -404,7 +403,7 @@ namespace alterNERDtive
// =========== // ===========
// SpanshAttack // SpanshAttack
string edtsPath = $@"{VA!.SessionState["VA_SOUNDS"]}\scripts\edts.exe"; string edtsPath = $@"{vaProxy.SessionState["VA_SOUNDS"]}\scripts\edts.exe";
if (File.Exists(edtsPath)) if (File.Exists(edtsPath))
{ {
File.Delete(edtsPath); File.Delete(edtsPath);
@ -422,7 +421,7 @@ namespace alterNERDtive
string name = $"{prefix}.{option}"; string name = $"{prefix}.{option}";
string oldName = $"{oldPrefix}.{option}"; string oldName = $"{oldPrefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } }); Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } });
bool? value = VA!.GetBoolean(oldName); bool? value = vaProxy.GetBoolean(oldName);
if (value != null) if (value != null)
{ {
Log.Info($"Migrating option {oldName} …"); Log.Info($"Migrating option {oldName} …");
@ -437,7 +436,7 @@ namespace alterNERDtive
{ {
string name = $"{prefix}.{option}"; string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } }); Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
bool? value = VA!.GetBoolean(name); bool? value = vaProxy.GetBoolean(name);
if (value != null) if (value != null)
{ {
Log.Info($"Migrating option {name} …"); Log.Info($"Migrating option {name} …");
@ -450,7 +449,7 @@ namespace alterNERDtive
{ {
string name = $"{prefix}.{option}"; string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } }); Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
string value = VA!.GetText(name); string value = vaProxy.GetText(name);
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {
Log.Info($"Migrating option {name} …"); Log.Info($"Migrating option {name} …");
@ -465,7 +464,7 @@ namespace alterNERDtive
{ {
string name = $"{prefix}.{option}"; string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } }); Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
bool? value = VA!.GetBoolean(name); bool? value = vaProxy.GetBoolean(name);
if (value != null) if (value != null)
{ {
Log.Info($"Migrating option {name} …"); Log.Info($"Migrating option {name} …");
@ -478,7 +477,7 @@ namespace alterNERDtive
{ {
string name = $"{prefix}.{option}"; string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } }); Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
string value = VA!.GetText(name); string value = vaProxy.GetText(name);
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {
Log.Info($"Migrating option {name} …"); Log.Info($"Migrating option {name} …");
@ -493,7 +492,7 @@ namespace alterNERDtive
{ {
string name = $"{prefix}.{option}"; string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } }); Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
string value = VA!.GetText(name); string value = vaProxy.GetText(name);
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {
Log.Info($"Migrating option {name} …"); Log.Info($"Migrating option {name} …");
@ -503,19 +502,19 @@ namespace alterNERDtive
} }
} }
private static void Context_Eddi_Event() private static void Context_Eddi_Event(dynamic vaProxy)
{ {
string eddiEvent = VA!.Command.Name(); string eddiEvent = vaProxy.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() private static void Context_EDSM_BodyCount(dynamic vaProxy)
{ {
string system = VA!.GetText("~system") ?? throw new ArgumentNullException("~system"); string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\scripts\explorationtools.exe"; string path = $@"{vaProxy.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);
@ -551,19 +550,19 @@ namespace alterNERDtive
break; break;
} }
VA!.SetInt("~bodyCount", bodyCount); vaProxy.SetInt("~bodyCount", bodyCount);
VA!.SetBoolean("~error", error); vaProxy.SetBoolean("~error", error);
VA!.SetText("~errorMessage", errorMessage); vaProxy.SetText("~errorMessage", errorMessage);
VA!.SetInt("~exitCode", p.ExitCode); vaProxy.SetInt("~exitCode", p.ExitCode);
} }
private static void Context_EDSM_DistanceBetween() private static void Context_EDSM_DistanceBetween(dynamic vaProxy)
{ {
string fromSystem = VA!.GetText("~fromSystem") ?? throw new ArgumentNullException("~fromSystem"); string fromSystem = vaProxy.GetText("~fromSystem") ?? throw new ArgumentNullException("~fromSystem");
string toSystem = VA!.GetText("~toSystem") ?? throw new ArgumentNullException("~toSystem"); string toSystem = vaProxy.GetText("~toSystem") ?? throw new ArgumentNullException("~toSystem");
int roundTo = VA!.GetInt("~roundTo") ?? 2; int roundTo = vaProxy.GetInt("~roundTo") ?? 2;
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\explorationtools.exe"; string path = $@"{vaProxy.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);
@ -595,16 +594,16 @@ namespace alterNERDtive
break; break;
} }
VA!.SetDecimal("~distance", distance); vaProxy.SetDecimal("~distance", distance);
VA!.SetBoolean("~error", error); vaProxy.SetBoolean("~error", error);
VA!.SetText("~errorMessage", errorMessage); vaProxy.SetText("~errorMessage", errorMessage);
VA!.SetInt("~exitCode", p.ExitCode); vaProxy.SetInt("~exitCode", p.ExitCode);
} }
private static void Context_Log() private static void Context_Log(dynamic vaProxy)
{ {
string message = VA!.GetText("~message"); string message = vaProxy.GetText("~message");
string level = VA!.GetText("~level"); string level = vaProxy.GetText("~level");
if (level == null) if (level == null)
{ {
@ -627,13 +626,14 @@ namespace alterNERDtive
} }
} }
private static void Context_Spansh_OutdatedStations() private static void Context_Spansh_OutdatedStations(dynamic vaProxy)
{ {
string system = VA!.GetText("~system") ?? throw new ArgumentNullException("~system"); string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
int minage = VA!.GetInt("~minage") ?? throw new ArgumentNullException("~minage"); int minage = vaProxy.GetInt("~minage") ?? throw new ArgumentNullException("~minage");
bool includeSettlements = vaProxy.GetBoolean("~includeSettlements") ?? throw new ArgumentNullException("~includeSettlements");
string path = $@"{VA!.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe"; string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
string arguments = $@"oldstations --system ""{system}"" --minage {minage}"; string arguments = $@"oldstations --system ""{system}"" --minage {minage}{(includeSettlements ? string.Empty : " --nofeet")}";
Process p = PythonProxy.SetupPythonScript(path, arguments); Process p = PythonProxy.SetupPythonScript(path, arguments);
@ -667,24 +667,25 @@ namespace alterNERDtive
break; break;
} }
VA!.SetText("~message", message); vaProxy.SetText("~message", message);
VA!.SetBoolean("~error", error); vaProxy.SetBoolean("~error", error);
VA!.SetText("~errorMessage", errorMessage); vaProxy.SetText("~errorMessage", errorMessage);
VA!.SetInt("~exitCode", p.ExitCode); vaProxy.SetInt("~exitCode", p.ExitCode);
} }
private static void Context_Startup() private static void Context_Startup(dynamic vaProxy)
{ {
Log.Notice("Starting up …"); Log.Notice("Starting up …");
CheckProfiles(VA); CheckProfiles(vaProxy);
Log.Notice($"Active profiles: {string.Join(", ", ActiveProfiles)}"); Log.Notice($"Active profiles: {string.Join(", ", ActiveProfiles)}");
Commands.TriggerEventAll(ActiveProfiles, "startup", logMissing: false); Commands.TriggerEventAll(ActiveProfiles, "startup", logMissing: false);
Log.Notice("Finished startup."); Log.Notice("Finished startup.");
} }
private static void Context_Update_Check() private static void Context_Update_Check(dynamic vaProxy)
{ {
UpdateCheck(); UpdateCheck();
} }
#pragma warning restore IDE0060 // Remove unused parameter
} }
} }

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net48" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net48" />
</packages>

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

1
requirements.txt Normal file
View file

@ -0,0 +1 @@
mkdocs-roamlinks-plugin