Compare commits

...

617 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
99305cfb5d 4.4! 2022-05-31 19:23:00 +02:00
bc5addd22a base: removed delays.keyPressDuration option since that isn’t actually used rn 2022-05-30 23:38:21 +02:00
64a096dae7 StyleCop compliance, round 2 of 3 … 2022-05-30 23:22:48 +02:00
33a4fb8e3d base: made config GUI buttons wider 2022-05-30 21:59:52 +02:00
3cbca1e542 base: config GUI now .Activate()s immediately 2022-05-30 21:58:46 +02:00
55a031686c auto draft a release on tag push 2022-05-30 21:28:09 +02:00
02a401a047 housekeeping 2022-05-30 21:25:08 +02:00
e36358be9f stylecop compliance, round 1 2022-05-29 22:16:17 +02:00
999d2b6883 alterNERDtive-base: configuration GUI now has an “Apply” button 2022-05-29 21:32:43 +02:00
e73b8c04f9 bump to c# 10 because why not 2022-05-29 21:14:54 +02:00
931ee4c4e7 RatAttack: added warning when running VA as Admin
fixes #138
2022-05-29 11:13:49 +02:00
751f80461f RatAttack-cli: added error message for running VA as Admin
see #138

Writing to other users’ pipes will cause an exception. You should not run VA elevated.

Needs a warning in VA too.
2022-05-29 10:51:51 +02:00
c9d39f6cc7 docs: typos 2022-05-28 15:09:00 +02:00
f8dd1ff464 docs: added upgrading EDDI event handlers to upgrading.md 2022-05-28 15:05:08 +02:00
f7328e31e2 bumped VERSION
I feel like I should do that whenever I bump it in base.cs …
2022-05-28 14:27:44 +02:00
2b0d2245e2 RatAttack: fixed superfluous “ly” output in distance to commands
fixes #140
2022-05-28 14:19:35 +02:00
dc42912cbe EliteAttack: fixed auto station services option
fixes #142
2022-05-28 14:19:08 +02:00
b3ad1ae799 switched for make to msbuild
Build file still private, since it relies on my local folder structure.
2022-05-27 20:20:41 +02:00
5421478d6e SpanshAttack: fixed getting current jump range from EDDI
Not waiting for the plugin context to finish running caused it to pretty consistently fail on the first attempt, and return the last value for attempts after that.
2022-05-22 12:49:06 +02:00
d771d0b403 docs: fixed weird character in general.md 2022-05-22 12:46:50 +02:00
b371523910 EliteAttack: added options from #133 i forgot
* auto retract landing gear
* auto disable SRV lights

fixes #133
2022-05-19 13:16:00 +02:00
8572d0ec4c CHANGELOG: typo 2022-05-19 12:54:22 +02:00
c00c1d9bbe Merge branch 'devel' into release 2022-05-19 12:49:30 +02:00
0c0cf068c4 4.3! 2022-05-19 12:46:31 +02:00
42faaa20d5 SpanshAttack: no longer pretends there’s a route if there isn’t
fixes #104
2022-05-19 12:40:38 +02:00
da9a6f6107 SpanshAttack: moved jumps announcement to end of jump instead of start
fixes #124
2022-05-19 12:19:47 +02:00
a5b22a8908 EliteAttack: workaround for bugged Body scanned EDDI events
fixes #121
2022-05-19 12:13:26 +02:00
20599fef88 EliteAttack: added logging to find nearest […] command
fixes #96
2022-05-19 12:08:00 +02:00
99438b4ed3 RatAttack: no longer sliently swallows calls if confirmation is disabled
fixes #128
2022-05-19 12:00:53 +02:00
368b7ca771 alterNERDtive-base: no longer cuts off EDDI’s “update available” TTS on startup
fixes #120
2022-05-19 11:58:47 +02:00
5442738a21 RatAttack: clarified call confirmation TTS
fixes #101

Also clarified that there _is_ call confirmation in the documentation.
2022-05-19 11:55:02 +02:00
d6cd7da11c docs: reordered setup instructions to clarify that the profile example already comes with a startup command
fixes #126
2022-05-19 11:48:44 +02:00
2f4015001f docs: clarified not having to install bundled dependencies manually
fixes #127
2022-05-19 11:44:08 +02:00
81b83bba2d docs: now mentions reloading the custom profile after initially adding its startup command
fixes #129
2022-05-19 11:41:48 +02:00
2544be701c RatAttack: added option for auto copying a client’s system on opening a case
Also updated the documentation to mention copying happens in the first place; fixes #130
2022-05-19 11:39:09 +02:00
9a8d7b646f CHANGELOG: forgot to add last fix 2022-05-19 11:33:05 +02:00
999650e84f docs: added HCS compatibility bit to troubleshooting.md
fixes #132
2022-05-19 11:31:23 +02:00
f69e3c03bd EliteAttack: make all docking actions optional
fixes #133
2022-05-19 11:18:52 +02:00
e81f3961ea alterNERDtive-base: fixed settings dialog closing prematurely 2022-05-18 13:55:35 +02:00
8a3b17d674 added rudimentary settings UI
Accessible by plugin context `config.dialog` or saying `customize settings`.

fixes #80
2022-05-18 13:50:14 +02:00
d038c58595 RatAttack: accounting for . in the lang part of a RATSIGNAL 2022-04-19 11:45:56 +02:00
08aaa3db8a RatAttack: fixed edge case with off duty + nearest CMDR
No longer announces the nearest CMDR if that option is turned off while
also being off duty alltogether. There was a missing condition there …
2022-04-18 13:36:30 +02:00
7cad49a6c2 general: added open documentation command 2022-04-18 12:48:31 +02:00
2997b8335c docs: added EDDI quiet mode info to requirements.md 2022-03-04 15:25:28 +01:00
5bf21a48ba docs: added tidbit about galaxy map vs. interface bindings conflict 2021-09-29 10:26:27 +02:00
28854968fd RatAttack: now gives feedback after asking for call confirmation 2021-09-18 14:26:14 +02:00
00923f3da5 EliteAttack: now throttling down on FSD engage, too 2021-09-18 14:23:42 +02:00
fa4e9535ba EliteAttack: added INFO logging for carrier events 2021-09-11 16:38:30 +02:00
302fd9f512 docs: mild un-doxxing 2021-08-26 15:05:39 +02:00
0e757eaf76 Merge branch 'devel' of https://github.com/alterNERDtive/VoiceAttack-profiles into devel 2021-08-26 14:59:34 +02:00
7bc58f19ef docs: fixed some typos/inconsistencies/mistakerinos 2021-08-26 14:51:11 +02:00
4836273007 RatAttack: allow , in lang strings 2021-07-19 19:45:16 +02:00
adcb01bead docs: added link to CHANGELOG on Github 2021-07-04 21:00:57 +02:00
61e7f00c1f RatAttack: fixed “Not Set” case number when asking for details about an invalid case 2021-07-04 03:58:02 +02:00
a57daf35a7 CHANGELOG: typo corrected 2021-06-23 09:45:02 +02:00
e12bb8a2ea docs: added disclaimer on Oddity development 2021-06-23 09:12:11 +02:00
f00fd22234 docs: update installation instructions 2021-06-23 09:06:17 +02:00
2715fa2a48 RatAttack: fixed RATSIGNAL parsing for system information containing /
e.g. “Herbig AE/BE star”
2021-06-18 11:37:05 +02:00
36abf8b53b sorted out the utf-8 crap 2021-06-14 11:50:15 +02:00
bcbde1dd47 mkdocs: mark external links 2021-06-14 11:24:41 +02:00
ec87397a92 .editorconfig: default to utf-8 2021-06-14 11:21:46 +02:00
4483945f6a SpanshAttack: OBOE on last jump
Introduced when I switched to announcing jumps on FSD engage. Or rather side effect of correcting the OBOE in the Spansh plugin + that change.
2021-06-14 09:12:17 +02:00
3261c11d70 docs: removed the 32/64 bit thing
VoiceAttack is now 64bit by default, if anyone insists on running the 32bit one they can sort it out for themselves :)
2021-06-14 09:10:24 +02:00
7c1c75ec98 RatAttack: turns out there can be & in a lang identifier 2021-06-01 20:51:20 +02:00
f6b5621bb2 docs: typo 2021-05-27 12:32:42 +02:00
a1ddb987e0 RatAttack: No longer trying to get nearest CMDR for the new “Unconfirmed” system info. 2021-05-26 17:17:15 +02:00
3c46b20a23 Merge branch 'devel' into release 2021-05-23 20:36:24 +02:00
b633d8791c 4.2.3! 2021-05-23 20:32:41 +02:00
a5a3740799 updated .editorconfig 2021-05-23 20:28:45 +02:00
1d6ee3953e updated .editorconfig 2021-05-23 20:26:54 +02:00
d47ea2597c 4.2.2! 2021-05-19 17:45:29 +02:00
42488b3bcf RatAttack: slightly changed case announcements 2021-05-19 17:44:21 +02:00
25a7440c7b CHANGELOG: bindED 4.0 tidbit 2021-05-19 12:41:34 +02:00
254ada7318 Preemptively changed VERSION before I forget it again … 2021-05-19 10:02:04 +02:00
aed4609ed8 RatAttack: fixed code red detection
… broke with the reworked case announcement.

fixes #115
2021-05-19 09:54:40 +02:00
1991e6b5f6 RatAttack: correctly handles "" system now
Still not sure if a completely empty system (happens on manual RATSIGNAL) is intentional; but I’m handling it gracefully now, defaulting to “None”.
2021-05-19 09:53:31 +02:00
b30074317f RatAttack: support for Odyssey
Due to split instancing between Horizons and Odyssey the RATSIGNAL announcement now contains extra info on that.

fixes #114
2021-05-19 09:51:00 +02:00
3b9031ae59 forgot to bump VERSION … 2021-05-03 10:39:32 +02:00
2d8b923d0e 4.2.1! 2021-05-03 10:30:48 +02:00
c546c22bc4 CHANGELOG: clarified not-fixed #105 2021-05-03 10:28:13 +02:00
387f17db1d docs: temporarily disabled pdf 2021-05-03 10:17:15 +02:00
ef86f0a517 docs: reworded the 32/64-bit section of INSTALLING 2021-05-03 09:16:18 +02:00
2411514643 spring cleaning 2021-05-02 16:17:29 +02:00
7aaf8d62b1 RatAttack: implemented new RATSIGNAL format
… also now stripping IRC formatting for my own sanity’s sake

fixes #111
2021-05-02 16:09:52 +02:00
68716bb45b EliteAttack: fixed on-demand outdated station check invocation
fixes #108
2021-04-27 17:38:52 +02:00
9705bba899 RatAttack: RATSIGNAL parsing fixed for landmarks with alternate name 2021-04-05 15:51:19 +02:00
2cda77edda RatAttack: RATSIGNAL parsing fixed for proc gen landmarks 2021-04-05 15:37:35 +02:00
ffad1ffa28 RatAttack: fixed “unknown system” in RATSIGNAL 2021-04-03 21:39:50 +02:00
0c592af8e2 EliteAttack: don’t honk after a hyperdiction
fixes #105
2021-03-18 22:41:27 +01:00
9745e1ccb1 base: no longer warn on missing init command 2021-03-15 18:38:09 +01:00
4fcca54ff0 EliteAttack: fixed variable names in the gear/scoop/hardpoints command 2021-03-12 22:32:03 +01:00
71615e366c RatAttack: fixed language string parsing for numbers 2021-03-10 19:57:37 +01:00
26dd98f050 docs: note on mIRC and hex for IRC setup 2021-03-10 13:36:42 +01:00
fd0e07ecfa RatAttack: removed TTS&logging from invalid signals, for real this time 2021-03-10 13:31:43 +01:00
eda735a426 4.2! 2021-03-09 20:13:19 +01:00
4495d9ead2 RatAttack: amended regex for special character in language strings 2021-03-09 20:09:25 +01:00
1904dd6d41 RatAttack: various RATSIGNAL regex fixes
* numbers in IRC nick
* proper detection of language, pervented IRC nick from being found in the first place
* fix to cardinal direction estimation detection
2021-03-08 21:25:28 +01:00
a5b0d175a2 EliteAttack: "limpet check" configuration option 2021-03-08 20:38:50 +01:00
b2f8ec96d6 RatAttack: fixed RATSIGNAL parsing for “cardinal direction” addition to distance estimates for proc gen systems. 2021-03-08 19:37:28 +01:00
7511d59641 RatAttack: added distance to latest rat case command
… also fixed some dumb bug in the other distance commands.
2021-03-07 22:04:00 +01:00
e4ea1abb5e docs: typo 2021-03-04 23:27:46 +01:00
5e94677048 docs: note about no VA update checking in the Steam version 2021-03-04 23:22:53 +01:00
99dfc2cf09 docs: fixed misspelt/dead link 2021-03-04 23:18:11 +01:00
9ce06804f4 README: explicitly mentioned installation guide in the docs 2021-03-04 23:11:07 +01:00
4fba3ef79b RatAttack: Fixed RATSIGNAL parsing for new wording of injected cases with no system given. 2021-02-24 19:08:15 +01:00
2d6c96fce0 SpanshAttack: moved EDTS stuff to plugin code
see #62
2021-02-22 21:28:53 +01:00
fdccb3a4ff RatAttack: Fixed RATSIGNAL parsing for “Sagittarius A*” landmark. 2021-02-21 07:13:44 +01:00
5d429d463a 4.1! 2021-02-19 23:14:14 +01:00
b4f26f33c8 RatAttack: latest rat case details command 2021-02-19 23:11:54 +01:00
bc902310f8 EliteAttack: AFMU repairs & Synthesis repairs
see #86
2021-02-18 12:06:06 +01:00
eee768896b RatAttack: attempt at narrowing down the Regex
Too lenient systemInfo part was gobbling up the permit stuff; might be fixed now, hopefully …
2021-02-18 01:04:15 +01:00
4c3b890120 RatAttack: Updated RATSIGNAL parsing for new nick announcement
see 1686fced33
2021-02-17 13:24:44 +01:00
d210779967 SpanshAttack: fixed summary for doing 0j 2021-02-16 21:47:03 +01:00
14092bf174 RatAttack: removed “Valid system name” thing from the regex
Mecha now gives an estimation based on the sector name!
2021-02-16 12:08:44 +01:00
c47c26482c RatAttack: narrowed down sys name regex for landmark
Seems to not cause issues so far ;)
2021-02-16 12:07:32 +01:00
6cd7722db1 RatAttack: fixerinoed the colour thing for invalid systems in a RATSGINAL line 2021-02-14 01:34:13 +01:00
72633273e1 RatAttack: updated RATSIGNAL parsing for “Invalid system name” and colouration 2021-02-12 22:28:02 +01:00
dc216dade8 EliteAttack: fixed Material Threshold event logging 2021-02-12 18:42:50 +01:00
62b94b000e SpanshAttack: added actual jump count
fixes #82
2021-02-12 14:51:30 +01:00
4bd6ccc7a7 SpanshAttack: skip [this;current] neutron waypoint command
Skips the next neutron waypoint.

fixes #94
2021-02-12 14:40:36 +01:00
bd94f2e0f8 RatAttack: now makes use of Mecha’s system info
* announces it with an incoming case
* no longer looks up your nearest CMDR if the system is neither in Mecha’s galaxy database nor a potentially valid system name (fixes #89)
2021-02-12 13:46:31 +01:00
0d0fdc58a8 CHANGELOG: format fix, added line between early versions 2021-02-12 12:07:43 +01:00
f2ca6dd0ad CHANGELOG: fixed RatAttack version typo 2021-02-12 11:39:30 +01:00
fa645fc369 EliteAttack: new config option “route jump count”
Give a jump count on plotting a route.
2021-02-12 11:38:17 +01:00
f0a006a113 docs: fixed borked link 2021-02-12 11:15:16 +01:00
ec7f6798eb RatAttack: call jumps [left;] command 2021-02-12 05:37:05 +01:00
4affcb85ff EliteAttack: how many jumps left command 2021-02-12 05:20:04 +01:00
27dbffbe79 EliteAttack: restricted outdated stations check to inhabited systems again 2021-02-09 13:27:19 +01:00
205f90870b RatAttack: Updated RATSIGNAL parsing to correctly handle new format for landmark systems. 2021-02-08 18:56:47 +01:00
d512b5edbc RatAttack: removed TTS from invalid RATSIGNAL trigger 2021-02-08 18:28:53 +01:00
9c1406c08b docs: RatAttack links back to IRC settings now 2021-02-04 19:08:33 +01:00
c7cbaec218 4.0.2! 2021-02-04 06:13:56 +01:00
7c7a6b8718 RatAttack: RATSIGNAL parsing fixed for latest changes
fixes #93
2021-02-03 23:54:28 +01:00
0e350ccc3d docs: added troubleshooting stuff
Also removed the “VoiceAttack Tips” section for now, empty anyway and probably redundant.
2021-01-31 15:26:30 +01:00
32f43660fd docs: slightly more inclusive upgrading instructions 2021-01-30 18:52:35 +01:00
e1b42b8c0c 4.0.1! 2021-01-30 18:48:08 +01:00
dcd58e1d23 SpanshAttack: fixed not getting next waypoint correctly 2021-01-30 18:42:45 +01:00
1106aafffe CHANGELOG: link fixed 2021-01-30 14:37:48 +01:00
fe3c84b4f2 docs: typo 2021-01-30 12:52:47 +01:00
7669290a65 docs: fixed to EliteAttack.md 2021-01-29 19:04:00 +01:00
94a5429818 docs: moved CHANGELOG link to the UPGRADING section 2021-01-29 19:03:42 +01:00
9495117a4a docs: added recognition issues to troubleshooting.md 2021-01-29 17:22:05 +01:00
78f6f955e3 4.0! 2021-01-29 14:58:26 +01:00
788b8a9d7b RatAttack: made code reds more prominent in the VA log. 2021-01-28 15:42:16 +01:00
13e812e310 SpanshAttack: moved logic from Jumped to FSD engaged
Now pulling/announcing the next neutron waypoint at the start of a jump instead of at the end.
2021-01-28 15:41:58 +01:00
c0875cde48 EliteAttack: moved logic from Jumped to FSD engaged
Getting the EDSM body count and outdated stations will now happen on
engaging FSD instead of finishing the jump.

With the increased latency on the EDSM API I’m seeing lately this was
very much needed to get the body count in time for the discovery scan
after the jump.

fixes #85
2021-01-28 15:30:21 +01:00
c2e30eb9da docs: another round of fixerinos 2021-01-28 02:37:49 +01:00
8c80a4389c EliteAttack: fixed TTS for trying to log out while in danger 2021-01-27 14:45:03 +01:00
58b4860a58 docs: proof reading, round 1 2021-01-25 17:56:21 +01:00
a355af016d docs: DONE! 2021-01-25 14:34:14 +01:00
ddc5bd9bcb MOAR DOCS (we’re getting there :D) 2021-01-25 12:04:28 +01:00
53d6472e01 alterNERDtive-base: fixed reload elite key binds command 2021-01-25 12:02:20 +01:00
e6766e67a8 RatAttack-cli: case-insenstive flag parameter 2021-01-25 11:01:36 +01:00
6731dfd44e alterNERDtive-base: re-implemented auto update check 2021-01-25 10:44:57 +01:00
8330e181db docs: upgrading & general settings 2021-01-25 01:09:46 +01:00
d3d668f65b RatAttack: added Mecha-provided system info to VA log 2021-01-23 19:18:11 +01:00
b8d811bca3 RatAttack: more RATSIGNAL fixes for Mecha3 changes 2021-01-21 23:04:25 +01:00
cc9b382d72 docs: added version warning 2021-01-21 16:25:27 +01:00
4befa49fe2 merged origin/devel 2021-01-21 15:45:49 +01:00
580abc8300 first round of new documentation! 2021-01-21 15:42:00 +01:00
da81ae5985 preliminary CHANGELOG 2021-01-21 15:32:05 +01:00
2bdab1a4c7 alterNERDtive-base: added open [docs;documentation;help] file command 2021-01-21 15:30:59 +01:00
a3cef9d365 alterNERDtive-base: added open [docs;documentation;help] command 2021-01-21 14:58:42 +01:00
6f6fb9219b removed file logging, because TRACEing apparently doesn’t work properly everywhere 2021-01-20 12:31:13 +01:00
a3bd10f4ae added mkdocs 2021-01-20 12:29:15 +01:00
abd3b07e60 EliteAttack: fixed Material threshold event 2021-01-20 11:35:33 +01:00
f153d3aa75 RatAttack: RATSIGNAL no longer has not in databes info 2021-01-20 11:32:32 +01:00
526730902f RatAttack: RATSIGNALs now have system names in quotes … 2021-01-19 23:16:04 +01:00
2306beb801 SpanshAttack: typon in token 2021-01-18 10:16:18 +01:00
4bab6a13e8 POG 2021-01-17 23:52:05 +01:00
1fb6d57cce SpanshAttack: print calculated jumps to VoiceAttack log 2021-01-17 19:13:47 +01:00
327be7a5c4 build prep 2021-01-16 14:09:39 +01:00
8d7ff42a48 CHANGELOG mistake 2021-01-16 11:02:13 +01:00
1a3846896a Merge branch 'plugin-rewrite' into devel 2021-01-16 11:00:25 +01:00
08ea88fbb9 alterNERDtive-base: update mechanism
Reverted to semi-manual aprroach.

fixes #65
2021-01-16 09:29:52 +01:00
22505515d3 alterNERDtive-base: changed some voice triggers 2021-01-16 04:30:47 +01:00
525e777913 alterNERDtive-base: added config.list plugin context
… and voice commands for listing both available settings (`… list [options;settings]`) and dumping them (`… report [options;settings]`).
2021-01-16 03:56:58 +01:00
ffa7ebcf5d alterNERDtive-base: revised config voice triggers, added descriptions 2021-01-16 03:39:40 +01:00
21a7e8cf50 now using type hint’s for EDDI’s {P("thing")} 2021-01-16 01:15:00 +01:00
2586d438b3 alterNERDtive-base: fixed race condition
Need to wait for the VA command to return when loading config variables from the profile.
2021-01-08 16:46:10 +01:00
44806fee9a 3.2.1! 2021-01-02 20:41:39 +01:00
faa38b194b RatAttack: backported RATSIGNAL regex fix 2021-01-02 18:53:42 +01:00
7cb429455c RatAttack: oh look, RATSIGNAL format changed. Again.
This time “Case #X” got delimited by ^B / \x02. Cool.
2021-01-02 18:27:22 +01:00
49ed63b421 removed deprecated VERSION file 2020-12-31 01:38:58 +01:00
55e008108a 3.2.0! 2020-12-31 01:34:18 +01:00
49ca50589a changed update command in preparation for 4.0 2020-12-31 01:28:20 +01:00
55b2ce9f6b RatAttack: backported Mecha3 permit colour change 2020-12-31 01:20:16 +01:00
0e199f88dc RatAttack: permit stuff in RATSIGNALS has been changed from red to orange … 2020-12-31 01:06:30 +01:00
ad55954f65 RatAttack: killed Settings stuff that has been accidentally generated at some point … 2020-12-29 19:19:32 +01:00
3e5430431f RatAttack: added constraints for “platforms” config option 2020-12-29 19:16:07 +01:00
4c75dbd236 Reworked logging.
No more cross-logging, using Trace for file logging.
2020-12-29 19:08:14 +01:00
6186d24096 EliteAttack: added “auto honk all systems” option 2020-12-29 13:21:15 +01:00
afc49ed7e5 alterNERDtive-base: fixed active profiles list, added “installed” list 2020-12-29 13:18:18 +01:00
4d4f22e216 EliteAttack: made scanner fire group configurable 2020-12-26 01:13:26 +01:00
7d104a2be2 EliteAttack: added options to auto honking
You can now a) disable auto honking new systems and b) set the discovery scanner to primary fire.
2020-12-25 18:23:51 +01:00
87610b1bbd EliteAttack: made EDDI discovery scan use command queue for TTS
Should fix ordering issues with the 2 TTS parts.
2020-12-25 15:44:38 +01:00
6f51333bd4 RatAttack: changed RATSIGNAL separator from | to \x02
Apparently `|` are valid in CMDR names. So now we’re using a proper separator character instead.
2020-12-19 13:26:04 +01:00
a9a1a84aa7 alterNERDtive-base: removd Python.scriptPath config
Scripts aren’t being called from VoiceAttack commands anymore.
2020-12-10 20:20:40 +01:00
0569a90aa3 SpanshAttack: added plugin, moved script execution there 2020-12-10 20:11:53 +01:00
dc71f21fe4 Moved all but SpanshAttack from having the profile invoke the Python scripts to the plugin wrapper. 2020-12-09 21:19:47 +01:00
aea70224da RatAttack: updated RATSIGNAL regex to the latest Mecha changes
Platform `PS` changed to `Playstation`.

In before it changes to `PlayStation` next week.
2020-12-09 21:01:36 +01:00
c1dcbb0817 removed VoiceAttack logging from all EDDI event handlers
If you want to see them, set DEBUG log level.

see #77
2020-12-09 00:40:54 +01:00
82c1cc065e misc profile fixes 2020-12-09 00:15:44 +01:00
03bfc512fc alterNERDtive-base: made startup command more robust
If you somehow prevented the active profile from resetting (e.g. by hitting the edit button while the startup command was still running) you’d get the config loaded flag to stick around, causing profile change/reload to not reset options anymore.

The flag is now a profile-scoped (`>>`) variable to prevent that. There are still some corner cases left, but resetting the profile should always work.
2020-12-08 12:12:13 +01:00
9d8eedd581 alterNERDtive-base: added some parameter checking for contexts that didn’t have it 2020-12-08 12:05:37 +01:00
69b097d7c3 alterNERDtive-base: added base plugin to profiles list
E.g. allows to have specific event handlers in the base profile.

Also fixed missing GUID in the base profile … that would have been a bummer if it made it to release.
2020-12-08 11:44:29 +01:00
c5eb93dd0e alterNERDtive-base: config options now strongly typed with generics 2020-12-08 11:21:58 +01:00
9637975bdb alterNERDtive-base: fixed config change handling 2020-12-08 09:20:37 +01:00
afee22cf62 alterNERDtive-base: moved loglevel setting from context to config option 2020-12-07 21:45:17 +01:00
e8134e240d alterNERDtive-base: fixed non-string config settings commands 2020-12-07 20:56:40 +01:00
e9ea4a2576 hid the log entries for lots of events
* top level `((EDDI <event>))` commands
* profile events (including `((<profile>.startup))`)

see #77
2020-12-07 20:47:07 +01:00
cd4390c9ef alterNERDtive-base: added active profile list logging to startup context 2020-12-07 20:38:49 +01:00
d15fae9197 EliteAttack: migrated to new config
Also changed names `EliteDangerous` -> `EliteAttack`
2020-12-07 20:25:24 +01:00
4bb10e28f5 chaged <profile>.startup to ((<profile>.startup)) 2020-12-07 18:15:49 +01:00
dac75b7af3 added custom profile example 2020-12-07 18:11:12 +01:00
e179fef0d1 SpanshAttack: migrated to new config 2020-12-07 18:09:26 +01:00
f6a4861a06 alterNERDtive-base: added config.dump plugin context
Dumps a list of all configuration options + their current value to the VoiceAttack log. Will also mention if they are set to the default.
2020-12-07 16:29:07 +01:00
58435a350e StreamAttack: fixed distance calculation commands 2020-12-07 14:27:57 +01:00
9baa3a1be4 added wrapper command for EDDI speech responders 2020-12-05 20:18:22 +01:00
ed0c9449c7 alterNERDtive-base: fixed config only being loaded on _initial_ startup 2020-12-04 17:48:32 +01:00
146653bdeb alterNERDtive-base: prevented variable load/save from showing in the log
see #77
2020-12-04 17:42:51 +01:00
c2d5655703 RatAttack: added support for manually injected cases, missing the system
fixes #76
2020-12-03 17:07:37 +01:00
977b0c74d7 Did you know VoiceAttack doesn’t like capitalization in strings? 2020-12-03 16:02:40 +01:00
c17355229f StreamAttack: moved to new config 2020-12-03 13:49:10 +01:00
e5183a6d5f upped version numbers 2020-12-03 02:15:11 +01:00
8bf6135482 alternNERDtive-base: upgraded config migration to INFO 2020-12-03 02:10:55 +01:00
1a5ae485b6 RatAttack: migrated to new configuration 2020-12-03 02:05:16 +01:00
ba0021c3bd alterNERDtive-base: plugin context namespacing 2020-12-03 00:51:51 +01:00
7f79af826f alterNERDtive-base: now also automatically loading config from profile 2020-12-02 20:28:09 +01:00
606f651eb6 alterNERDtive-base: plugin now fully supports the new configuration approach 2020-12-02 19:08:46 +01:00
ca52c39da3 replaced string.equals() with == for consistency 2020-12-02 11:19:37 +01:00
22f6365f60 RatAttack: made RATSIGNAL regex readonly, as it should be 2020-12-02 11:08:10 +01:00
c7c99995d4 RatAttack: extended commands for up to 30 cases 2020-12-01 09:37:31 +01:00
0a3cc4cf3e EliteAttack: added [where's;where is] my landing pad command 2020-12-01 09:36:47 +01:00
10cd0c8811 EliteDangerous: removed outdated IRC nick stuff from the docs
fixes #74
2020-11-29 12:17:37 +01:00
c7404c2563 README: updated bindED bit
fixes #75
2020-11-29 12:15:27 +01:00
01c162c459 RatAttack: fixed case list for >20 cases …
It’s one of these days when you look at your code and you are like “WTF was I thinking?!”.
2020-11-23 20:52:44 +01:00
d9199d0dee README: updated link to bindED 2020-11-22 19:15:09 +01:00
72af5a3683 added GPL license 2020-11-18 17:16:48 +01:00
b09dc47f5c RatAttack: changed platform PS4 to PS to match latest Mecha3 changes 2020-11-18 17:16:36 +01:00
2585a5a4b3 EliteAttack: removed manual cooldown event on carrier jump cancel
EDDI now handles that in the latest beta, so no need to manually fiddle.
2020-11-10 09:25:23 +01:00
77ecc1a2d9 base: added generate missing key binds report command 2020-11-09 10:16:54 +01:00
9f326c88ad base: removed explicit bindED invocation from startup 2020-11-09 08:30:35 +01:00
957caa9780 3.1.3! 2020-11-06 13:19:07 +01:00
caa432859c StreamAttack: jump target now takes Spansh plot target if set 2020-11-03 01:55:31 +01:00
3419aeb44b util: fixed hard-coded pipe name 2020-10-25 20:26:02 +01:00
288f3f3678 RatAttack: backported latest regex changes 2020-10-25 20:20:19 +01:00
a96a3c9d87 RatAttack: Oh look! RSIG announcement format changed again! 2020-10-25 20:18:34 +01:00
12d946f036 RatAttack-cli: fixed timeout, added TimeoutException handling 2020-10-25 12:39:34 +01:00
a63b6f7a87 RatAttack: fixed permit announcement in the VA profile 2020-10-25 00:32:37 +02:00
1d63f58097 RatAttack: fixed setting ~permitName for VoiceAttack 2020-10-24 19:23:54 +02:00
006bbcac3b base: fixed error handling for the distancebetween context 2020-10-24 16:28:24 +02:00
cd9437c59d RatAttack: permit announcements 2020-10-23 17:38:53 +02:00
92eee3f1e7 RatAttack: more backported fixes:
* System names will now be `ToLower()`ed since Mecha3 capitalizes them and EDDI
  likes spelling those out instead of saying the names. Makes them a little
  messy in other ways, but less annoying overall.
* Permit detection part of the RATSIGNAL RegEx fixed for named permits.
* `XB` platform changed to `Xbox` to match Mecha3.
2020-10-23 01:40:31 +02:00
a23dd5816f StreamAttack: fixed missing jumpTarget distance output 2020-10-23 01:26:36 +02:00
6633af6060 RatAttack: added new VA Event ((RatAttack.invalidRatsignal))
Fires when a signal doesn’t match the current RegEx. By default warns with TTS and writes the signal to `%appdata%\RatAttack\ratsignal.error.log`.
2020-10-23 00:05:26 +02:00
e14512f076 RatAttack: apparently Mecha3 also has permit NAMES. 2020-10-22 23:45:27 +02:00
4b29cd9d0e 3.1.2! 2020-10-22 20:29:34 +02:00
1dedb8b2d1 RatAttack: fixed Mecha3 RATSIGNAL RegEx, now for all new stuff 2020-10-22 20:27:23 +02:00
d9f940c7bc RatAttack: apparently the XB platform is now Xbox 2020-10-21 23:26:51 +02:00
5623d47aa9 RatAttack: formatting changes 2020-10-21 20:59:31 +02:00
f1f78e69ce RatAttack: more Mecha3 fixes
I’ve heard there have been a couple other misc changes, reflected now. Also added `PermitLocked` Property to the cases.
2020-10-21 20:32:15 +02:00
77e727bb9c RatAttack: more corner case regex adjustment, and PS4 colour fix 2020-10-21 18:47:38 +02:00
67d4c45102 RatAttack: fixed & refined RATSIGNAL regex, added debug logging 2020-10-21 17:11:41 +02:00
adcec42dbd log missing .startup commands
-> profile is present, but not loaded/included
2020-10-21 16:14:59 +02:00
48593fce9d Let’s not get crazy with the indentations, shall we? 2020-10-21 15:08:34 +02:00
126f736a40 3.1.1! 2020-10-21 12:37:43 +02:00
cb62c3b5f5 RatAttack: backported RATSIGNAL parsing for Mecha3
fixes #67
2020-10-21 12:36:07 +02:00
e0b7631eac RatAttack: updated RATSIGNAL parsing for Mecha3 2020-10-21 12:14:06 +02:00
0196a2aaf2 cleaned up some of the projects/solutions mess 2020-10-21 10:25:17 +02:00
c955fe05d6 initial messy plugin rewrite commit 2020-10-21 01:19:34 +02:00
646658648d EliteDangerous: station check now with station count if outdated found 2020-08-23 01:34:36 +02:00
810024b854 EliteDangerous: fixed mission outdated station TTS 2020-08-23 01:33:21 +02:00
f4a05e2974 EliteDangerous: fixed [find;target] nearest […] 2020-08-18 23:54:23 +02:00
2b79b5e738 3.1! 2020-08-18 00:18:20 +02:00
9d91d124f1 EliteDangerous: extra words for what’s left to map
fixes #54
2020-08-17 18:26:39 +02:00
4554a4f789 EliteDangerous: moved R2R announcements to Jumped
fixes #61
2020-08-17 18:22:58 +02:00
98dddc90c8 added some missing command descriptions 2020-08-16 05:19:51 +02:00
db4b481996 EliteDangerous: limited target nearest command to 1 search
… at a time. Also added some feedback TTS.

fixes #59
2020-08-15 19:17:26 +02:00
75ecc022d1 EliteDangerous: Discovery scan event more reslient
properly realizes now if EDSM has been slow to respond and body count
hasn’t been pulled for the current system yet.

see comment on #61
2020-08-15 19:02:39 +02:00
73763b3090 EliteDangerous: added find nearest command variation
fixes #55
2020-08-14 11:24:04 +02:00
e806a31480 EliteDangerous: update check now logs current version
… even when no update was found.

fixes #58
2020-08-14 11:11:34 +02:00
90a28eb2be SpanshAttack: added TTS feedback for route plotting
Also fixed copypasta error of last change …
2020-08-13 11:48:27 +02:00
0cc46b1bbf SpanshAttack: get next waypoint on jumpin instead of supercharge event 2020-08-13 00:39:17 +02:00
7b99d9cf73 EliteDangerous: added carrier cooldown event after jump cancel 2020-08-10 23:53:02 +02:00
0db67c44cd SpanshAttack: docs typo 2020-08-10 01:24:23 +02:00
2cb9379b17 SpanshAttack: fixed plotting to systems not in the DB
fixes #53
2020-08-09 20:59:13 +02:00
ef01f6b09f EliteDangerous: changed update check logging behaviour
Now always logs, and logs the command you need to invoke to update, in
case you missed it in the TTS.
2020-08-04 20:33:51 +02:00
02705d5e1a EliteDangerous: added open profiles change log command 2020-08-03 13:00:11 +02:00
e07826be4c 3.0! 2020-08-03 12:38:49 +02:00
05b1b111c3 docs: fixed some double spaces at line endings … 2020-08-01 00:06:35 +02:00
2dd74ec19e RatAttack: not deprecating the pipe file for now
Passing parameters to VoiceAttack through the command line is not thread
safe. For RATSIGNALS coming in in rapid succession (either because,
well, several cases at once or when using an IRC bouncer, like I do) it
completely messes up the data.

see #51
2020-07-31 21:56:31 +02:00
dc263686e2 removed excess quotes from [enable;disable] logging output 2020-07-31 21:30:08 +02:00
c224c25a82 RatAttack: fixed log output for pipe file, ; was causing issues 2020-07-31 21:19:11 +02:00
8450b5b3e2 EliteDangerous: fixed open voiceattack import folder if it doesn’t exist yet 2020-07-31 20:14:20 +02:00
1dfc93c426 fixed logging prefixes. no longer using {PROFILE} 2020-07-31 19:55:16 +02:00
e146127b00 workaround for VA bug for commands with same name, but different IDs
see #52
2020-07-31 19:39:37 +02:00
a434f78a32 EliteDangerous: slightly restructured the docs 2020-07-31 19:11:09 +02:00
2879854070 implmented proper logging 2020-07-31 19:01:50 +02:00
a991f71091 EliteDangerous: clarified profile update log messages 2020-07-31 17:48:30 +02:00
7c9f6c41b6 RatAttack: deprecated passing RATSIGNALs through the pipe file
see #51
2020-07-31 08:32:26 +02:00
7efb48b4a0 EliteDangerous: added .enableAutoUpdateCheck config variable 2020-07-31 08:28:13 +02:00
a3821a8c69 Fixed TTS handling for systems containing '.
fixes #49
2020-07-31 07:27:32 +02:00
de21754069 New and improved and automated updates! 2020-07-31 07:03:31 +02:00
4d58bba1f4 Merge branch 'release' into devel 2020-07-31 06:06:08 +02:00
5587b9bc43 added VERSION file
This will in the future be used to have an automated update check. Ain’t
that great⁈
2020-07-31 06:05:38 +02:00
833f6bcd0f Proper profile updating! Yay!!!!
fixes #48
2020-07-31 05:57:34 +02:00
e22656da1e RatAttack: added note about VA as admin to the IRC section 2020-07-31 01:04:04 +02:00
c4c5af91f3 EliteDangerous: fixed how many <thing> do i have 2020-07-31 00:22:46 +02:00
08fd729bcd SealAttack: profile removed for now
see #7
2020-07-30 12:04:19 +02:00
4f16a9763a README: included tidbit about “newer version” 2020-07-29 15:09:16 +02:00
d9eb73e145 EliteDangerous: fixed Route details event TTS 2020-07-28 17:56:49 +02:00
b69d19e27f EliteDangerous: parameterized EDSM system thingies 2020-07-28 11:43:39 +02:00
79a3dd54ba EliteDangerous: removed ((EDDI Commander continued)) 2020-07-27 19:16:27 +02:00
e82e9621fc RatAttack: fixed TTS for RatAttack.enableRatDuty 2020-07-26 03:17:21 +02:00
98b5ae52ca README: updated update instructions
fixes #47
2020-07-25 18:26:52 +02:00
da60d3cc4d EliteDangerous: fixed Route details event
Now not firing on atuomated events like handing in missions which caused
an event of type `update`. Might need additional tinkering in the future
if I want to expand on the functionality, like actually having voice
commands for mission route updates. I don’t see that coming, but who
knows.

fixes #46
2020-07-25 15:09:55 +02:00
6635c158bc 2.0.1! 2020-07-21 01:16:07 +02:00
ffc5674c26 EliteDangerous: improved readability of carrier jump request timing logic 2020-07-20 11:08:39 +02:00
e74cc9a3ce RatAttack: fixed distance to … command for unknown systems 2020-07-20 02:47:30 +02:00
68bb138ae3 EliteDangerous: fixed carrier pre-lockdown and jump engaged TTS 2020-07-20 00:09:15 +02:00
383a0e7b3f EliteDangerous: tentative fix for carrier pre-lockdown warnings timing 2020-07-19 01:39:11 +02:00
a064e907a8 EliteDangerous: fixed Carrier jump request event TTS 2020-07-19 01:32:03 +02:00
273c0b291c README: removed obsolete tidbit about EDDI quiet mode 2020-07-18 17:22:36 +02:00
bde59cac5c 2.0! 2020-07-18 17:13:33 +02:00
d565ff58e5 README: updated install docs
fixes #42
2020-07-18 17:09:04 +02:00
87b45264fc fixes for the inevitable refactoring mistakes 2020-07-18 15:00:07 +02:00
0c921a6cd1 RatAttack: tentative workaround for ratsignal file sometimes sticking around when profile switching 2020-07-16 20:55:12 +02:00
1666e72725 RatAttack: included warning about starter area for incoming cases
fixes #43
2020-07-16 20:30:02 +02:00
337b73902e fixed #37 2020-07-16 20:28:52 +02:00
8028a3e82b more work on #37 2020-07-16 19:24:38 +02:00
47dc5e5338 EliteDangerous: fixed carrier lockdown pre-announcement timings 2020-07-16 18:07:50 +02:00
e3c9a3e887 Changed startup commands to use default values
You can directly pass default values instead of checking for “Not set”,
then setting a default. Sadly isn’t a thing for Booleans though :-/

Default values can’t contain tokens either … T.T

Also fixes #38 command queue parameter passing because VoiceAttack
profiles aren’t properly diff-able and that’s what I was working on.
Yay!
2020-07-16 18:00:20 +02:00
09803cbe2b RatAttack: fixed sendToRatchat invocation from the message sent event 2020-07-16 17:12:02 +02:00
99887044c6 EliteDangerous: added carrier lockdown pre-announcements
10min, 5min, 2min to lockdown.

fixes #38
2020-07-16 16:53:43 +02:00
88124688fb RatAttack: removed a personal thingy from IRC docs 2020-07-16 15:53:52 +02:00
2f30b8df25 EliteDangerous: added open spansh command 2020-07-16 01:58:05 +02:00
3e3ccff719 EliteDangerous: bumped fss and cruise confidence thresholds
Those werer firing by accident a lot.
2020-07-16 01:11:43 +02:00
1ef9100c6d EliteDangerous: improved re-focusing of Elite client for certain events 2020-07-15 11:07:53 +02:00
f068d19f62 RatAttack: fixed docs, IRC setup 2020-07-14 21:40:58 +02:00
d483eb2cad EliteDangerous: added old station results to log window 2020-07-14 01:12:18 +02:00
d1acf3a8df RatAttack: RATSIGNALs are now passed through a file!
No more clipboard dancing/ninjaing!

fixes #41
2020-07-13 21:37:29 +02:00
82eb1bddf3 RatAttack: more command parameter fixes
– `passedInteger` ≠ `passedInt` T.T
– Passed string variables are evluated, `|{` and `|}` are swallowed
  … again. Needs to passed as String literal without going through
  a variable.
2020-07-13 15:53:12 +02:00
ec6354db9d RatAttack: fixed getNearestCommander invocation parameters 2020-07-13 14:22:01 +02:00
4c11f2ff8f RatAttack: fixed overzealous getInfoFromRatsignal refactoring 2020-07-13 13:22:05 +02:00
c8b7360d28 RatAttack: fixed a couple inevitable refactoring mistakes 2020-07-13 12:56:28 +02:00
9b31298a8d RatAttack: LOTS of refactoring.
see #37
2020-07-13 12:51:13 +02:00
bffc0d9988 StreamAttack: distance to jump target restricted to single instance
see #40
2020-07-13 11:36:35 +02:00
30a773828f forgot to mention: fixed #40 2020-07-13 11:33:48 +02:00
c23364cad3 House keeping!
fixes #39
2020-07-13 11:31:24 +02:00
c98692e15f added TTS feedback to reload bindings 2020-07-11 20:26:33 +02:00
e39b89296f CHANGELOG: missing bit about renamed variables 2020-07-11 10:06:13 +02:00
d0d94cf63d README: typo/leftover text bit from refactoring 2020-07-11 10:02:41 +02:00
2462b56346 EliteDangerous: removed FA/off check from normal space event
It’s finicky. At best. Randomly doesn’t update FA status fast enough to
be of any use.
2020-07-11 01:50:00 +02:00
ba4149fc8b EliteDangerous: added config options
Announcements of outdated station data and missing system/bodies on EDSM
is now optional. Still defaults to doing them.
2020-07-10 14:55:54 +02:00
7f493840c7 EliteDangerous: fixed R2R mapping candidates announcement
It was still using the outdated variable name …
2020-07-10 14:41:59 +02:00
22927cf9dd EliteDangerous: added comments to settings in startup 2020-07-10 14:41:36 +02:00
6d3450186a EliteDangerous: removed obsolete/removed settings from docs 2020-07-10 14:36:11 +02:00
e5a8e3742c EliteDangerous: old station threshold is now a config option
Updated `elite-scripts` to take an optional age as parameter for old
station search, and addded it as a config option to the profile. Still
defaults to 365d = 1y.
2020-07-10 14:34:22 +02:00
83669e9f2b EliteDangerous: no longer checking FA when dropping near a planet
see #36
2020-07-10 02:51:53 +02:00
41ebe0f89b SpanshAttack: updated docs for ED-Neutronrouter pre-release
Now matches the general README.
2020-07-09 20:26:36 +02:00
94050258e9 EliteDangerous: improved Low fuel event
fixes #34
2020-07-09 18:29:25 +02:00
f5107d168c EliteDangerous: fixed TTS for EDDI carrier jumped 2020-07-09 17:39:31 +02:00
88e1e2a49c EliteDangerous: added FA check to EDDI entered normal space event 2020-07-09 17:38:55 +02:00
e7faa5813c RatAttack: incoming ratsignals now convert system to lower case
A lot of people put there systems in caps lock for some reason. That
causes EDDI to pronounce it letter by letter. Converting to lower case
first prevents that.

On the flip side that might mean that e.g. “HIP 2342” might be
mispronounced; this should happen way less often than the above problem
though.
2020-07-08 21:25:39 +02:00
3e6f9d0854 i never forget to update a CHANGELOG 2020-07-08 00:06:28 +02:00
409b979175 Now using EDDI’s {P("<string>")} thingy
… which means we will now have proper system name pronunciation in more
cases. No more “Sagittarius A Asterisk”!

fixes #31
2020-07-07 23:59:44 +02:00
0f7d050f10 Settings now preserved when switching profiles around. 2020-07-07 23:20:30 +02:00
0884bc0f98 targeting Elite via process name instead of window title 2020-07-07 11:11:49 +02:00
c812c5483e clarified the settings commands documentation 2020-07-06 22:02:48 +02:00
807bbed51c updated everything to settings via voice commands!
fixes #12, #26
2020-07-06 21:26:16 +02:00
d237ec9e21 renamed leftover >var style configuration variables
… in preparation for the great config overhaul of 2020™

(see #12, #26)
2020-07-06 17:14:30 +02:00
aec0fea5ff CHANGELOG: fixed version number 2020-07-05 19:11:58 +02:00
5fbc530b61 1.5.1! 2020-07-05 19:08:03 +02:00
a9a3924ea7 another quite/quiet typo T.T 2020-07-05 18:22:49 +02:00
fd4243b2bd fixed version no for SpanshAttack 2020-07-05 18:21:27 +02:00
ac7e3090d6 1.5! 2020-07-05 18:13:42 +02:00
8d6d8ccdee SpanshAttack: trip timer preserved on (re-)plot
fixes #16
2020-07-05 16:03:17 +02:00
d89a2ad2c9 missing CHANGELOG items added 2020-07-05 16:01:56 +02:00
50f449613c EliteDangerous: triage for #33 2020-07-05 15:55:06 +02:00
40cc3984af RatAttack: removed leftover debug log output 2020-07-05 15:54:16 +02:00
cbb34cd6ab RatAttack: fixed distance to rat case commands
fixes #30
2020-07-05 15:43:36 +02:00
07d611b83b EliteDangerous: fixed a bug in getOldStations
… which caused the last speech in a command chain to be repeated
2020-07-04 16:06:05 +02:00
ab0db22cac EliteDangerous: carrier jump event fixed
now correctly runs the EDSM body count and old stations checks like
a normal jump
2020-07-04 03:01:10 +02:00
dc57829718 SpanshAttack: fixed missing dec→int conversion getting coords from EDDI 2020-07-03 00:07:44 +02:00
7a4c9200f1 EliteDangerous: removed a bunch of commands
see #27
2020-07-01 12:06:45 +02:00
6f40777d9b SpanshAttack: now using the new edts.py script
Automation of getting unknown target systems’ coordinates! Yay!

fixes #28
2020-07-01 11:52:56 +02:00
b4a3c7abb7 SpanshAttack: refactoring and target system ≠ plot system 2020-07-01 10:08:09 +02:00
87e258afb5 EliteDangerous: fixed and refactored EDDI Material threshold 2020-06-30 00:03:03 +02:00
8d3674d62e EliteDangerous: fixed ((EDDI carrier pads locked)) command name 2020-06-27 15:29:54 +02:00
969e8bb86a StreamAttack: now updates your location on Carrier jumped
fixes #29
2020-06-26 04:02:36 +02:00
f163d5c513 SpanshAttack: coordinate lookup through EDDI 2020-06-25 00:33:54 +02:00
7bf184322b Changelog: fixed 1.4 release date 2020-06-23 15:58:11 +02:00
cc0fa10cea EliteDangerous: removed deprecated commands
fixes #25
2020-06-23 12:19:56 +02:00
75183c632e EliteDangerous: refactored EDDI say invocations
fixes #22
2020-06-23 12:19:20 +02:00
8c70cc780e implemented EDDI VA initialized
… now sets it to quiet mode even if profile was loaded before plugin
initialization.

fixes #23
2020-06-23 10:59:44 +02:00
8fb3981766 EliteDangerous: added EDDI’s new carrier-based events
fixes #19
2020-06-23 09:52:11 +02:00
f39875fdb6 EliteDangerous: fixed auto-honk on EDDI Jumped
fixes #21
2020-06-22 01:27:15 +02:00
9de9d3eea2 v1.4! 2020-06-19 22:42:00 +02:00
a5d4b8c9a7 EliteDangerous: added shut up EDDI command 2020-06-19 22:36:49 +02:00
7c809bf3d6 EliteDangerous: added support for EDDI’s route()
There are a bunch of `target <thing>` commands powered by EDDI now. Put
them in their own fresh “navigation” category along with old commands
that fit in there.
2020-06-18 00:24:51 +02:00
4565a99e4c CHANGELOG: typo fixed 2020-06-14 20:18:09 +02:00
58a7695cb8 v1.3! 2020-06-14 20:10:32 +02:00
cbdc929eb8 automated bindings!
EliteDangerous: now automatically detects the bindings profile in use
and loads that.

SpanshAttack: now loads bindings, like, at all. Guess I forgot that.
Also automated, of course.
2020-06-13 15:47:42 +02:00
6439927224 EliteDangeuros: increased delay before EDDI docked starts 2020-06-10 02:08:31 +02:00
4ed3cbdb03 EliteDangeuros: fixed nav panel filters for carriers 2020-06-09 21:16:29 +02:00
17d5f8f948 EliteDangerous: fixed EDDI docked event for new interface 2020-06-09 21:10:30 +02:00
a2cdb3db99 EliteDangerous:
* added a couple materials/engineering related commands
* added `Entered normal space` event; will throttle you to 0 if
  `EliteDangerous.hyperSpaceDethrottle` is set
2020-06-07 21:17:10 +02:00
a85027646b StreamAttack: now updates location on dropping from SC 2020-06-07 17:28:32 +02:00
b8de820885 EliteDangerous: materials + commander loading
* added `[what;which] materials do i need?` command
* added `EDDI Material Threshold` event
* changed `EDDI Commander continued` event to `EDDI Commander loading`
  which executes on game start rather than every time you log into
  a game mode.
2020-06-03 18:14:15 +02:00
54c7777d0e RatAttack: added RatAttack.[enable;disable]RatDuty commands 2020-05-30 17:59:11 +02:00
64e933f424 README: missing comma 2020-05-10 18:39:10 +02:00
04af7eff2c Merge branch 'release' into devel 2020-04-24 10:20:20 +02:00
ccdf607f14 README: fixed Discord invite 2020-04-24 10:20:00 +02:00
e60a50468b EliteDangerous: removed my HOTAS/HOSAS button commands
Moved them to their own profile. They are not really useful for anyone
else without tinkering anyway.
2020-04-24 10:17:45 +02:00
8b18c2eac3 EliteDangerous: added restart from Desktop command
Also started making delays/pauses configurable (see #18).
2020-04-24 10:11:52 +02:00
a0c97ee688 EliteDangerous: updated miner’s tool URL 2020-03-13 21:40:21 +01:00
e10e02a91c EliteDangerous: added open inara command 2020-03-13 19:45:26 +01:00
4b58c342e9 EliteDangerous: added open materials finder command 2020-03-13 19:34:30 +01:00
a8ce3598f9 StreamAttack: fixed copypasta errors in the docs 2020-03-09 23:03:35 +01:00
ba65a9094b CHANGELOG typos 2020-03-09 23:01:53 +01:00
a8d8b5597e Merge branch 'release-prep/1.2' into devel 2020-03-09 22:35:52 +01:00
d5bfaa8c99 Merge branch 'release-prep/1.2' into release 2020-03-09 22:35:41 +01:00
ebfdc12e28 v1.2! 2020-03-09 22:35:32 +01:00
284aa120d7 SpanshAttack: clarified EDDI’s “laden” range. 2020-03-09 21:06:59 +01:00
efc3728a33 EliteDangerous: typo in EliteDangerous.focusElite fixed 2020-03-09 21:01:22 +01:00
4dd41e850b SpanshAttack: now aware of the router’s system database
Will check if a system exists in the database before trying to plot
a route. If not, will ask for coordinates to find the nearest system
that is.

Now requires `elite-scripts`. **This change breaks compatibilty**.
2020-03-09 20:52:20 +01:00
25dbb3edc8 SpanshAttak: checking for current/target system before plotting 2020-03-09 19:40:08 +01:00
2f868a1460 EliteDangerous: made Water Worlds worth mapping … 2020-03-09 18:27:24 +01:00
d22455df38 SpanshAttack: added SpanshAttack.defaultToLadenRange option
If enabled, this will ask EDDI about the ship’s laden range and default
to that instead of asking for user input. Setting a ship’s range
manually in `SpanshAttack.getShipRange` will still have higher priority
(e.g. if you are usually using a ship with less than a full cargo hold).
2020-03-08 02:14:58 +01:00
d4faee85cb EliteDangerous: fixed for changed spansh.py interface 2020-03-08 01:07:13 +01:00
b9b72881a1 README: added note about using the latest VA Spansh plugin 2020-03-08 00:06:34 +01:00
e2874d72e2 README: added note about using the latest VA Spansh plugin 2020-03-08 00:05:01 +01:00
864d78141f EliteDangerous: now telling you about outdated station data 2020-03-04 18:18:48 +01:00
3b4c7545a2 StreamAttack: added [copy;open] ship build command 2020-02-26 11:38:43 +01:00
f8ce6ab33e EliteDangerous: fixed docking request if you have a target
Got messed up before if the “target” tab was active. Now doing panel
right x2 instead of panel left.
2020-02-26 11:37:24 +01:00
032523b58c StreamAttack: fixed location for planetary bases 2020-02-26 10:57:05 +01:00
4ba0943e13 RatAttack: split passing and announcing new cases
You can now just pass a ratsignal to VA (without it being announced) by
calling `RatAttack.getInfoFromRatsignal`, or choose to also have it
announced in TTS by calling `RatAttack.announceCaseFromRatsignal`.

**Breaks interface compatibility!** `RatAttack.getInfoFromRatsignal`
behaviour has changed.
2020-02-25 19:45:25 +01:00
c924709e34 StreamAttack: location fixes
EDDI sets `Status near surface` near stations, but without
a corresponding event firing … so I had to change the logic there.

Also updating the state variables takes a couple seconds after an event,
so `EDDI Docked`, `EDDI Near surface` and `EDDI Undocked` now have a 5s
delay each. Let’s see if that is enough.
2020-02-25 00:35:18 +01:00
643d662ed0 EliteDangerous: running StreamAttack.startup now … 2020-02-25 00:34:59 +01:00
631fdd2851 RatAttack: added proper handling for multiple rsigs
Handling of a ratsignal will be delayed by 5s if a signal is currently
being handled. That way all signals will find their way into VoiceAttack
even if they hit simultaneously / shortly after each other.

To reduce possible confusion though the “open case?” prompt has been
removed from `RatAttack.getInfoFromRatsignal`.

**Breaks interface compatibility!**
2020-02-24 17:32:59 +01:00
ce15622a7c StreamAttack: fixed EDDI jumped event to write location data 2020-02-24 00:58:08 +01:00
77835da532 RatAttack: added open [rat;] dispatch board command 2020-02-23 07:53:02 +01:00
28a9508977 StreamAttack: some more fixes 2020-02-23 07:51:40 +01:00
1f7d6aeffc StreamAttack: some typos in the profile fixed 2020-02-22 20:18:44 +01:00
696e39f040 StreamAttack: initial version
Moved all `jump target` stuff out of the `EliteDangerous` profile into
its own. Added various info files for commander, ship, location, jump
target.
2020-02-22 20:00:53 +01:00
0e7e766f4d EliteDangerous: >hyperspaceDethrottle setitng
Will now respect the setting for auto dethrottle after a jump. defaults
to false.
2020-02-18 01:41:04 +01:00
59fbcd3f82 docs: removed double spaces 2020-02-10 18:53:36 +01:00
3e1cc35243 EliteDangerous: fixed mapping value announcement
It’s now “x.y million credits”.
2020-02-10 10:58:49 +01:00
5950bea451 EliteDangerous: changed logic for “worthwhile” bodies to map
Now treats terraformables and ELW/Ammonia Worlds as worthwhile instead
of going by estimated scan value.

Also now tells you the map data value of high-value bodies you mapped.
2020-02-09 21:17:03 +01:00
9f95ba6327 imagine forgetting to include the actual profile in your commits … 2020-02-08 12:43:27 +01:00
9500b09527 EliteDangerous: removed headlook buttons, no longer in use 2020-02-08 11:43:55 +01:00
3061e00c1e EliteDangerous: events will focus Elite
If an event is about to send key presses, it will focus the Elite client
window now to make sure the first one won’t get swallowed even if you
are tabbed out right now.

For all non-event commands, I’m going to assume you are actively playing
and the client already has focus.

Fixes rare instances of key presses being swallowed, e.g. in the `EDDI
Jumped` command when you tabbed out of the game in hyper space. Should
make things more reliable in general.

Also replaced all occurences of focusing the client window with the
helper function to have a single point of change if the client window
title ever changes.
2020-02-08 11:41:25 +01:00
35ed643d2c changelog fixed 2020-01-30 06:44:35 +01:00
a69db3ee7a Merge branch 'release-prep/1.1' into devel 2020-01-30 06:42:25 +01:00
e2ad40defa Merge branch 'release-prep/v1.1' into release 2020-01-30 06:40:49 +01:00
770b17ae04 v1.1! 2020-01-30 06:40:36 +01:00
0ed96207f0 EliteDangerous: added distance [from;to] jump target 2020-01-30 06:22:13 +01:00
4a02e41959 docs typos 2020-01-30 03:02:13 +01:00
c5bd8bc936 EliteDangerous: added some quick links
Coriolis, EDSM main page, EDDB (incl. station/system/faction search page)
2020-01-30 02:56:21 +01:00
d54c66b1b6 SealAttack: VERY early alpha
Basically the only thing that works and is “finished” already is pasting
ingame chat into Seals IRC. use `.sb <msg>` for \#Seal-Bob and `.rr
<msg>` for \#Repair-Requests.
2020-01-29 23:13:33 +01:00
fcbd556c3c RatAttack: [current;] rat case details changed
Now always has to include “rat” in the command to pave the way for
SealAttack arriving soon™.
2020-01-29 23:05:58 +01:00
57a6221a47 EliteDangerous: added jumpTarget stuff
You can now set a jump target. This will start writing the distance to
said target to `>jumpTargetFile` for inclusion e.g. in OBS.

If SpanshAttack currently has a target system, jump target will default
to that. A manually set target will take precedence.
2020-01-29 22:44:21 +01:00
90d4d20e37 EliteDangerous: mute button + docs fixes 2020-01-29 16:02:12 +01:00
1be50d5aed updated for new controls setup 2020-01-28 23:59:46 +01:00
5edd0ecad6 SpanshAttack: added info about EDDB to docs
Just a little tidbit about making sure the target system is actually in
the DB.
2020-01-25 02:40:45 +01:00
72f92fe1bc EliteDangerous,RatAttack: updated for single-file scripts 2020-01-17 16:19:45 +01:00
7cd280d3bf more docs fixes 2020-01-13 23:44:29 +01:00
2a56091b3c some fixes to the docs 2020-01-13 23:25:41 +01:00
fe16c75dfe fixed great typo in jump call command 2020-01-12 02:05:43 +01:00
8f033b2eec added call client offline command 2020-01-10 01:14:08 +01:00
10ebd102fc added distance commands
`distance to current rat case`
`distance to rat case number [0..19]`

Both require a current version of the elite-scripts.
2020-01-09 21:43:13 +01:00
217582cf79 added option to call jumps “left” 2020-01-09 21:16:01 +01:00
2d12fec087 fixed race condition in EDDI ship fsd
Weirdly that only started being an issue in VA 1.8.
2020-01-07 21:36:29 +01:00
5f9a469344 logic around getting bodycount more sturdy
Now actually notices when the script errors out for some reason.
Probably still won’t notice when it’s flat out missing, but hey, that’s
PEBKAC for not using the profile package.
2020-01-07 21:02:45 +01:00
a70b202936 SpanshAttack: added plot command “with custom range”
Instead of using the saved jump range for your current ship, you can now
plot a route with a custom range; e.g. if you have temporarily changed
modules around or have more/less cargo than usual for this trip.
2019-12-12 08:48:43 +01:00
7b220bacbe EliteDangerous: changed EDDI Body scanned constraint
Now checks for being in SC instead of just in FSS; will now include
auto-scans of bodies, while still excluding nav beacon scan data.
2019-12-08 22:47:20 +01:00
92b179c6bb some more refactoring for variable scoping 2019-12-07 19:33:06 +01:00
ab65679245 RatAttack: added option to aut-close on fuel+
Defaults to off. Enabled in EliteDangerous by default.
2019-12-07 10:23:07 +01:00
54fc6bd53e CHANGELOG: fixed header formatting 2019-12-04 01:54:51 +01:00
284bd0d7cf Merge branch 'release-prep/1.0' into devel 2019-12-04 01:51:58 +01:00
80dda67114 Merge branch 'release-prep/1.0' into release 2019-12-04 01:51:52 +01:00
9b5ac8c2f7 v1.0! 2019-12-04 01:51:41 +01:00
5e9a9453fe CHANGELOG: removed VA beta stuff
… it’s now the official release anyway.
2019-12-04 01:34:34 +01:00
d081ebc38d README: typo 2019-12-04 01:33:34 +01:00
267b5862f2 README: added note about individual profile download 2019-12-04 01:32:10 +01:00
6bb8087c0f README: updated for upcoming profile package releases 2019-12-04 01:29:46 +01:00
674c5d62b8 changed python script dir
Now resides in `Sounds\scripts` for upcoming profile package compatibility.

Techincally the `Apps` directory would be more appropriate; as soon as
a profile package has that directory though you have to restart
VoiceAttack without plugin support to import the package.
2019-12-04 01:18:37 +01:00
17a0ae4917 EliteDangerous: added [dis;]engage silent running 2019-11-28 04:59:49 +01:00
487217a678 RatAttack: added call wing pending command 2019-11-25 10:03:03 +01:00
415e5f93bf Spansh/RatAttack: exported in new format
… for consistency’s sake
2019-11-24 20:40:30 +01:00
fcec8b8cc5 EliteDangerous: refactored the next star scoopable check
That one was still using global variables, and speech output looks
cleaner now.

Also changed the default setting for Fuelrats IRC nickname switching.
2019-11-24 20:38:58 +01:00
b06ebef617 added notice about using VA beta to CHANGELOG 2019-11-24 20:37:07 +01:00
38d7c67a91 added fixed elite-scripts version to the CHANGELOG
… actually doesn’t change anything until a new release is published.
2019-11-24 20:35:17 +01:00
281374cfd5 RatAttack: fixed first case announcement
Correctly ask about opening a case even if it’s the frist
(`RatAttack.onCase` has not been set yet).
2019-11-16 22:18:11 +01:00
b989b7de26 RatAttack: copy sys to clipboard first on open
first copy the system, _then_ announce case details!
2019-11-15 15:15:39 +01:00
e8023de816 SpanshAttack: set neutron mode and target before getting range 2019-11-14 02:29:33 +01:00
316a85093c RatAttack: only get nearest CMDR for the proper platform
On incoming RATSIGNAL, only fetch the nearest commander if the case is
on one of the enabled platforms; even if not on duty.
2019-11-11 16:39:46 +01:00
8893913904 Merge branch 'release-prep/0.5' into devel 2019-11-09 08:02:05 +01:00
553ae0f735 Merge branch 'release-prep/0.5' into release 2019-11-09 08:01:33 +01:00
748e057ca3 v0.5! 2019-11-09 08:01:26 +01:00
538696d482 RatAttack: fixes to the docs :) 2019-11-09 07:48:29 +01:00
138ef3ed34 RatAttack: added docs
fixes #7!
2019-11-09 07:36:09 +01:00
cf3955960a RatAttack: disabled deprecated current case variables 2019-11-09 07:32:57 +01:00
b8b5ca6460 {Spansh,Rat}Attack: disabled EDDI’s speech responder by default
In order not to confuse people that have not been using EDDI in the
past, the profiles will now automatically disable the speech responder.
To use it with the profiles, you will have to explicitly enable it
again.
2019-11-08 00:23:49 +01:00
d2549b2ab7 EliteDangerous: added [start;stop] [firing;mining] 2019-11-07 06:30:56 +01:00
9803dd9abb EliteDangerous: fixed edsm body count comparison
report if EDSM has FEWER bodies, not more …
2019-11-04 22:39:51 +01:00
90e28605e3 EliteDangerous: now automatically toggles FA off
If you set `>flightAssistOff` in the startup command, VA will now
automatically make sure that FA is off when you lift off a planet or
undock from a station. Defaults to on.
2019-11-03 19:59:58 +01:00
d70734ff5e RatAttack/EliteDangerous: fixed .sentToX
Now does a ^A before pasting. Prevents accidental mishaps with having
text typed and then VoiceAttack pasting behind it.
2019-11-01 20:40:46 +01:00
67bac3e4f9 RatAttack: more RSIG parsing fixing 2019-10-31 20:07:36 +01:00
61f8a2e51e RatAttack: refactoring
Opening a case now reuses the `RatAttack.announceCaseDetails` command
instead of replicationg it.
2019-10-31 12:44:11 +01:00
c248a851d0 SpanshAttack: documentation typos 2019-10-31 12:37:57 +01:00
0f97adafa1 SpanshAttack: added requirements to documentation 2019-10-31 12:26:15 +01:00
490307ecd5 RatAttack: workaround for weird platform parsing bug
PC cases would have EVERYTHING till the end of the ratsignal as
platform. Didn’t cut correctly at end of platform. So I’m now just using
the ??_SIGNAL at the end instead of debugging the problem because I’m
a lazy fuck.
2019-10-31 01:32:20 +01:00
4dd57ab273 RatAttack: bunch of platform fixes
For one i made a bunch of small mistakes (of course), and I had to do
a dirty workaround for platform detection since IRC color coding messes
with VA really badly.
2019-10-30 16:38:23 +01:00
e676893b3a RatAttack: is now multiplatform! also 2-digit case numbers. 2019-10-30 11:23:40 +01:00
fd2ee7741e SpanshAttack: fixed target announcement when plotting 2019-10-30 09:35:04 +01:00
dc8bb112f7 RatAttack: re-wrote case handling
VoiceAttack will now keep a list of cases and case data. That
streamlines handling of multiple cases / opening an already announced
one after finishing the current one.
2019-10-27 13:45:33 +01:00
dcbda089d2 EliteDangerous: fast orbit notification in scan event 2019-10-22 09:46:25 +02:00
0bfc7ac63e EliteDangerous: fixed the discovery scan event
Now will only tell you about differences with EDSMM when EDSM knows
_fewer_ bodies (there are some issues with duplicate entries in EDSM,
e.g. in Dromi)
2019-10-21 23:49:48 +02:00
f5d0a999df RatAttack: fixed RatAttack.parseRatsignal
VoicaAttack can handle control characters within a commond definition.
Sadly it errors out if you try to _import_ a profile that has said
control characters in them …

The workaround is to set the delimiter variable (`^B`) in an inline
function. This way the character itself does not appear in the exported
profile and everything works fine.
2019-10-19 22:34:38 +02:00
7fa191219f removed bindED from RatAttack requirements 2019-10-18 23:04:21 +02:00
e697b22867 added RatAttack profile. No docs yet. 2019-10-18 22:33:33 +02:00
132bd9565b fixed auto jump on scooping
Now only queues a jump _once_ not once per “refuelled” event (fires
every 5s)
2019-10-18 22:31:32 +02:00
45b8f6e9ff CHANGELOG: typo fixed 2019-10-14 20:23:14 +02:00
ac34f85a6f Merge branch 'release-prep/0.4.1' into devel 2019-10-14 20:15:03 +02:00
4d7cba2d6b Merge branch 'release-prep/0.4.1' into release 2019-10-14 20:14:53 +02:00
b2ae6c455c v0.4.1! 2019-10-14 20:14:39 +02:00
6dd011bde0 SpanshAttack: fixed jump on scooping
Will no longer conflict with an already charging jump
2019-10-14 15:25:44 +02:00
e5c3671d0e fixed srv lauched event to properly turn off the lights 2019-10-14 14:46:53 +02:00
3397ec1285 fixed discovery scan event for new EDDI variable naming 2019-10-14 10:11:27 +02:00
99b75f38db EliteDangerous: fixed lights off command for SRV
EDDI has a new `Status srv high beams` variable that can be used to
distinguish the two SRV lights states :)
2019-10-14 08:52:49 +02:00
b4423e4f0d Merge branch 'release-prep/0.4' into devel 2019-10-12 00:36:45 +02:00
db5540ab17 Merge branch 'release-prep/0.4' into release 2019-10-12 00:36:32 +02:00
5f9d488989 v0.4! 2019-10-12 00:36:13 +02:00
382b4c8605 EliteDangerous: docs typos ’n’ stuff 2019-10-12 00:33:10 +02:00
b360975339 EliteDangerous: added extensive documentation
fixes #11
2019-10-12 00:16:51 +02:00
94d98cbf3b EliteDangerous: straightened out some command invocations 2019-10-12 00:08:48 +02:00
5ece1c5f0d EliteDangerous: minor change to opening system on EDSM 2019-10-11 23:14:36 +02:00
7ea4a3128c SpanshAttack: fixed auto jump logic 2019-10-11 18:16:02 +02:00
739e885417 SpanshAttack docs: wording fix “import”→“include” 2019-10-10 12:17:54 +02:00
881484fa70 typo 2019-10-10 12:14:57 +02:00
650c9ee25e SpanshAttack: fixed auto jump after scooping
… will now also only fire if actually in neutron jump mode.
2019-10-10 09:46:47 +02:00
b75746c044 SpanshAttack: fixed clear on shutdown
Now correctly handles cases when you are NOT on a neutron trip …
2019-10-10 09:07:30 +02:00
adee73698d fixed CHANGELOG typos 2019-10-10 07:43:50 +02:00
0f9501c83a SpanshAttack: added option to auto jump ofter fuel scooping
default: on
2019-10-10 07:37:04 +02:00
5c59300347 SpanshAttack docs: better formatting 2019-10-10 07:28:10 +02:00
8f2fca8517 typo corrected 2019-10-10 07:26:43 +02:00
4bf036596e README: added {Rat,Seal}Attack disclaimers 2019-10-10 07:19:01 +02:00
c960d468cd SpanshAttack: fixed SpanshAttack.announceTripTime
Now knows proper singular for hours and minutes.

fixes #13
2019-10-10 06:53:05 +02:00
16905c68cf SpanshAttack: added option to clear route on game shutdown
Defaults to true. Also added compatibility for that to EliteDangerous.
2019-10-10 06:44:30 +02:00
7cd25e4a5b changed “distance to” command to be more flexible
Right now includes “home”, “the center”, “Beagle Point”, “Colonia” and
is easily extensible.
2019-10-10 00:44:36 +02:00
f46ef41fe1 changed EliteDangerous version to 2.0
adding the elite-scripts dependency should be viewed as breaking
compatibility, IMO. requires manual changes when upgrading.
2019-10-08 11:35:58 +02:00
b4a77944b4 added elite-scripts dependency to README 2019-10-08 11:35:47 +02:00
d9c1edbe43 added some commentary around the body count thing 2019-10-08 11:31:32 +02:00
b15ad00a61 added missing CHANGELOG entries 2019-10-07 21:22:43 +02:00
98997a5622 moved EDSM body count call to the jumped event
– got its own command now
– called on jumped instead of disco scan for less spamming the API and
having the information available in the scan event without waiting
– information is cleared on commander login to not interfere with other
sessions
– if not already downloaded when disco scan is executed, will download
then
2019-10-07 21:18:31 +02:00
4ff6bb161c fixed EliteDangerous.jumpToSupercruise: no longer drops from SC 2019-10-04 05:22:02 +02:00
0c06a2d67f added distance from home command 2019-10-04 05:20:25 +02:00
028f01095a EliteDangerous: fixed relog command, added EDSM body count comparison
The latter needs the elite-scripts stuff.
2019-10-04 03:08:52 +02:00
ac07478f55 README: included note about major version changes 2019-09-29 16:18:23 +02:00
c5c1801748 SpanshAttack: plotting a route now aborts if no jump range was given 2019-09-27 16:04:41 +02:00
880b7d97bb Merge branch 'release' into devel 2019-09-22 14:03:07 +02:00
1c3f85bf18 adde missing SpanshAttack changes 2019-09-22 14:01:37 +02:00
a447ac70fe Merge branch 'release-prep/0.3' into devel 2019-09-22 13:57:44 +02:00
17ea977e06 Merge branch 'release-prep/0.3' into release 2019-09-22 13:57:25 +02:00
bef89087b4 v0.3!
fixes #6
2019-09-22 13:56:55 +02:00
cfc15a3cfe Added lots of command descriptions for ease of use. 2019-09-22 13:50:44 +02:00
ff851405ad added Discord link to README 2019-09-22 03:49:38 +02:00
dc588db2f6 added Discord link to README 2019-09-22 03:48:56 +02:00
25d78f193f updatet EliteDangerous 2019-09-22 01:43:00 +02:00
d401f2b3c8 SpanshAttack: now writing trip time to VA log 2019-09-16 14:28:39 +02:00
3112e84b51 random bits and bobs 2019-09-09 21:20:49 +02:00
ab051fb243 optimisations for recognition and small things that i’ve already forgotten about 2019-09-09 21:20:02 +02:00
74c8609b33 EliteDangerous: major refactoring work
Not thoroughly bug tested yet, command structure should know roughly
represent what I’m aiming for, still not finished though. Everything
else (sanitising, commenting, …) still has to be done for an initial
release that can be publicly used.
2019-09-01 01:48:43 +02:00
dc54473982 fixed band-aid for #5 :) 2019-09-01 01:48:39 +02:00
c9f8224bfd SpanshAttack: improved trip time announcement
Don’t announce “0 hours” if the trip has been shorter than 1 h.
2019-08-30 07:08:09 +02:00
b13b7d7750 band-aid for #5. 2019-08-30 07:06:40 +02:00
90 changed files with 8056 additions and 37750 deletions

14
.editorconfig Normal file
View file

@ -0,0 +1,14 @@
[*]
guidelines = 80
end_of_line = lf
insert_final_newline = true
charset = utf-8-bom
[*.cs]
guidelines = 80, 120
# IDE0021: Use block body for constructors
csharp_style_expression_bodied_constructors = when_on_single_line
# IDE0024: Use block body for operators
csharp_style_expression_bodied_operators = when_on_single_line

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

23
.github/workflows/create-release.yaml vendored Normal file
View file

@ -0,0 +1,23 @@
name: Create release on tag push
on:
push:
tags:
- 'releases/*.*'
- 'releases/*.*.*'
jobs:
build:
name: Create draft release
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Draft release
uses: ncipollo/release-action@v1
with:
bodyFile: "CHANGELOG.md"
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

361
.gitignore vendored Normal file
View file

@ -0,0 +1,361 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
/plugins/build
/build
/alterNERDtive-VoiceAttack-profiles.vax
/Makefile
/site
/src
/build.csproj

File diff suppressed because it is too large Load diff

BIN
Custom Profile Example.vap Normal file

Binary file not shown.

25
Directory.build.props Normal file
View file

@ -0,0 +1,25 @@
<Project>
<PropertyGroup>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- StyleCop Analyzers configuration -->
<PropertyGroup>
<CodeAnalysisRuleSet>$(SolutionDir)StyleCop.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers.Error" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.CSharp.Async.Rules" Version="6.1.41">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<AdditionalFiles Include="$(SolutionDir)stylecop.json" Link="stylecop.json" />
</ItemGroup>
</Project>

674
LICENSE Normal file
View file

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program 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.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View file

@ -1,86 +1,42 @@
# Elite Dangerous VoiceAttack Profiles #
# Elite Dangerous VoiceAttack Profiles #
These are various profiles for [VoiceAttack](https://voiceattack.com) (VA) I use
to enhance my Elite experience. They give me important info, facilitate
day-to-day gaming and do some special things for [Fuel
Rats](https://fuelrats.com) and [Hull Seals](https://hullseals.space) work.
Each of the profiles is documented in `/docs/`.
**NOTE**: Further development is on hold and Odyssey compatibility will not be
worked on for the time being. See [the corresponding issue on
Github](https://github.com/alterNERDtive/VoiceAttack-profiles/issues/113). This
might or might not change after the Horizons/Odyssey merge when console release
is upon us. Feel free to file issues for anything that is broken on Odyssey and
it will be worked on when it is worked on.
## Available Profiles ##
* [EliteDangerous](docs/EliteDangerous.md): My main Elite VA profile. Here be
dragons; things may be heavily tailored towards how _I_ play the game and may
not apply to how you play it. Included for reference and as a baseline or
inspiration to create your own stuff.
* [SpanshAttack](docs/SpanshAttack.md): profile to plot and follow trips along
the neutron highway using [spansh](https://spansh.co.uk/plotter).
* [RatAttack](docs/RatAttack.md): profile for interactions with the Fuel Rats
IRC server.
* [SealAttack](docs/SealAttack.md): profile for interactions with the Hull
Seals IRC server.
* EliteAttack: The main Elite VA profile. Anything related to “just” playing the
game.
* RatAttack: Manages interactions with the FuelRats IRC server.
* SpanshAttack: Plots and follows trips along the neutron highway using
[Spanshs neutron plotter](https://spansh.co.uk/plotter).
* StreamAttack: Writes various status things to files that can then be read by
streaming software like OBS.
## Requirements ##
## Documentation & Installation Guide
* [VoiceAttack](https://voiceattack.com): absolutely required (duh).
* [bindED](https://forum.voiceattack.com/smf/index.php?topic=564.0): required
for all profiles; makes anything involving hitting E:D key binds portable.
* [EDDI](https://github.com/EDCD/EDDI) installed as a VoiceAttack plugin:
required for my personal profile and for SpanshAttack, optional for RatAttack
and SealAttack.
* [ED-NeutronRouter](https://github.com/sc-pulgan/ED-NeutronRouter): required
for SpanshAttack.
You can find [comprehensive documentation on Github
Pages](https://alternerdtive.github.io/VoiceAttack-profiles).
Additionally, you need to have keyboard binds setup at least as secondary
bindings in Elites controls options. VA _cannot_ “push” joystick buttons for
you, it can only do keyboard inputs. Hence its only way to interact with Elite
is through keyboard emulation, even if you otherwise play the game with
a controller or HOTAS. Or racing wheel. Or Rock Band set. Or bananas.
## Need Help / Want to Contribute? ##
## Settings ##
If you run into any errors, please make sure you are running the latest version
of the profiles and all requirements.
Each profile has its respective `startup` command that should be launched upon
loading the profile. If you include the profile in your own (see below) you have
to manually call them for each included profile when yours is loaded.
## Using a Profile ##
Import the profile into VA, check the startup command for any settings you might
want to adjust, activate it, done.
Oh, and you probably might want to check the corresponding README first.
## Including a Profile ##
If you are already using a custom profile (or want to use mine), you can include
others by going to the profile options and adding them to the “Include commands
form other profiles:” option.
VoiceAttack does not execute configured startup commands for included profiles.
Hence, youll have to have your own profile have one that in turn runs the
included profiles startup commands. While you are doing that, you might as well
set all settings here, centrally. Main advantage is that you can just upgrade
the included profiles to newer versions without losing your settings.
Because of limitations of VoiceAttack itself, only the first matching command
found will be executed, _including EDDI events_. That means you have to check
your profile against the imported ones for events they both handle. E.g. if you
already have a `((EDDI Message sent))` handler in your profile, you have to run
`RatAttack.EDDI Message sent` and `SealAttack.EDDI Message sent` from within it.
You also have to do that if you include multiple profiles using the same events
(e.g. RatAttack + SealAttack), even if you dont have the same event in the
including profile! If you want to make sure, manually create all EDDI Event
handlers used in imported profiles and have them call the corresponding
commands. See the Elite Dangerous profile for reference.
## Contributing ##
If you run into any errors, please try running the profile in question on its
own / get a fresh version. If that doesnt fix the error, look at the
[devel](https://github.com/alterNERDtive/VoiceAttack-profiles/tree/devel) branch
and see if its fixed there already.
If you have no idea what I was saying in that last parargraph and / or the
things mentioned there dont fix your problem, please [file an
If your problem persists, please [file an
issue](https://github.com/alterNERDtive/VoiceAttack-profiles/issues). Thanks! :)
You can also [say “Hi” on Discord](https://discord.gg/kXtXm54) if that is your
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" />

1
VERSION Normal file
View file

@ -0,0 +1 @@
4.5

314
docs/EliteAttack.md Normal file
View file

@ -0,0 +1,314 @@
# EliteAttack
This is my personal VoiceAttack profile for Elite: Dangerous. It started out
ages ago as a modification of [MalicVRs public
profile](https://forums.frontier.co.uk/threads/malics-voice-attack-profile-for-vr.351050/),
then looked less and less and less like that and I added and cleaned up a lot of
things while removing the stuff I didnt use anyway. By now it would have
probably been simpler to start from scratch.
Funnily enough it has grown to rely way more on events provided by
[EDDI](https://github.com/EDCD/EDDI) than actual voice commands.
## Chat Commands
These commands will only work with the comms panel active, and you should be in
the edit window ready to send. They will _not_ hit Enter on their own.
* `clear [chat;text]`: Clears the chat window. Use from outside the comms panel.
* `[local;squad;system;wing] chat`: Puts you into the chosen chat channel.
* `salute; oh seven`: Will put “o7” into the chat.
## Engineering/Materials
* `how many [<g5 manufactured materials list>] do i have`: Tells you how many of
the given g5 manufactured material you currently have on board. Ive
restricted it to just those to not spam speech recognition with too many
phrases, and because those are the ones I usually want to know while jumping
around the bubble and having an eye on any HGE that might be around.
* `[launch;open] e d engineer`: Opens the ED Engineer tool.
* `what [mats;materials] do i need?`: Runs the EDDI responder that tells you
which materials are below wanted threshold. Needs setting those first. Gets
very spammy if you do it for all of them; personally I only set them for g5
manufactured, so I can quickly check if its worth looking for HGE in a system
Im in.
## Navigation
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
powered by awesome EDDI so I dont have to do the work myself!
* `distance [from;to] [Sol;home;the center;Beagle Point;Colonia]`: Gives you the
current distance to the given POI.
* `[find;target] nearest [encoded;manufactured;raw] material trader`: Targets
the nearest respective material trader.
* `[find;target] nearest [fuel;scoopable] star`: Targets the nearest scoopable
star.
* `[find;target] nearest [guardian;human] tech broker`: Targets the nearest
respective tech broker.
* `[find;target] nearest [interstellar factor;mission system;scoopable star]`:
Well, you know the drill by now.
* `[find;target] nearest mission system`: Targets the nearest system that has a
mission target.
* `how many jumps left`: Announces the jumps left on a neutron trip (requires
SpanshAttack) or a course plotted via the galaxy map.
* `plot course;[target;] next [waypoint;way point]`: Plots a course to the text
in your clipboard.
* `target [bug killer;colonia;davs hope;explorers anchorage;jackson's lighthouse;jamesons cobra;robigo;shinrarta dezhra;sagittarius a*;shinrarta;sothis]`:
Targets the given system on the galaxy map.
* `[wheres;where is] my landing pad`: Will tell you the location of your
assigned landing pad on a starport.
## Ship Controls
Basically anything that is related to directly doing something with your ship.
* `[abort;cancel;stop] jumping`: Stops a currently charging FSD jump.
* `[half;] power to [engines;shields;systems;weapons]`: Sets pips to 6/3/3
(`half`) or 8/2/2 towards the given capacitor.
* `[balanced;half;] power to [engines;shields;systems;weapons] [and engines;and shields;and systems;and weapons;]`:
Sets pips to 6/6/0 (balanced), 5/5/2 (half) or 8/4/0 towards the given capacitors.
* `[close;deploy;extend;open;retract;] [cargo scoop;hard points; landing gear] [up;down;]`:
Overly complicated command to handle everything related to Cargo Scoop, Hard
Points, Landing Gear. You get the gist, I guess. Works in SRV too.
* `[disco;discovery scan]`: Executes a discovery scan. Expects the Discovery
Scanner in your first fire group, secondary fire. [You can change
that](configuration/EliteAttack.md#settings).
* `[dis;]engage silent running`: Turns silent running on and off.
* `[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,
which sometimes leads to weird results.
* `[jump;engage;get me out] [and scan;] [when ready;]`: Retracts everything that
might be protruding from your ship, then jumps to the next system. If the FSD
isnt charging within 1s, it gets you into SC instead (e.g. if your target is
obstructed). If given “and scan” runs a discovery scan. If given “when ready”
waits for mass lock to clear, your FSD to cool down and you to leave scoop
range before jumping.
* `night vision [on;off]`: Toggles your night vision on/off. Works in SRV too.
* `rapid fire lights`: Flashes your lights 5 times in a row.
* `retract [all;everything]`: Retracts, well, everything.
* `[start;stop] [firing;mining]`: Starts/stops holding down primary fire. Mostly
useful when mining. When triggered with “mining”, also deploys the cargo
scoop.
* `[super;] cruise [when ready;]`: Retracts everything, then jumps to SC. If
given “when ready” will wait for mass lock to clear and your FSD to cool down
first.
## SRV Controls
Things relevant to your SRV, but not your ship.
* `[recall;dismiss] ship`: Recalls or dismisses ship. Currently does the same
thing regardless of the state of your ship. I wish it would be possible to
restrict it to doing one thing each, but thats currently not possible sadly.
* `[toggle;enable;disable] drive assist`: Handles all your drive assist needs!
## Targeting
Well … targeting stuff, I guess. Not really sure why I made that its own
category, but oh well :)
* `target the [drive;drives;power plant;frame shift drive;f s d;shield
generator]`: Targets the given submodule on your current target, or your next
target if you dont have one currently. Does not persist between targets.
* `clear sub [module;system] target`: Clears the current submodule target.
* `target next system`: Selects the next system on your route.
* `target wing man [1;2;3]`: Targets your wingmen.
* `targets target`: Targets your targets target (only works on wingmen).
* `wing man [1;2;3] target`: Targets your wingmens target.
* `wing man nav lock`: Toggles wing man nav lock on the selected wing member.
## UI Commands
Everything handling stuff thats not related to controlling your ship, but
manipulating some UI element(s).
* `[enter;leave] F S S`: Opens/closes FSS.
* `[main;game] menu`: Opens the ESC menu.
* `[relog;reset] to [open;solo]`: Relogs to Open or Solo mode, respectively.
* `controls options`: Opens the controls options menu.
* `docking request;request dock[ing;]`: Sends a docking request.
* `galaxy map`: Opens the galaxy map.
* `restart from Desktop`: Quits the game and restarts from an open launcher by
clicking the play button.
* `set [default;star;station;settlement;signal sources;anomaly;unknown;system] filter`:
Sets a nav panel filter setting. See the command or just try different things
for what is possible. You need to clear filters and hover over the filter
button, then run this.
* `system map`: Opens the system map.
* `take [high res;] screenshot`: Takes a (high res) screenshot.
* `toggle orbit lines`: Toggles the visibility of orbit lines.
## Miscellaneous
The commands in here do random more or less useful things.
* `[are there any;] outdated stations [in this system;]`: Runs an on-demand
check for outdated stations in the current system.
* `[bodies;whats;what is] left to [map;be mapped;scan]`: Tells you which bodies
EDDI thinks are worth mapping in the system that you havent mapped yet.
* `copy current system`: Copies the current system name into the clipboard.
* `open [current;] system on EDSM`: Opens your current system on EDSM in your
default browser.
* `open copied system on EDSM`: Opens the system in your clipboard on EDSM in
your default browser.
* `open coriolis`: Opens Coriolis in your default browser.
* `open e d d b [station;system;faction;] [search;]`: Opens EDDB in your default
browser.
* `open e d s m`: Opens EDSM in your default browser.
* `open inara`: Opens Inara in your default browser.
* `open materials finder`: Opens EDTutorials materials finder in your default
browser.
* `open miners tool`: Opens https://edtools.cc/miner in your default browser.
* `open spansh`: Opens https://spansh.uk in your default browser.
## Events
This is a list of ingame Events, [provided by
EDDI](https://github.com/EDCD/EDDI/wiki/VoiceAttack-Integration), that the
profile will act on.
### AFMU Repairs
Reports on the module that has been repaired, and if it has been fully or
partially repaired.
### Body Mapped
Announces an estimate for high-value bodies payouts and the remaining mapping
candidates in the system as given by EDDI.
### Body scanned
Announces any interesting body traits found when scanning:
* terraformable
* Earth-like World, Ammonia World or Water World
* landable and >5g
* semimajor axis <1.5ls (only really interesting for planets, but theres no
proper way to separate them from moons, sadly)
* radius <300km
Feel free to suggest more!
### Carrier Cooldown
Tells you when your carrier is able to do its next jump.
### Carrier Jump Engaged
This event fires when your carrier jumps but you are _not_ docked at it. It
provides way less information than the `Carrier Jumped` event, but hey, I dont
use most of it anyway. Basically just calls `Carrier Jumped`.
### Carrier Jump Request
Announces the system and body your carrier has just been scheduled to jump to.
Use this to double check ingame information; Ive had my carrier accept a body
as jump target, but then end up around the star. This _might_ give you a heads
up on that.
Also starts a command queue to give you advance warnings on carrier lockdown at
-10, -5 and -2 minutes.
### Carrier Jumped
Announces system and body your carrier has just jumped to.
### Carrier Pads Locked
Announces your carriers lockdown procedures.
### Discovery Scan
Announces the number of bodies (and non-body signals) found in the system. Also
compares the number of bodies to the amount reported by EDSM (requires Python
scripts).
### Docked
Automatically refuels, repairs, rearms, then gets your ship into the hangar and
opens station services. Can be individually disabled.
### Docking Denied
Tells you the reason for docking denial.
### Entered Normal Space
Throttles to 0 upon dropping from SC, if the hyperspace dethrottle option is
enabled.
### Fighter Launched
Orders your ship to hold position so it doesnt chase after you immediately.
### Jet Cone Boost
Sets your ship to full throttle immediately after you have supercharged.
### Jumped
* Zeroes throttle if the hyperspace dethrottle option is enabled.
* Gets the systems body count from EDSM if that option is enabled.
* Gets stations with outdated data (by default: older than 1 year) from Spanshs
API. Again, if it is enabled.
* Starts a discovery scan if that is enabled.
* Last but not least tells you about planets worth scanning if you are on the
R2R.
### Liftoff
Retracts landing gear for you. Seriously, is there any occasion in which you
_dont_ immediately want to retract it after takeoff?
### Low Fuel
Warns you when you reach 25% fuel. Also reports number of jumps you have left or
the (rough) range you still have on the fumes left in your tank.
### Material Threshold
Warns you when a monitored material falls below its minimum stock level and
tells you when you reach your desired level or fill up.
You will have to set minimum and desired amounts in EDDIs material monitor
options first for all materials you wish to be monitored.
### Next Jump
Gives you a jump count upon plotting a route using the galaxy map.
### Ship FSD
This event actually is several different events in one. Currently the following
are handled:
* Charging: Warns you if you are jumping with less than 25% fuel.
* Cooldown complete: Announces FSD cooldown if you are currently in normal
space.
### Ship Interdicted
Tells you when you have been interdicted by a player. Is also supposed to target
the interdictor automatically, but randomly sometimes just doesnt work. Yay!
### SRV Launched
Toggles SRV lights off after launching. Might not work if you drop particularly
far after deployment because it works off a timer. Conversely might take a
second to turn your lights off on a short drop and/or in high gravity.
### Synthesis
Reports on the synthesis type and quality.
### System Scan Complete
Lists all bodies EDDI considers worth mapping in the current system.
### Undocked
Retracts landing gear for you. Seriously, is there any occasion in which you
_dont_ immediately want to retract it after takeoff?

View file

@ -1,31 +0,0 @@
# EliteDangerous #
This is my personal VoiceAttack profile for Elite: Dangerous. It started out
ages ago as a modification of [MalicVRs public
profile](https://forums.frontier.co.uk/threads/malics-voice-attack-profile-for-vr.351050/),
then looked less and less and less like that and I added and cleaned up a lot of
things while removing the stuff I didnt use anyway. By now it would have
probably been simpler starting from scratch.
Some of it has grown to a state that it might be useful to others in its own
package, so Ive separated the neutron jumping and Seals stuff into their own
profiles.
The rest is a random conglomerate of all things VA and E:D; from various voice
commands and some buttons that are now being handled by VA to lots of EDDI event
handlers.
Speaking of EDDI; it has become in integral part of my Elite experience,
especially the plethora of information it extracts from the games journal and
presents to you via lots and lots of status variables and by firing various
events that can then be handled through VA commands. Its great. Check it out.
(You might want to make it talk a lot less in its personality options, or
disable the speech responder entirely like I have.)
This profile doesnt have and probably never will have an exhaustive
documentation (or basically any documentation at all). That said, the commands
themselves have some comments that might be useful in understanding what they
do. If one does(t, bug me until it does.
Go through the thing, look at what is possible with some fiddling, then do your
own crazy shit :D

View file

@ -0,0 +1,110 @@
# RatAttack
This profile facilitates [Fuel Ratting](https://www.fuelrats.com). It aims to
eliminate as much of the required manual task and attention switching as
possible via automation and voice commands.
If you dont know what the Fuel Rats are, come hang out and ask :)
## Going On/Off Duty
When you are on duty, RatAttack will automatically announce cases coming in
through IRC. When off duty, it wont.
* `[enable;disable] rat duty`: puts you on/off duty.
* `open [fuel rats;] dispatch board`: opens the web dispatch board.
## Case Handling
[If you have your IRC client setup
properly](../configuration/RatAttack/#getting-case-data-from-irc), VoiceAttack
will hold a list with all rat cases that have come in while you had it running.
It will save the case number, CMDR name, system, O₂ status and platform. There
are several commands you can run on this list, giving it a case number:
### Getting Case Information
* `rat case number [0..30] details`: Will give you all stored info on a case.
* `[current;] rat case details`: Will give you all stored info on the currently
open case.
* `distance to current rat case`: Will give you the distance from your current
location to the currently opened rat case.
* `distance to rat case number [0..30]`: Will give you the distance from your
current system to a cases system.
* `latest rat case details`: Will give you the case data for the latest incoming
case.
* `nearest commander to rat case number [0..30]`: Will give you the nearest of
your CMDRs with their distance to a cases system. [Requires some
setup](../configuration/RatAttack/#announcing-your-nearest-cmdr).
* `nearest commander to [the;] rat case`: Will give you the nearest of your
CMDRs with their distance to the current cases system. [Requires some
setup](../configuration/RatAttack/#announcing-your-nearest-cmdr).
### Opening a Case
* `open rat case number [0..30]`: Opens rat case with the given number. If there
is no case data for that case (e.g. because you dont have your IRC client set
up properly), it will still open it, just not have any data on it.
* `open [latest;] rat case`: Opens the latest rat case that has come in through
IRC. Will only work if you actually have [your IRC client setup to send case
announcements to
VoiceAttack](../configuration/RatAttack/#getting-case-data-from-irc).
Opening a case will automatically copy the clients system to the clipboard for
easy route plotting. This can be disabled.
### Making Calls ###
There are a bunch of calls you can make for a case, the most common are modelled
through VoiceAttack commands. The descriptive commands (e.g. “system confirmed”)
will be shortened to the usual IRC short hands (e.g. “sysconf”). If you need
something more unusual you can either still manually type it into your IRC
client or use the “General IRC Integration”, see below.
* `call [1..20] jumps [and login;and takeoff;left;]`: Calls jumps for the
currently open case. You can optionally include that you will still have to
login to the game or have to take off from your current
station/port/outpost/planet.
* `call jumps [left;]`: Calls jumps for the currently open case based on a
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;]`:
Friend request confirmations, with all the
things you might want to / should call with it.
* `call [beacon;fuel;instance;pos;position;prep;sys;system;wing] [positive;negative]`:
All the stuff you usually need for ratting after you have received the friend request.
* `call wing pending`: Calls “wr pending” for when it takes 30s again to
actually show up.
* `call client in [exclusion zone;main menu;open;open sysconf;pg;private group;solo;super cruise]`:
Callouts for all the various things a client could get themselves into.
* `call [client destroyed;client offline;sysconf;system confirmed]`: This is the
command you dont want to use. Include sysconf in your “friend+” or “in open”
calls, and make sure you will never have to call “client destroyed”, would
you?
By default, VoiceAttack will ask for confirmation before sending calls to the
`#fuelrats` channel.
### Closing a Case
* `[close;clear] rat case`: Closes the currently open rat case.
## General IRC Interaction
Using EDDI to read the games journal, you can send messages to IRC from Elites
ingame chat.
**Be aware that the chat message will still appear in the ingame chat channel
you send it to!**
I recommend using local chat and limiting the use to instances that will
probably not have other players in it (e.g. instanced in normal space with the
client or in SC in some remote system out in the black on a long range rescue).
* \#fuelrats: Use `.fr <message>` to have VoiceAttack send
`#<caseNumber> <message>` to \#fuelrats or yell at you when you
are not on a case.
* \#ratchat: Use `.rc <message>` to have VoiceAttack send `<message>` to
\#ratchat.
Make sure [that your IRC client is setup
properly](../configuration/RatAttack/#sending-text-to-fuelrats-irc).

View file

View file

@ -1,103 +1,91 @@
# SpanshAttack #
# SpanshAttack
This profile uses the
[ED-NeutronRouter](https://github.com/sc-pulgan/ED-NeutronRouter) plugin to plot
neutron jumps using [spansh](https://spansh.co.uk/plotter). It fully does
everything you need from within the game and VoiceAttack, you wont have to
visit the site at any point.
[ED-NeutronRouter](https://github.com/sc-pulgan/ED-NeutronRouter) plugin to
plot neutron jumps using [Spansh](https://spansh.co.uk/plotter). It does
everything you need fully from within the game and VoiceAttack, you wont have
to visit the site at any point.
## Settings ##
Because Elites keyboard handling is … weird youll have to set the key to use
for pasting text into Elite:Dangerous. If you are using a “standard” QWERT[YZ]
layout, you dont have to do anything; if you are using something different, you
have to set it to the symbol thats on the physical button that has `v` on
QWERT[YZ]. E.g. for Neo2, set it to `p`.
For other settings, see the [Configuration Variables](#Configuration-Variables)
section.
The last “setting” in the not-so-strict sense of the word is the
`SpanshAttack.getShipRange` command. Any ship listed in there will automatically
have its jump range used instead of VA prompting you for it. Since, again, VA
will execute the first matching command found, you can create this command in
your own profile when you are using SpanshAttack by including it.
The ED-NeutronRouter plugin is technically supposed to read the current jump
range from EDDI; sadly a) its
[bugged](https://github.com/sc-pulgan/ED-NeutronRouter/issues/3) right now, and
b) EDDI is storing the _maximum_ distance for your ship instead of the current
/ full on fuel one.
## Importing the Profile ##
When importing the prifle, be sure to
* Run the startup command. You will need to have a startup command in your
profile (= one that is run on profile loading) and call `SpanshAttack.startup`
from that one.
* Set configuration options. In the same startup command of yours, overwrite all
configuration variables you want changed; _after_ the `SpanshAttack.startup`
call. See [below](#Configuration-Variables).
* Make sure all EDDI events that SpanshAttack needs are correctly handled. For
all events used in Spanshattack that you already have handelrs for in your
profile, youll have to include a call to `SpanshAttack.<event name>`. E.g.
for “EDDI Jumped”, call `SpanshAttack.EDDI Jumped` by name from your `((EDDI
Jumped))` command.
* Initialise the [bindED](https://forum.voiceattack.com/SMF?topic=564.0) plugin
correctly to read your Elite keybinds. Do that in your main profiles startup
command to only have it run once.
* (Optional) Have a `SpanshAttack.getShipRange` command in your profile to
overwrite the default one with your ships ranges. See the default command for
pointers.
## Usage ##
### Plotting a Route ###
## Plotting a Route
1. _Target_ the system you want to be routed to (target, do not plot to it).
1. Either exit the galaxy map or make sure you are on its first tab (or
auto-plotting will break).
1. Trigger the `SpanshAttack.plotRoute` command either by voice (`plot neutron
[course;route;trip]`) or calling it from another command
1. (if ship not listed in `SpanshAttack.getShipRange`) Enter your ships jump
range when prompted.
1. Trigger the `SpanshAttack.plotRoute` command either by voice
(`plot neutron [course;route;trip] [with custom range;]`) or by
calling it from another command.
1. Enter your ships jump range if prompted.
1. Wait for the route to be calculated. The command will automatically open the
galaxy map and jump to the first waypoint on your route.
galaxy map and search it for the first waypoint on your route.
1. Either target the first waypoint or plot to it.
1. Start jumping!
### Neutron Jumping ###
### Plotting to a System Unknown to the Neutron Router
The router can only plot a route to a system that is in its database (obviously
can also only give you waypoints that are). If your target system is not, there
are several levels of fallback handling to find a system that is.
1. Check `Next system` coordinates provided by EDDI. If the system is in EDSM,
but has for some reason not been sent over EDDN to other sites including
Spansh, we can get coordinates here.
1. If the system is not in EDSM check EDTS. It can calculate approximate
coordinates for a given procedurally generated system name.
1. If that fails prompt the user for input.
1. Query Spansh API for the closest system to these coordinates.
1. Plot a route to the closest system.
Generally you should almost never be asked to input coordinates manually. If
EDTS provides coordinates with an accuracy that is worse than ±100ly per axis,
you will be prompted to make sure you are going roughly to the right
coordinates. You will find the system that is used for plotting, its
coordinates and the accuracy in VoiceAttacks log window.
## Neutron Jumping
With standard settings, just supercharge off a neutron cone. You should
automatically be taken to the galaxy map with the next waypoint selected.
In case you have disabled auto-plotting to the next waypoint, manually invoke
the `SpanshAttack.targetNextNeutronWaypoint` command by voice (`[target;] next
neutron [waypoint; way point]` or calling it from another command.
the `SpanshAttack.targetNextNeutronWaypoint` command by voice
(`[target;] next neutron [waypoint; way point]`) or calling it from
another command.
Additionally, you can use the `SpanshAttack.getNextNeutronWaypoint`
Additionally, you can use the `SpanshAttack.copyNextNeutronWaypoint`
/ `[get;copy] next neutron [waypoint;way point]` command to copy the next
neutron waypoint to the clipboard.
#### Manual Re-Plot ####
### Skipping a Waypoint
Trigger the `SpanshAttack.replotRoute` command either by voice (`replot neutron
[course;route;trip]`) or calling it from another command. This will start
a re-plot of the current route with the same target system and jump range.
Sometimes, especially in very neutron-sparse areas of the galaxy, the plotter
will give you weird jumps. E.g. I recently got neutron → 37 ly → neutron → 440
ly.
### Refueling ###
In these cases you can use the `SpanshAttack.skipNeutronWaypoint` / `skip
[this;current] neutron waypoint` command to move on to the next one in the
list.
Whenever you refuel off a scoopable star, the profile will automatically
throttle back up to 100% speed.
### Manual Re-Plot
### Clearing a Route ###
Trigger the `SpanshAttack.replotRoute` command either by voice
(`replot neutron [course;route;trip]`) or calling it from another command.
This will start a re-plot of the current route with the same target system and
jump range.
When you reach your target system, the neutron route will automatically be
cleared. If you want to prematurely end your trip, call the
## Refueling
Whenever you finish refueling off a scoopable star, the profile will
automatically throttle back up to 100% speed. Unless you have disabled it in
your configuration, you will also automatically target the next system on your
route and jump to it once you leave fuel scoop range.
## Clearing a Route
When you reach your target system the neutron route will automatically be
cleared. If you want to prematurely end your trip, call the
`SpanshAttack.clearRoute` / `clear neutron [course;route;trip]` command.
## Other Commands ##
## Other Commands
### Announcing Jumps Left ###
@ -114,49 +102,4 @@ neutron waypoint_.
SpanshAttack keeps track of your start time, even if you have the option to time
your trip turned off. This way you can get the time youve been jumping with the
`SpanshAttack.announceTripTime` or
`how long have i been [jumping;on this trip;on this neutron trip]?` commands.
### Helper Functions ###
The profile contains a lot of helper functions that get called by the
aforementionde commands. Have a look around, maybe learn something about
VoiceAttack :)
## Exposed Variables ##
The following Variables are _global_ and thus readable (and writeable! please
dont unless its a config variable …) from other profiles:
### Configuration Variables ###
These are set in `SpanshAttack.startup` and can be overriden from your profile
if you have imported SpanshAttack.
* Elite.pasteKey (string): the key used for pasting into Elite. On QWERTY this
is `v`. Default: `v`.
* SpanshAttack.timeTrip: whether to automatically tell you at the end of a trip
how long it to you to get there. Default: false.
* SpanshAttack.announceWaypoints (boolean): whether to announce each waypoint of
the neutron route. Default: true.
* SpanshAttack.announceJumpsLeft (string): `;`-separated list of remaining jumps
to announce when said amounts are reached. Right now only works if they are
_exactly_ reached when supercharging off a neutron. Note the extra `;` at the
beginning and end of the string. Default: `;1;3;5;10;15;20;30;50;75;100;`
* SpanshAttack.autoPlot (boolean): whether to automatically plot to the next
waypoint on supercharging. Default: true.
* SpanshAttack.copyWaypointToClipboard (boolean): whether to copy the next
waypoint into the Windows clipboard for use in other programs. Default: false.
* SpanshAttack.useEddiForVoice (boolean): whether to use EDDI over VAs builtin
`say` command. Default: false.
### Other Variables ###
These variables can be used to get information about the current neutron route.
Please do not set them manually and / or from outside the SpanshAttack profile.
* SpanshAttack.targetSystem (string): the target system for the current neutron
route
* SpanshAttack.nextNeutronWaypoint (string): the next waypoint on the current
neutron route
* SpanshAttack.neutronJumpMode (boolean): neutron jump mode active/inactive
* SpanshAttack.jumpRange (decimal): the current ships jump range
`how long have i been [jumping;on this trip;on this neutron trip]?` commands.

52
docs/StreamAttack.md Normal file
View file

@ -0,0 +1,52 @@
# StreamAttack
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
to files that can be accessed e.g. by your streaming software to be displayed on
stream.
Default folder is `%appdata%\StreamAttack\`.
## Commands
* `clear jump target`: Clears the current jump target.
* `distance [to;from] jump target`: Tells you the current distance to the jump
target.
* `set jump target`: Sets the jump target to the currently targeted system.
Distance will be written to the configured file.
* `[copy;open] ship build`: Copies the current ship build (coriolis) or opens it
in your default browser.
* `open StreamAttack folder`: Opens the configured folder in Explorer.
## Output Files
### 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
* `Elite\cmdr\name`: The current commanders name.
#### Jump Target
* `Elite\jumpTarget\distance`: Distance to current jump target in light years.
* `Elite\jumpTarget\full`: Pretty-printed `<distance> ly to <name>`.
* `Elite\jumpTarget\name`: The current jump targets system name.
#### Location
* `Elite\location\full`: Depending on your status, either the station you are
currently docked at (+ system), the body you are currently near, or the system
you are currently in.
* `Elite\location\system`: The system you are currently in.
#### Ship
* `Elite\ship\build`: Your current ships loadout (link to coriolis).
* `Elite\ship\full`: `“<name>” | <model> | <build>`.
* `Elite\ship\model`: Your current ships model.
* `Elite\ship\name`: Your current ships name.

4
docs/VoiceAttack.md Normal file
View file

@ -0,0 +1,4 @@
# VoiceAttack Tips
This will fill up eventually with tips on how to properly setup VoiceAttack for
decent recognition.

View file

@ -0,0 +1,53 @@
# EliteAttack
## Settings
Toggles:
* `auto honk all systems`: Automatically honk upon entering a system, each jump,
without constraints. Default: false.
* `auto honk new systems`: Automatically honk upon entering a system if it is
your first visit. Default: true.
* `auto refuel`: Automatically refuel after docking at a station. Default:
true.
* `auto repair`: Automatically repair after docking at a station. Default:
true.
* `auto restock`: Automatically restock after docking at a station. Default:
true.
* `auto move to hangar`: Automatically move the ship to the hangar after docking
at a station. Default: true.
* `auto enter station services`: Automatically enter the Station Services menu
after docking at a station. Default: true.
* `auto retract landing gear`: Automatically retract landing gear when lifting
off a planet / undocking from a station. Default: true. (#133)
* `auto disable s r v lights`: Automatically turn SRV lights off when deploying
one. Default: true. (#133)
* `edsm system status`: Pull system data from EDSM and compare it
against your discovery scan. Default: true.
* `discovery scan on primary fire`: Use primary fire for honking instead of
secondary. Default: false.
* `flight assist off`: Permanent Flight Assist off mode. You should really do
that, its great. Default: false.
* `hyper space dethrottle`: Throttle down after a jump and when dropping from
SC. Like the SC Assist module does. Default: true.
* `limpet check`: Do a limpet check when undocking, reminding you if you forgot
to buy some. Default: true.
* `mapping candidates`: Announce bodies worth mapping when you have finished
scanning a system. (Terraformables, Water Worlds, Earth-Like Worlds and
Ammonia Worlds that have not been mapped yet.) Default: true.
* `outdated stations`: Announce stations with outdated data in the online
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.
* `road to riches`: Announce bodies worth scanning if you are looking for some
starting cash on the Road to Riches. Default: false.
* `route jump count`: Give a jump count on plotting a route. Default: true.
* `synthesis reports`: Report on synthesis. Default: true.
Other settings:
* `outdated station threshold`: The threshold for station data to count as
“outdated”, in days. Default: 365.
* `scanner fire group`: The fire group your discovery scanner is assigned to.
Default: 0 (the first one).

View file

@ -0,0 +1,108 @@
# RatAttack
## Getting Case Data From IRC
You can setup your IRC client to pass incoming RATSIGNALS to VoiceAttack by
calling the `RatAttack-cli.exe` helper tool with the RATSIGNAL as first argument
and an optional boolean as second argument that triggers a TTS case
announcement. You can find it under your VoiceAttack “Apps” folder,
`\alterNERDtive\RatAttack-cli.exe`.
**Note**: If you are running VoiceAttack as admin, you need to run your IRC
client as admin, too! Otherwise they cannot communicate. In general you want to
run both with normal privileges.
This has two purposes:
1. Announcing a new incoming case (if passing `true` as second argument).
1. Storing case data and making it available to VoiceAttack, e.g. for copying
the clients system into the clipboard.
For my AdiIRC, it looks like this (obviously change the path, please):
```adiirc
on *:TEXT:*RATSIGNAL*(??_SIGNAL):#fuelrats:{
if ( $away ) {
/run -h "X:\path\to\VoiceAttack\Apps\alterNERDtive\RatAttack-cli.exe" " $+ $replace($1-,","") $+ " false
}
else {
/run -h "X:\path\to\VoiceAttack\Apps\alterNERDtive\RatAttack-cli.exe" " $+ $replace($1-,","") $+ " true
}
}
```
If I am away it will just add the new case to the list. If I am not away, it
will announce it using TTS.
The “replace” part handles the fact that announcements now put the system in
quotes. They have to be escaped as double quotes (`""`) to create a correct
command invocation.
You get the gist; if not and you dont know how to do the same thing for your
IRC client, either switch to AdiIRC or bribe me to make an example for yours.
mIRC is a straight forward copy & paste job from Adi to mIRC (“Tools” → “Script
Editor” → “Remote”). Make sure you do not strip colour codes from incoming
messages!
Note for Hexchat users: Hexchat doesnt seem to have a simple way of doing this.
If you figure it out, Ill gladly add instructions here.
Keep in mind that if you are not on duty (see below) you will _not_ get case
announcements.
## Announcing Your Nearest CMDR
In case you have more than one CMDR registered as a Fuel Rat you can have
VoiceAttack announce the nearest one to a case and the distance. You will have
to go through a couple steps to set that up:
1. Have all CMDRs on EDSM.
1. Have all profiles on EDSM set to _public_ including your flight log (which
includes the current location).
1. Set the CMDR names you want to use (“customize setting set fuel rat
commanders”).
1. Enable the nearest CMDR announcements (“customize setting enable nearest
commander to fuel rat case”).
You can use this for a single CMDR, too. A less convoluted setup for announcing
the distance to your location in that case is on the list™ but does not have an
ETA yet.
Currently there is no way to specify a platform for each CMDR separately.
## Sending Text to FuelRats IRC
The profile will attempt to send calls to “\#fuelrats”, and you can send
messages from ingame chat to “\#fuelrats” and “\#ratchat”.
That will send text to windows with “\#fuelrats” and “\#ratchat” in
their title, respectively. If your IRC client does not do that, you will have to
change the “target” window of the `RatAttack.sendToFuelrats` and
`RatAttack.sendToRatchat` commands to reflect the actual window titles on your
system. I will look into making this more elegant to change in the future.
## Settings
Toggles:
* `auto close fuel rat case`: Automatically close a rat case when sending
“fuel+” via voice command or ingame chat. Default: false.
* `auto copy rat case system` : Automatically copy the clients system to the
clipboard when you open a rat case. Default: true.
* `fuel rat call confirmation`: Only make calls in #fuelrats after vocal
confirmation to prevent mistakes. Default: true.
* `fuel rat duty`: On duty, receiving case announcements via TTS. Default: true.
* `nearest commander to fuel rat case`: Announce the nearest commander to
incoming rat cases. Default: false.
* `platform for fuel rat case`: Announce the platform for incoming rat cases.
Default: false.
* `system information for fuel rat case`: System information provided by Mecha.
Default: true.
Other Settings:
* `fuel rat commanders`: All your CMDRs that are ready to take rat cases. Use
; as separator, e.g. “Bud Spencer;Terrence Hill”. Default: "".
* `fuel rat platforms`: The platform(s) you want to get case announcements for
(PC, Xbox, Playstation). Use ; as separator, e.g. “PC;Xbox”. Default: "PC".

View file

@ -0,0 +1,47 @@
# SpanshAttack
## Supplying Your Ships Range
The ED-NeutronRouter plugin is technically supposed to read the current jump
range from EDDI; sadly EDDI is storing the _maximum_ distance for your ship
instead of the current / full on fuel one. The “default to laden range” option
works reasonably well, but it has a few quirks. It always assumes full cargo,
and it will take your _current_ fuel levels for range calculations, disregrading
the range loss if you fill your tank.
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
have with full fuel and your preferred amount of cargo/limpets.
In order to do that, copy the `SpanshAttack.getShipRange` command from
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
EDDIs reported laden range or VoiceAttack prompting you to manually supply it.
![[SpanshAttack-getshiprange.png]]
You can override a saved range for your ship by using the
`plot neutron [course;route;trip] with custom range` command.
## Settings
Toggles:
* `auto jump after scooping`: Automatically jump out when fuel scooping is
complete. Default: true.
* `auto plot`: Automatically plot to the next waypoint after supercharging.
Default: true.
* `clear neutron route on shutdown`: Clear an active neutron route when the game
is shut down. Default: true.
* `copy neutron waypoints to clipboard`: Copy each neutron waypoint into the
Windows clipboard. Default: false.
* `default to laden range`: Default to the current ships laden range as
reported by EDDI instead of prompting for input. Default: false.
* `time neutron route`: Keep track of how long a neutron route takes you to
complete. Default: false.
* `waypoint announcements`: Announce each waypoint by name. Default: true.
Other Settings:
* `announce jumps left`: Estimated jumps left to announce when reached. NEEDS to
have leading and trailing “;”. Default: ";1;3;5;10;15;20;30;50;75;100;"

View file

@ -0,0 +1,6 @@
# StreamAttack
## Settings
* `StreamAttack output directory`: The directory the status files are written
to. Default: "%appdata%\StreamAttack\"

View file

@ -0,0 +1,77 @@
# General Configuration
## Settings
All profiles will load sane defaults if you havent changed anything. The
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
with their own distinct settings.
The easiest way to change settings is to say `customize settings`. That will
bring up a rudimentary settings UI.
You change also change the configuration directly via voice commands:
* For toggles (booleans): `customize setting [enable;disable] <trigger phrase>`
* For everything else: `customize setting set <trigger phrase>`
You can find a list of trigger phrases on this page, or you can say
`customize setting list [options;settings]` for a list of voice triggers and
what they do. If you dont remember your settings or just want a nice list,
`customize setting report [options;settings]` will print that to the
VoiceAttack log. If you want to reset everything back to default state, say
`customize setting clear all my settings`.
The “customize setting” prefix is kind of a leftover from times long gone and
does not quite fit anymore. Might change in a future version.
Since the settings are saved to your custom profile they will not necessarily be
preserved when you switch profiles. Once you switch back, the correct settings
for the profile are re-loaded.
### General Settings for All Profiles
Toggles:
* `auto update check`: Automatically check Github for profiles updates when the
profile loads. Default: true.
* `eddi quiet mode`: Make EDDI shut up. Disables all built-in speech responders.
Default: true.
Other settings:
* `elite paste key`: The key used to paste in conjunction with CTRL. The
physical key in your layout that would be 'V' on QWERTY. Default: 'v'.
* `log level`: The level of detail for logging to the VoiceAttack log. Valid
levels are "ERROR", "WARN", "NOTICE", "INFO" and "DEBUG". Default: "NOTICE".
* `quit to desktop delay`: The delay before restarting the game after hitting
“Exit to Desktop”, in seconds. Default: 10.0. (Used by the `restart from desktop`
command)
## Note on Non-Standard Keyboard Layouts
Because Elites keyboard handling is … weird youll have to set the key to use
for pasting text into Elite Dangerous if you are not using a keyboard layout
that the game supports by default. You will have to change it to the key that
is physically in the place where `V` would be on QWERTY, e.g. `P` for
[Neo2](https://neo-layout.org).
To set the key, say “customize setting set elite paste key”.
## Adding Commands
If you want to edit a command or add your own, _do not edit the profiles
directly_. Instead create commands in your custom profile, and copy commands you
want to change over to that before editing them. This will make sure no changes
are lost if you update the profiles.
### EDDI Events
Because of limitations of VoiceAttack itself, only the first matching command
found will be executed, _including EDDI events_. That means that if you create
commands to handle EDDI events, you are going to have to make sure that the
appropriate handlers in my profiles are called, too. That is done by invoking
the `eddi.Event` plugin context of the `alterNERDtive-base` plugin. Otherwise
stuff _will_ break.
![[EDDI-event.png]]

41
docs/general.md Normal file
View file

@ -0,0 +1,41 @@
# General Commands
## Configuration
The base profile provides voice commands for changing the profiles settings.
See [the configuration section](../configuration/general#settings).
## Chat
* `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
configured paste key. If youre using a non-standard layout that means that
you _cannot_ use this command to paste text into other applications.
## Updating
* `check for profiles update`: Checks Github for a new version, and alerts you
if there is one.
* `download profiles update`: Opens the latest release on Github and the
VoiceAttack import folder where you can drop it.
* `open profiles [docs;documentation;help] [file;site;]`: Opens this
documentation, either on the web or the PDF file supplied with the installed
release.
* `open profiles change log`: Opens the CHANGELOG on Github.
* `open voiceattack [apps;import;sounds] [folder;directory]`: Opens the
respective VoiceAttack-related folder.
## Miscellaneous
* `generate missing key binds report`: Generates a report of missing key binds
and places it on your Desktop. Note that this currently uses bindEDs built-in
report which will output _any_ bind that does not have a keyboard key set,
including axis binds and binds that are not actually used by the profiles.
* `open documentation`: Opens the documentation in your default browser.
* `open EDDI options;configure EDDI`: Displays EDDIs configuration window.
* `open elite bindings folder`: Opens Elites bindings folder
(`%localappdata%\Frontier Developments\Elite Dangerous\Options\Bindings`)
* `reload elite key binds`: Forces a reload of your Elite binds. Should not be
necessary.
* `shut up EDDI`: Immediately interrupts any current and pending speech on
EDDIs end.

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
docs/images/EDDI-event.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
docs/images/Elite-COVAS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

BIN
docs/images/Elite-binds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

43
docs/index.md Normal file
View file

@ -0,0 +1,43 @@
# Elite Dangerous VoiceAttack Profiles
These are various profiles for [VoiceAttack](https://voiceattack.com) (VA) I use
to enhance my Elite experience. They give me important info, facilitate
day-to-day gaming and do some special things for [Fuel
Rats](https://fuelrats.com) and [Hull Seals](https://hullseals.space) work.
**NOTE**: Further development is on hold and Odyssey compatibility will not be
worked on for the time being. See [the corresponding issue on
Github](https://github.com/alterNERDtive/VoiceAttack-profiles/issues/113). This
might or might not change after the Horizons/Odyssey merge. Feel free to file
issues for anything that is broken on Odyssey and it will be worked on when it
is worked on.
## Available Profiles
* [EliteAttack](EliteAttack): The main Elite VA profile. Anything related to
“just” playing the game.
* [RatAttack](RatAttack): Manages interactions with the FuelRats IRC server.
* [SpanshAttack](SpanshAttack): Plots and follows trips along the neutron
highway using [Spanshs neutron plotter](https://spansh.co.uk/plotter).
* [StreamAttack](StreamAttack): Writes various status things to files that can
then be read by streaming software like OBS.
They all require the `alterNERDtive-base` profile that, well, provides basic
functionality common to all of the above.
## Need Help / Want to Contribute?
Well, you are in the right place. You can find comprehensive documentation right
here.
If you run into any errors, please make sure you are running the latest version
of the profiles and all [requirements](requirements.md).
If your problem persists, please [file an
issue](https://github.com/alterNERDtive/VoiceAttack-profiles/issues). Thanks! :)
You can also [say “Hi” on Discord](https://discord.gg/kXtXm54) if that is your
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)

238
docs/installing.md Normal file
View file

@ -0,0 +1,238 @@
# Installing
## Install VoiceAttack
Grab the [most recent VoiceAttack beta
version](https://voiceattack.com/#download-1) off the official site and install
it.
If you are using the standalone version you should probably download the
executable installer.
![[VoiceAttack-download.png]]
If you are using the Steam version of VoiceAttack, you will have to download the
zipped folder and replace your installed version with its contents.
[Here is the first hit on a Google search for finding the installation
folder](https://steamcommunity.com/sharedfiles/filedetails/?id=760447682). It is
for a completely unrelated game, but the steps are the same.
You can potentially also install the latest non-beta version; but I often use
features that have only just been added to the beta, so some things might break
for you if you are not using that. There might not be a beta version at the time
youre reading this, just get the full release then.
### Enable Plugin Support
Make sure you have plugin support enabled:
1. Go to VoiceAttack settings. ![[VoiceAttack-settings.png]]
1. Check “enable plugin support”. ![[VoiceAttack-settings-plugin-support.png]]
While you are there, you might also want to enable the automatic update checks
(Note: those settings do not exist in the Steam version).
![[VoiceAttack-settings-updates.png]]
## Install EDDI
Install [the latest release](https://github.com/EDCD/EDDI/releases/latest) from
Github (The `EDDI-X.Y.Z.exe` file under “Assets”). You will need to [install it
as a VoiceAttack
plugin](https://github.com/EDCD/EDDI/wiki/VoiceAttack-Integration#using-eddi-with-voiceattack).
If you do not want to install it into the VoiceAttack installation folder (or
already have it installed somewhere else) you can instead put it elsewhere and
create a symbolic link. Open a command prompt (Windows key + `R`, enter “cmd”,
hit `Enter`) and do
```cmd
>cd x:\path\to\VoiceAttack\Apps
>mklink /J EDDI x:\path\to\EDDI
```
If you have installed the non-Steam version of VoiceAttack to the default folder
within “Program Files” you will have to run the command prompt as admin (Windows
key + `R`, enter “cmd”, hit `Control` + `Shift` + `Enter`).
## Install ED-NeutronRouter
Grab [the latest release release from
Github](https://github.com/sc-pulgan/ED-NeutronRouter/releases/latest) (The
`EDNeutronRouter.vX.YZ.zip` under “Assets”). You will have to extract the
contents of the release .zip file to your VoiceAttack Apps folder:
1. Go into VoiceAttack settings. ![[VoiceAttack-settings.png]]
1. Click the folder set as “Apps Folder”. ![[VoiceAttack-apps.png]]
Now extract the contents of the downloaded file into there. Make sure that they
are not naked files under “Apps”, but have their own folder
“Apps\ED-NeutronRouter”! The exact folder name does not matter as long as they
_are_ in a subfolder. Otherwise the plugin will not load.
![[ED-NeutronRouter-folder.png]]
Leave the “Apps” folder open in Windows Explorer, you will need it for the next step.
## Import Profiles Package
Acquire [the latest
release](https://github.com/alterNERDtive/VoiceAttack-profiles/releases/latest)
from Github (the `alterNERDtive-voiceattack-profiles.vax` file under “Assets”).
Put it into VoiceAttacks “Import” folder:
1. Go into VoiceAttack settings. ![[VoiceAttack-settings.png]]
1. Click the folder set as “Apps Folder”. ![[VoiceAttack-apps.png]]
1. Create a sub folder named “Import” if it does not exist yet.
1. Drop the downloaded .vax file into the “Import” folder.
1. Restart VoiceAttack.
1. When prompted, import the profile package. VoiceAttack will restart when completed.
## Create a Custom Profile
Last but not least you are going to create your own custom VoiceAttack profile
for Elite. It will allow you to add your own commands, override any commands in
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
profile example as a basis. Regardless of which way you choose, make sure to
read the [Include Profiles](#include-profiles) section and follow the instructions there!
### Option 1: Create a New Profile Or Use an Existing One
1. Click the “Profile Actions” button, then “Create New Profile”.
![[VoiceAttack-new-profile.png]]
1. Give it a name and add some commands if you want to.
1. Hit “Done” to create the new profile.
Alternatively you can keep using your existing profile. You will still have to
follow the rest of the instructions in this case.
#### Create a Startup Command
First off, hit the “Edit” button in VoiceAttack.
![[VoiceAttack-edit.png]]
If you are using your existing profile (or have just created a fresh one) you
will now have to create the startup command. Hit the “New Command” button.
![[VoiceAttack-edit-new-command.png]]
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
make sure you do not accidentally run it via voice.
![[VoiceAttack-edit-startup.png]]
Add a new action using “Other” → “VoiceAttack Action”→ “Execute Another Command”.
![[VoiceAttack-edit-startup-execute.png]]
Choose “Execute by name (Advanced)” and enter `((alterNERDtive-base.startup))`.
![[VoiceAttack-edit-startup-action.png]]
Make sure to leave “Wait until this command completes before continuing” on and
have this action at the top of the action list for the command. That way you can
be sure that my profiles are initialized properly before your personal startup
actions are processed.
![[VoiceAttack-edit-startup-actionlist.png]]
You can add anything else you want your profile to do when it loads below this
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).
After adding the startup command you will have to right click VoiceAttacks
title bar and choose “Reload Active Profile” or restart VoiceAttack to see it
executed for the first time.
### Option 2: Use the Profile Example
1. Click the “Profile Actions” button, then “Import Profile”.
![[VoiceAttack-import-profile.png]]
1. Navigate to your VoiceAttack Apps folder (see above), go into the
“alterNERDtive” subfolder, choose the profile example and hit “Open”.
![[VoiceAttack-import-profile-open.png]]
Once you are done with the setup and configuration process, you can find a bunch
of example commands with comments on how to do things in this profile. Make sure
to also rename it to something more exciting than “Custom Profile Example”!
## Include Profiles
In order to use my profiles with your custom profile, you will need to take two
additional steps:
1. Include the profiles in your custom profile. That will make all commands
available when your custom profile is active.
1. Create a startup command for your custom profile. You can use it to do
anything you want when your profile loads, but it will also have to run the
startup command for my profiles.
#### Set Profile Options
While editing the profile, hit the “Options” button.
![[VoiceAttack-profile-options.png]]
On the section labeled “Include commands from other profiles”, hit the “…”
button.
![[VoiceAttack-profile-options-include.png]]
Add all my profiles (“alterNERDtive-base”, “EliteAttack”, “RatAttack”,
“SpanshAttack”, “StreamAttack”).
![[VoiceAttack-profile-options-includelist.png]]
Make sure that “alterNERDtive-base” is on top of the list, the order of the
others does not matter. But I like it nice and alphabetical. Technically you can
leave out any profile you are not planning to use. Practically it probably will
not hurt you to just include everything, and it will then be available for you
in the future should you choose to check it out!
Now switch to the “Profile Exec” tab. Tick the “Execute a command each time this
profile is loaded” checkbox, and select the “startup” command you have created
earlier.
![[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
You need to have keyboard binds setup at least as secondary bindings in Elites
controls options. VoiceAttack _cannot_ “push” joystick buttons for you, it can
only do keyboard inputs. Hence its only way to interact with Elite is through
keyboard emulation, even if you otherwise play the game with a controller or
HOTAS. Or racing wheel. Or Rock Band set. Or bananas.
![[Elite-binds.png]]
For the “Galaxy Map” section, make sure that the bindings do not conflict with
the ones in the “Interface Mode” section. The map bindings take precedence and a
conflict leads to VoiceAttack being unable to target systems for you. In that
case you would see it open the map for you and then wiggle the view for a split
second instead of switching tabs over to the system search.
![[Elite-binds-galmap.png]]
Should you use a keyboard layout that is _not_ en-US QWERTY, some keys might not
work out of the box. You can try telling bindED about your keyboard layout by
setting the `bindED.layout#` variable (including the `#`!) to something more
appropriate in your startup command.
![[bindED-layout.png]]
Currently bindED supports the `en-US`, `en-GB` and `de-Neo2` layouts. [You can
find instructions on how to add your own
here](https://alternerdtive.github.io/bindED/troubleshooting/#adding-a-keyboard-layout).

69
docs/requirements.md Normal file
View file

@ -0,0 +1,69 @@
# Requirements
## VoiceAttack
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
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
for our US-based friends).
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
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
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!
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
fixes/additions in beta versions quite often.
## EDDI
[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
game as well as various third-party tools. In this case, you will need to run it
as a VoiceAttack plugin.
EDDI also regularly publishes beta versions. Unless a profiles release
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
built-in speech responders. This can be changed
[via the `EDDI quiet mode` setting](configuration/general.md#general-settings-for-all-profiles).
## bindED
[bindED](https://alterNERDtive.github.io/bindED) reads your Elite Dangerous
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
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
and install it manually, but you _can_ independently update it if a newer
version is available.
## Elite Scripts
I have written a [collection of Python
scripts](https://github.com/alterNERDtive/elite-scripts) to interface with
various 3ʳᵈ party services like EDSM or Spansh. Those are called by the profiles
for various tasks, like checking a systems body count.
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
and install them manually, but you _can_ independently update them if a newer
version is available.
## ED-NeutronRouter
[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.
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.

100
docs/troubleshooting.md Normal file
View file

@ -0,0 +1,100 @@
# Troubleshooting
This will fill up gradually with Troubleshooting tips as people run into common
ones.
## VoiceAttack does not understand me / mishears me / fires random commands
There is [a thread on the VoiceAttack
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.
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
can remedy that by blocking the voice trigger. One-syllable triggers are
especially prone to misrecognition.
1. Create a new command in your custom profile.
1. Set the “when I say” field to the trigger that gets misrecognized.
Adding the “Other” → “VoiceAttack Action” → “Ignore an Unrecognized Word or
Phrase” action will also hide it from the VoiceAttack log when it is (wrongly)
recognized. You might or might not want that.
Example for the “cruise” voice trigger of the Supercruise command:
![[troubleshooting-remove-trigger.png]]
Alternatively you can raise the minimum confidence level and call the underlying
command to make misfires less likely:
![[troubleshooting-raise-min-confidence.png]]
There are a few examples in the [Custom Profile
Example](../installing#use-the-profile-example).
## 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
outlined in [[Installing#Set Elite Keyboard Binds]].
## 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 always prevent the two from speaking over each other.
You can however either disable TTS responses for events that you know will clash
(or [file a feature
request](https://github.com/alterNERDtive/VoiceAttack-profiles/issues/) if one
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
ingame Audo settings:
![[Elite-COVAS.png]]
While youre in there you might as well get rid of the spoken FSD countdown that
is off by one second …
## This doesnt work (well) with my HCS pack
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
custom profile instead of selecting e.g. `EliteAttack` as your active profile.
HCS on the contrary explicitly expects you do exclusively use HCS with
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
HCS to run an included profiles startup command.
So, in order to mostly make stuff work, you need to treat the HCS profile as
your “custom” profile as per this documentation.
1. Include `alterNERDtive-base` and all profiles you want to use into the active
HCS profile.
1. Include a custom profile that has a startup command with a voice trigger of
your choosing, e.g. “load included profiles”.
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
“load included profiles”.
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
priority.
**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
other”. There is no way to alleviate this.
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
if EDDI is speaking to prevent conflicts. Refer to them if you want that
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.

103
docs/upgrading.md Normal file
View file

@ -0,0 +1,103 @@
# Upgrading
To upgrade to the latest version, follow these simple steps:
1. Say “download profiles update”.
1. Put the `alterNERDtive-voiceattack-profiles.vax` file from Github into
VoiceAttacks “Import” folder.
1. Restart VoiceAttack.
In general, migration from old versions will be handled automatically. If there
is something you have to do manually you will find the necessary steps below.
You can find the full
[Changelog](https://github.com/alterNERDtive/VoiceAttack-profiles/blob/release/CHANGELOG.md)
on Github.
## 3.x.x to 4.x.x
If you have been using a custom profile as outlined in [[Installing#Create a
Custom Profile]] your settings will be migrated to the new variables
automatically.
If you have not and you have used my “EliteDangerous” profile as the main
profile … well, you will unfortunately have to take note of your settings, and
recreate them after creating a custom profile and including everything.
Please do not fiddle with the configuration variables from your startup command
(or any other, really). It _should_ not break anything, but it might. And it is
entirely unnecessary since configuration will be saved to and loaded from the
profile anyway.
### EDDI Events
The process for adding your own handlers for EDDI events has changed. You no
longer have to check which of my profiles handle them and add the commands for
those manually; instead you need to [run the `eddi.event` context of the
`alterNERDtive-base` plugin](../configuration/general#eddi-events).
### bindED
If you have done anything non-standard with bindED before, it might break. The
profiles now include my fork of bindED which has a lot more features, but
does no longer support a bunch of plugin invocations that have become obsolete.
Please [file an issue with
bindED](https://github.com/alterNERDtive/bindED/issues/new/choose) on Github if
your use case does not work anymore.
### EliteDangerous
The “EliteDangerous” profile is no longer the main profile. Instead you will
_have_ to create a custom profile, and the new “base” profile that the others
require to be included in your custom profile is “alterNERDtive-base”. That way
you can use e.g. RatAttack without having to also use the general Elite profile.
To be consistent with the other profiles it has been renamed to “EliteAttack”.
If you are upgrading from an older version the name will not change for you in
the profiles list. I recommend renaming your “EliteDangerous” profile to
“EliteAttack” to prevent confusion in the future, but it is not strictly
necessary to do so.
### RatAttack
#### Getting Case Data From IRC
Handing a RATSIGNAL from IRC to VoiceAttack via text file is now deprecated and
the feature will be removed in a future version.
Instead you should use the new `RatAttack-cli.exe` helper tool that uses IPC to
talk to the VoiceAttack plugin. For that you have to change the way your IRC
client handles incoming case announcements. Instead of writing the announcement
to the text file and calling VoiceAttack to run a command, it will have to call
the helper tool with a) the announcement and b) an optional true/false switch to
determine if the case should be announced via TTS or just added to the case
list.
For my AdiIRC, it looks like this (obviously change the path, please):
```adiirc
on *:TEXT:*RATSIGNAL*(??_SIGNAL):#fuelrats:{
if ( $away ) {
/run -h "X:\path\to\VoiceAttack\Apps\alterNERDtive\RatAttack-cli.exe" " $+ $replace($1-,","") $+ " false
}
else {
/run -h "X:\path\to\VoiceAttack\Apps\alterNERDtive\RatAttack-cli.exe" " $+ $replace($1-,","") $+ " true
}
}
```
If I am away it will just add the new case to the list. If I am not away, it
will announce it using TTS.
The `$replace` part handles the fact that case announcements now put the system
in quotes. They have to be escaped as double quotes (`""`) to create a correct
command line invocation.
#### Nearest CMDR Announcements
If you have RatAttack set up to announce your nearest commander to a case,
youll have to change the setting to the new format, separated by `;` instead of
whitespace.
Say “customize setting set fuel rat commanders” to update it.

50
mkdocs.yml Normal file
View file

@ -0,0 +1,50 @@
site_name: "alterNERDtive VA profiles"
site_url: https://alterNERDtive.github.io/VoiceAttack-profiles
repo_url: https://github.com/alterNERDtive/VoiceAttack-profiles
edit_uri: "edit/devel/docs/"
site_description: "alterNERDtive VoiceAttack profiles for Elite: Dangerous"
site_author: "alterNERDtive"
remote_name: "origin"
theme:
name: readthedocs
prev_next_buttons_location: both
plugins:
- search
- roamlinks
# - mkpdfs:
# author: 'alterNERDtive'
# output_path: 'pdf/Profiles Documentation.pdf'
markdown_extensions:
- toc:
permalink: True
- sane_lists
nav:
- 'Home': 'index.md'
- 'Install':
- 'requirements.md'
- 'installing.md'
- 'upgrading.md'
- 'Configure':
- 'configuration/general.md'
- 'configuration/EliteAttack.md'
- 'configuration/RatAttack.md'
- 'configuration/SpanshAttack.md'
- 'configuration/StreamAttack.md'
- 'Use':
- 'general.md'
- 'EliteAttack.md'
- 'RatAttack.md'
- 'SpanshAttack.md'
- 'StreamAttack.md'
- 'Issues':
#- 'VoiceAttack Tips': 'VoiceAttack.md'
- 'troubleshooting.md'
- '⎋ Changelog': 'https://github.com/alterNERDtive/VoiceAttack-profiles/blob/release/CHANGELOG.md'
- '⎋ Report a Bug': 'https://github.com/alterNERDtive/VoiceAttack-profiles/issues/'
- 'Watch in Action':
- '⎋ Twitch': 'https://twitch.tv/alterNERDtive'
- '⎋ Youtube': 'https://www.youtube.com/channel/UC3XNZA7xWed1zM1AWOOdmog'

103
plugins.sln Normal file
View file

@ -0,0 +1,103 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32519.111
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VoiceAttack-base", "plugins\VoiceAttack-base\VoiceAttack-base.csproj", "{1C05DB3F-3449-4664-B363-A379892995E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatAttack", "plugins\RatAttack\RatAttack.csproj", "{64CD3BA3-7FD2-4360-B055-6927CE92DA68}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatAttack-cli", "plugins\RatAttack-cli\RatAttack-cli.csproj", "{D72A35EC-8D39-4B96-BBC5-1B330F4CBEEF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EliteAttack", "plugins\EliteAttack\EliteAttack.csproj", "{77CEF35C-C25C-4793-AB2C-0B0C5D9A5BB8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpanshAttack", "plugins\SpanshAttack\SpanshAttack.csproj", "{D2047704-696B-4665-8D37-3AD298A8B9F9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C2B4D94B-8D73-431A-880B-B1E7ADF064B2}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
CHANGELOG.md = CHANGELOG.md
.github\workflows\create-release.yaml = .github\workflows\create-release.yaml
Directory.build.props = Directory.build.props
mkdocs.yml = mkdocs.yml
README.md = README.md
stylecop.json = stylecop.json
VERSION = VERSION
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{5401ADF7-CB6D-448B-A4AC-D8A17B2D841F}"
ProjectSection(SolutionItems) = preProject
docs\EliteAttack.md = docs\EliteAttack.md
docs\general.md = docs\general.md
docs\index.md = docs\index.md
docs\installing.md = docs\installing.md
docs\RatAttack.md = docs\RatAttack.md
docs\requirements.md = docs\requirements.md
docs\SpanshAttack.md = docs\SpanshAttack.md
docs\StreamAttack.md = docs\StreamAttack.md
docs\troubleshooting.md = docs\troubleshooting.md
docs\upgrading.md = docs\upgrading.md
docs\VoiceAttack.md = docs\VoiceAttack.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "configuration", "configuration", "{1AFD9AE6-7D22-4EF4-B0DE-51C9E91370FB}"
ProjectSection(SolutionItems) = preProject
docs\configuration\EliteAttack.md = docs\configuration\EliteAttack.md
docs\configuration\general.md = docs\configuration\general.md
docs\configuration\RatAttack.md = docs\configuration\RatAttack.md
docs\configuration\SpanshAttack.md = docs\configuration\SpanshAttack.md
docs\configuration\StreamAttack.md = docs\configuration\StreamAttack.md
EndProjectSection
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
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1C05DB3F-3449-4664-B363-A379892995E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C05DB3F-3449-4664-B363-A379892995E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C05DB3F-3449-4664-B363-A379892995E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C05DB3F-3449-4664-B363-A379892995E5}.Release|Any CPU.Build.0 = Release|Any CPU
{64CD3BA3-7FD2-4360-B055-6927CE92DA68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64CD3BA3-7FD2-4360-B055-6927CE92DA68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64CD3BA3-7FD2-4360-B055-6927CE92DA68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64CD3BA3-7FD2-4360-B055-6927CE92DA68}.Release|Any CPU.Build.0 = Release|Any CPU
{D72A35EC-8D39-4B96-BBC5-1B330F4CBEEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D72A35EC-8D39-4B96-BBC5-1B330F4CBEEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D72A35EC-8D39-4B96-BBC5-1B330F4CBEEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D72A35EC-8D39-4B96-BBC5-1B330F4CBEEF}.Release|Any CPU.Build.0 = Release|Any CPU
{77CEF35C-C25C-4793-AB2C-0B0C5D9A5BB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77CEF35C-C25C-4793-AB2C-0B0C5D9A5BB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77CEF35C-C25C-4793-AB2C-0B0C5D9A5BB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77CEF35C-C25C-4793-AB2C-0B0C5D9A5BB8}.Release|Any CPU.Build.0 = Release|Any CPU
{D2047704-696B-4665-8D37-3AD298A8B9F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2047704-696B-4665-8D37-3AD298A8B9F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2047704-696B-4665-8D37-3AD298A8B9F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2047704-696B-4665-8D37-3AD298A8B9F9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5401ADF7-CB6D-448B-A4AC-D8A17B2D841F} = {C2B4D94B-8D73-431A-880B-B1E7ADF064B2}
{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
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {339E6747-C7BF-43C3-99C6-9249C9849A84}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,175 @@
// <copyright file="EliteAttack.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>
#nullable enable
using System;
using alterNERDtive.util;
namespace EliteAttack
{
/// <summary>
/// VoiceAttack plugin for the EliteAttack profile.
/// </summary>
public class EliteAttack
{
private static readonly Version VERSION = new ("8.5");
private static VoiceAttackLog? log;
private static VoiceAttackCommands? commands;
private static dynamic? VA { get; set; }
private static VoiceAttackLog Log => log ??= new (VA, "EliteAttack");
private static VoiceAttackCommands Commands => commands ??= new (VA, Log);
/*========================================\
| required VoiceAttack plugin shenanigans |
\========================================*/
/// <summary>
/// The plugins GUID, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The GUID.</returns>
public static Guid VA_Id()
=> new ("{5B46321D-2935-4550-BEEA-36C2145547B8}");
/// <summary>
/// The plugins display name, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The display name.</returns>
public static string VA_DisplayName()
=> $"EliteAttack {VERSION}";
/// <summary>
/// The plugins description, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The description.</returns>
public static string VA_DisplayInfo()
=> "EliteAttack: a plugin for doing Elite-y things.";
/// <summary>
/// The Init method, as required by the VoiceAttack plugin API.
/// Runs when the plugin is initially loaded.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Init1(dynamic vaProxy)
{
VA = vaProxy;
Log.Notice("Initializing …");
VA.SetText("EliteAttack.version", VERSION.ToString());
Log.Notice("Init successful.");
}
/// <summary>
/// The Invoke method, as required by the VoiceAttack plugin API.
/// Runs whenever a plugin context is invoked.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy)
{
string context = vaProxy.Context.ToLower();
Log.Debug($"Running context '{context}' …");
try
{
switch (context)
{
case "startup":
Context_Startup(vaProxy);
break;
case "log.log":
// log
Context_Log(vaProxy);
break;
default:
// invalid
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
break;
}
}
catch (ArgumentNullException e)
{
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
}
catch (Exception e)
{
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
}
}
/// <summary>
/// The Exit method, as required by the VoiceAttack plugin API.
/// Runs when VoiceAttack is shut down.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
public static void VA_Exit1(dynamic vaProxy)
{
}
/// <summary>
/// The StopCommand method, as required by the VoiceAttack plugin API.
/// Runs whenever all commands are stopped using the “Stop All Commands”
/// button or action.
/// </summary>
public static void VA_StopCommand()
{
}
/*================\
| plugin contexts |
\================*/
#pragma warning disable IDE0060 // Remove unused parameter
private static void Context_Log(dynamic vaProxy)
{
string message = vaProxy.GetText("~message");
string level = vaProxy.GetText("~level");
if (level == null)
{
Log.Log(message);
}
else
{
try
{
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
}
catch (ArgumentNullException)
{
throw;
}
catch (ArgumentException)
{
Log.Error($"Invalid log level '{level}'.");
}
}
}
private static void Context_Startup(dynamic vaProxy)
{
Log.Notice("Starting up …");
Log.Notice("Finished startup.");
}
#pragma warning restore IDE0060 // Remove unused parameter
}
}

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{77CEF35C-C25C-4793-AB2C-0B0C5D9A5BB8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EliteAttack</RootNamespace>
<AssemblyName>EliteAttack</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\EliteAttack.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\EliteAttack.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="EliteAttack.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VoiceAttack-base\VoiceAttack-base.csproj">
<Project>{1c05db3f-3449-4664-b363-a379892995e5}</Project>
<Name>VoiceAttack-base</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -0,0 +1,55 @@
// <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.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EliteAttack")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EliteAttack")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("77cef35c-c25c-4793-ab2c-0b0c5d9a5bb8")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,55 @@
// <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.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("RatAttack-cli")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RatAttack-cli")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("d72a35ec-8d39-4b96-bbc5-1b330f4cbeef")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D72A35EC-8D39-4B96-BBC5-1B330F4CBEEF}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>RatAttack_cli</RootNamespace>
<AssemblyName>RatAttack-cli</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\RatAttack-cli.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\RatAttack-cli.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Serialization" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RatAttack_cli.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RatAttack\RatAttack.csproj">
<Project>{64cd3ba3-7fd2-4360-b055-6927ce92da68}</Project>
<Name>RatAttack</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -0,0 +1,68 @@
// <copyright file="RatAttack_cli.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>
#nullable enable
using System;
using System.IO;
using System.IO.Pipes;
using System.Text.RegularExpressions;
namespace RatAttack
{
/// <summary>
/// CLI helper tool for the RatAttack VoiceAttack plugin. Accepts RATSIGNALs
/// e.g. from an IRC client and passes them to the plugin via named pipe.
/// </summary>
public class RatAttack_cli
{
/// <summary>
/// Main entry point.
/// </summary>
/// <param name="args">The command line arguments.</param>
public static void Main(string[] args)
{
RatAttack.Ratsignal ratsignal = new (StripIrcCodes(args[0]), args.Length > 1 && args[1].ToLower() == "true");
using (NamedPipeClientStream pipeClient = new (".", "RatAttack", PipeDirection.Out))
{
try
{
// try connecting for up to 2minutes; then well assume VoiceAttack just isnt up and wont come up
pipeClient.Connect(120000);
using StreamWriter writer = new (pipeClient);
writer.WriteLine(ratsignal);
}
catch (TimeoutException)
{
Console.Error.WriteLine("Connection to RatAttack pipe has timed out.");
}
catch (UnauthorizedAccessException)
{
Console.Error.WriteLine("Cannot connect to RatAttack pipe. Are you running VoiceAttack as Admin?");
}
}
}
private static string StripIrcCodes(string message)
{
return Regex.Replace(message, @"[\x02\x11\x0F\x1D\x1E\x1F\x16]|\x03(\d\d?(,\d\d?)?)?", string.Empty);
}
}
}

View file

@ -0,0 +1,55 @@
// <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.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("VoiceAttack-plugins")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VoiceAttack-plugins")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("64cd3ba3-7fd2-4360-b055-6927ce92da68")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,445 @@
// <copyright file="RatAttack.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>
#nullable enable
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Text.RegularExpressions;
using alterNERDtive.util;
namespace RatAttack
{
/// <summary>
/// VoiceAttack plugin for the RatAttack profile.
/// </summary>
public class RatAttack
{
private static readonly Version VERSION = new ("6.4");
private static readonly Regex RatsignalRegex = new (
@"^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 VoiceAttackLog? log;
private static VoiceAttackCommands? commands;
private static ConcurrentDictionary<int, RatCase> CaseList { get; } = new ();
private static dynamic? VA { get; set; }
private static PipeServer<Ratsignal> RatsignalPipe
=> ratsignalPipe ??= new (
Log,
"RatAttack",
new PipeServer<Ratsignal>.SignalHandler(On_Ratsignal));
private static VoiceAttackLog Log => log ??= new (VA, "RatAttack");
private static VoiceAttackCommands Commands => commands ??= new (VA, Log);
/*========================================\
| required VoiceAttack plugin shenanigans |
\========================================*/
/// <summary>
/// The plugins GUID, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The GUID.</returns>
public static Guid VA_Id()
=> new ("{F2ADF0AE-4837-4E4A-9C87-8A7E2FA63E5F}");
/// <summary>
/// The plugins display name, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The display name.</returns>
public static string VA_DisplayName()
=> $"RatAttack {VERSION}";
/// <summary>
/// The plugins description, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The description.</returns>
public static string VA_DisplayInfo()
=> "RatAttack: a plugin to handle FuelRats cases.";
/// <summary>
/// The Init method, as required by the VoiceAttack plugin API.
/// Runs when the plugin is initially loaded.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Init1(dynamic vaProxy)
{
VA = vaProxy;
Log.Notice("Initializing …");
VA.SetText("RatAttack.version", VERSION.ToString());
vaProxy.ProfileChanged += new Action<Guid?, Guid?, string, string>(On_ProfileChanged);
Log.Notice("Init successful.");
}
/// <summary>
/// The Invoke method, as required by the VoiceAttack plugin API.
/// Runs whenever a plugin context is invoked.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy)
{
string context = vaProxy.Context.ToLower();
Log.Debug($"Running context '{context}' …");
try
{
switch (context)
{
case "getcasedata":
// plugin methods
Context_GetCaseData(vaProxy);
break;
case "parseratsignal":
Context_ParseRatsignal(vaProxy);
break;
case "startup":
Context_Startup(vaProxy);
break;
case "edsm.getnearestcmdr":
// EDSM
Context_EDSM_GetNearestCMDR(vaProxy);
break;
case "log.log":
// log
Context_Log(vaProxy);
break;
default:
// invalid
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
break;
}
}
catch (ArgumentNullException e)
{
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
}
catch (Exception e)
{
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
}
}
/// <summary>
/// The Exit method, as required by the VoiceAttack plugin API.
/// Runs when VoiceAttack is shut down.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
public static void VA_Exit1(dynamic vaProxy)
{
Log.Debug("Starting teardown …");
Log.Debug("Closing RATSIGNAL pipe …");
RatsignalPipe.Stop();
Log.Debug("Teardown finished.");
}
/// <summary>
/// The StopCommand method, as required by the VoiceAttack plugin API.
/// Runs whenever all commands are stopped using the “Stop All Commands”
/// button or action.
/// </summary>
public static void VA_StopCommand()
{
}
/// <summary>
/// Parses a RATSIGNAL and extracts case data for storage.
/// </summary>
/// <param name="ratsignal">The incoming RATSIGNAL.</param>
/// <returns>The case number.</returns>
/// <exception cref="ArgumentException">Thrown on invalid RATSIGNAL.</exception>
private static int ParseRatsignal(string ratsignal)
{
if (!RatsignalRegex.IsMatch(ratsignal))
{
throw new ArgumentException($"Invalid RATSIGNAL format: '{ratsignal}'.", "ratsignal");
}
Match match = RatsignalRegex.Match(ratsignal);
string cmdr = match.Groups["cmdr"].Value;
string? language = match.Groups["language"].Value;
string? system = match.Groups["system"].Value;
string? systemInfo = match.Groups["systemInfo"].Value;
bool permitLocked = match.Groups["permit"].Success;
string? permitName = match.Groups["permitName"].Value;
string platform = match.Groups["platform"].Value;
bool codeRed = match.Groups["oxygen"].Success;
string? mode = match.Groups["mode"].Value;
int number = int.Parse(match.Groups["number"].Value);
if (string.IsNullOrEmpty(system))
{
system = "None";
}
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, mode, codeRed, number);
return number;
}
private static void On_Ratsignal(Ratsignal ratsignal)
{
try
{
int number = ParseRatsignal(ratsignal.Signal);
Log.Notice($"New rat case: {CaseList[number]}.");
Commands.TriggerEvent("RatAttack.incomingCase", parameters: new dynamic[] { new int[] { number }, new bool[] { ratsignal.Announce } });
}
catch (ArgumentException e)
{
Log.Error(e.Message);
Commands.TriggerEvent("RatAttack.invalidRatsignal", parameters: new dynamic[] { new string[] { ratsignal.Signal } });
}
catch (Exception e)
{
Log.Error($"Unhandled exception while parsing RATSIGNAL: '{e.Message}'.");
}
}
private static void On_ProfileChanged(Guid? from, Guid? to, string fromName, string toName)
=> VA_Exit1(VA);
/*================\
| plugin contexts |
\================*/
#pragma warning disable IDE0060 // Remove unused parameter
private static void Context_EDSM_GetNearestCMDR(dynamic vaProxy)
{
int caseNo = vaProxy.GetInt("~caseNo") ?? throw new ArgumentNullException("~caseNo");
string cmdrList = vaProxy.GetText("~cmdrs") ?? throw new ArgumentNullException("~cmdrs");
string[] cmdrs = cmdrList.Split(';');
if (cmdrs.Length == 0)
{
throw new ArgumentNullException("~cmdrs");
}
string system = CaseList[caseNo]?.System ?? throw new ArgumentException($"Case #{caseNo} has no system information", "~caseNo");
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\edsm-getnearest.exe";
string arguments = $@"--short --text --system ""{system}"" ""{string.Join(@""" """, cmdrs)}""";
Process p = PythonProxy.SetupPythonScript(path, arguments);
p.Start();
string stdout = p.StandardOutput.ReadToEnd();
string stderr = p.StandardError.ReadToEnd();
p.WaitForExit();
string message = stdout;
string? errorMessage = null;
bool error;
switch (p.ExitCode)
{
case 0:
error = false;
Log.Info(message);
break;
case 1: // CMDR not found, Server Error, Api Exception (jeez, what a mess did I make there?)
error = true;
Log.Error(message);
break;
case 2: // System not found
error = true;
Log.Warn(message);
break;
default:
error = true;
Log.Error(stderr);
errorMessage = "Unrecoverable error in plugin.";
break;
}
vaProxy.SetText("~message", message);
vaProxy.SetBoolean("~error", error);
vaProxy.SetText("~errorMessage", errorMessage);
vaProxy.SetInt("~exitCode", p.ExitCode);
}
private static void Context_GetCaseData(dynamic vaProxy)
{
int cn = vaProxy.GetInt("~caseNumber");
if (CaseList.ContainsKey(cn))
{
RatCase rc = CaseList[cn];
vaProxy.SetInt("~~caseNumber", rc.Number);
vaProxy.SetText("~~cmdr", rc.Cmdr);
vaProxy.SetText("~~system", rc?.System?.ToLower());
vaProxy.SetText("~~systemInfo", rc?.SystemInfo);
vaProxy.SetBoolean("~~permitLocked", rc?.PermitLocked);
vaProxy.SetText("~~permitName", rc?.PermitName);
vaProxy.SetText("~~platform", rc?.Platform);
vaProxy.SetText("~~mode", rc?.Mode);
vaProxy.SetBoolean("~~codeRed", rc?.CodeRed);
}
else
{
Log.Warn($"Case #{cn} not found in the case list");
}
}
private static void Context_Log(dynamic vaProxy)
{
string message = vaProxy.GetText("~message");
string level = vaProxy.GetText("~level");
if (level == null)
{
Log.Log(message);
}
else
{
try
{
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
}
catch (ArgumentNullException)
{
throw;
}
catch (ArgumentException)
{
Log.Error($"Invalid log level '{level}'.");
}
}
}
private static void Context_Startup(dynamic vaProxy)
{
Log.Notice("Starting up …");
_ = RatsignalPipe.Run();
Log.Notice("Finished startup.");
}
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.");
On_Ratsignal(new Ratsignal(vaProxy.GetText("~ratsignal"), vaProxy.GetBoolean("~announceRatsignal") ?? false));
}
#pragma warning restore IDE0060 // Remove unused parameter
/// <summary>
/// Encapsulates a RATSIGNAL for sending between the CLI helper tool and
/// the plugin via named pipe.
/// </summary>
public class Ratsignal : IPipable
{
private readonly char separator = '\x1F';
/// <summary>
/// Initializes a new instance of the <see cref="Ratsignal"/> class.
/// </summary>
public Ratsignal()
=> (this.Signal, this.Announce) = (string.Empty, false);
/// <summary>
/// Initializes a new instance of the <see cref="Ratsignal"/> class.
/// </summary>
/// <param name="signal">The RATSIGNAL.</param>
/// <param name="announce">Whether or not to announce the new case.</param>
public Ratsignal(string signal, bool announce)
=> (this.Signal, this.Announce) = (signal, announce);
/// <summary>
/// Gets or sets the RATSIGNAL.
/// </summary>
public string Signal { get; set; }
/// <summary>
/// Gets or Sets a value indicating whether to announce the incoming
/// case.
/// </summary>
public bool Announce { get; set; }
/// <summary>
/// Initializes the <see cref="Ratsignal"/> instance from a
/// serialized representation.
/// FIXXME: should probably make this a static factory method.
/// </summary>
/// <param name="serialization">The serialized <see cref="Ratsignal"/>.</param>
/// <exception cref="ArgumentException">Thrown on receiving an invalid signal.</exception>
public void ParseString(string serialization)
{
try
{
string[] parts = serialization.Split(this.separator);
this.Signal = parts[0];
this.Announce = bool.Parse(parts[1]);
}
catch (Exception e)
{
throw new ArgumentException($"Invalid serialized RATSIGNAL: '{serialization}'", e);
}
}
/// <inheritdoc/>
public override string ToString()
=> $"{this.Signal}{this.separator}{this.Announce}";
}
private class RatCase
{
public RatCase(string cmdr, string? language, string? system, string? systemInfo, bool permitLocked, string? permitName, string platform, string mode, bool codeRed, int 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, mode, codeRed, number);
public string Cmdr { get; }
public string? Language { get; }
public string? System { get; }
public string? SystemInfo { get; }
public bool PermitLocked { get; }
public string? PermitName { get; }
public string Platform { get; }
public string? Mode { get; }
public bool CodeRed { get; }
public int Number { get; }
public string ShortInfo
{
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()
=> this.ShortInfo;
}
}
}

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{64CD3BA3-7FD2-4360-B055-6927CE92DA68}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RatAttack</RootNamespace>
<AssemblyName>RatAttack</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\RatAttack.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\RatAttack.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Serialization" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RatAttack.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VoiceAttack-base\VoiceAttack-base.csproj">
<Project>{1c05db3f-3449-4664-b363-a379892995e5}</Project>
<Name>VoiceAttack-base</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -0,0 +1,55 @@
// <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.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SpanshAttack")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SpanshAttack")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("d2047704-696b-4665-8d37-3ad298a8b9f9")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,336 @@
// <copyright file="SpanshAttack.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>
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using alterNERDtive.edts;
using alterNERDtive.util;
namespace SpanshAttack
{
/// <summary>
/// VoiceAttack plugin for the SpanshAttack profile.
/// </summary>
public class SpanshAttack
{
private static readonly Version VERSION = new ("7.2.2");
private static VoiceAttackLog? log;
private static VoiceAttackCommands? commands;
private static dynamic? VA { get; set; }
private static VoiceAttackLog Log => log ??= new (VA, "SpanshAttack");
private static VoiceAttackCommands Commands => commands ??= new (VA, Log);
/*========================================\
| required VoiceAttack plugin shenanigans |
\========================================*/
/// <summary>
/// The plugins GUID, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The GUID.</returns>
public static Guid VA_Id()
=> new ("{e722b29d-898e-47dd-a843-a409c87e0bd8}");
/// <summary>
/// The plugins display name, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The display name.</returns>
public static string VA_DisplayName()
=> $"SpanshAttack {VERSION}";
/// <summary>
/// The plugins description, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The description.</returns>
public static string VA_DisplayInfo()
=> "SpanshAttack: a plugin for doing routing with spansh.co.uk for Elite: Dangerous.";
/// <summary>
/// The Init method, as required by the VoiceAttack plugin API.
/// Runs when the plugin is initially loaded.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Init1(dynamic vaProxy)
{
VA = vaProxy;
Log.Notice("Initializing …");
VA.SetText("SpanshAttack.version", VERSION.ToString());
Log.Notice("Init successful.");
}
/// <summary>
/// The Invoke method, as required by the VoiceAttack plugin API.
/// Runs whenever a plugin context is invoked.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy)
{
string context = vaProxy.Context.ToLower();
Log.Debug($"Running context '{context}' …");
try
{
switch (context)
{
case "startup":
Context_Startup(vaProxy);
break;
case "edts.getcoordinates":
// EDTS
Context_EDTS_GetCoordinates(vaProxy);
break;
case "log.log":
// log
Context_Log(vaProxy);
break;
case "spansh.systemexists":
// Spansh
Context_Spansh_SytemExists(vaProxy);
break;
case "spansh.nearestsystem":
Context_Spansh_Nearestsystem(vaProxy);
break;
default:
// invalid
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
break;
}
}
catch (ArgumentNullException e)
{
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
}
catch (Exception e)
{
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
}
}
/// <summary>
/// The Exit method, as required by the VoiceAttack plugin API.
/// Runs when VoiceAttack is shut down.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
public static void VA_Exit1(dynamic vaProxy)
{
}
/// <summary>
/// The StopCommand method, as required by the VoiceAttack plugin API.
/// Runs whenever all commands are stopped using the “Stop All Commands”
/// button or action.
/// </summary>
public static void VA_StopCommand()
{
}
/*================\
| plugin contexts |
\================*/
#pragma warning disable IDE0060 // Remove unused parameter
private static void Context_EDTS_GetCoordinates(dynamic vaProxy)
{
string name = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
bool success = false;
string? errorType = null;
string? errorMessage = null;
try
{
StarSystem system = EdtsApi.GetCoordinates(name);
if (system.Coords.Precision < 100)
{
Log.Info($@"Coordinates for ""{name}"": ({system.Coords.X}, {system.Coords.Y}, {system.Coords.Z}), precision: {system.Coords.Precision}ly");
}
else
{
Log.Warn($@"Coordinates with low precision for ""{name}"": ({system.Coords.X}, {system.Coords.Y}, {system.Coords.Z}), precision: {system.Coords.Precision}ly");
}
vaProxy.SetInt("~x", system.Coords.X);
vaProxy.SetInt("~y", system.Coords.Y);
vaProxy.SetInt("~z", system.Coords.Z);
vaProxy.SetInt("~precision", system.Coords.Precision);
success = true;
}
catch (ArgumentException e)
{
errorType = "invalid name";
errorMessage = e.Message;
}
catch (Exception e)
{
errorType = "connection error";
errorMessage = e.Message;
}
vaProxy.SetBoolean("~success", success);
if (!string.IsNullOrWhiteSpace(errorType))
{
Log.Error(errorMessage!);
vaProxy.SetText("~errorType", errorType);
vaProxy.SetText("~errorMessage", errorMessage);
}
}
private static void Context_Log(dynamic vaProxy)
{
string message = vaProxy.GetText("~message");
string level = vaProxy.GetText("~level");
if (level == null)
{
Log.Log(message);
}
else
{
try
{
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
}
catch (ArgumentNullException)
{
throw;
}
catch (ArgumentException)
{
Log.Error($"Invalid log level '{level}'.");
}
}
}
private static void Context_Spansh_Nearestsystem(dynamic vaProxy)
{
int x = vaProxy.GetInt("~x") ?? throw new ArgumentNullException("~x");
int y = vaProxy.GetInt("~y") ?? throw new ArgumentNullException("~y");
int z = vaProxy.GetInt("~z") ?? throw new ArgumentNullException("~z");
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
string arguments = $@"nearestsystem --parsable {x} {y} {z}";
Process p = PythonProxy.SetupPythonScript(path, arguments);
Dictionary<char, decimal> coords = new () { { 'x', 0 }, { 'y', 0 }, { 'z', 0 } };
string system = string.Empty;
decimal distance = 0;
bool error = false;
string errorMessage = string.Empty;
p.Start();
string stdout = p.StandardOutput.ReadToEnd();
string stderr = p.StandardError.ReadToEnd();
p.WaitForExit();
switch (p.ExitCode)
{
case 0:
string[] stdoutExploded = stdout.Split('|');
system = stdoutExploded[0];
distance = decimal.Parse(stdoutExploded[2]);
string[] stdoutCoords = stdoutExploded[1].Split(',');
coords['x'] = decimal.Parse(stdoutCoords[0]);
coords['y'] = decimal.Parse(stdoutCoords[1]);
coords['z'] = decimal.Parse(stdoutCoords[2]);
Log.Info($"Nearest system to ({x}, {y}, {z}): {system} ({coords['x']}, {coords['y']}, {coords['z']}), distance: {distance}ly");
break;
case 1:
error = true;
errorMessage = stdout;
Log.Error(errorMessage);
break;
default:
error = true;
Log.Error(stderr);
errorMessage = "Unrecoverable error in plugin.";
break;
}
vaProxy.SetText("~system", system);
vaProxy.SetDecimal("~x", coords['x']);
vaProxy.SetDecimal("~y", coords['y']);
vaProxy.SetDecimal("~z", coords['z']);
vaProxy.SetDecimal("~distance", distance);
vaProxy.SetBoolean("~error", error);
vaProxy.SetText("~errorMessage", errorMessage);
vaProxy.SetInt("~exitCode", p.ExitCode);
}
private static void Context_Spansh_SytemExists(dynamic vaProxy)
{
string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
string arguments = $@"systemexists ""{system}""";
Process p = PythonProxy.SetupPythonScript(path, arguments);
bool exists = true;
bool error = false;
string errorMessage = string.Empty;
p.Start();
string stdout = p.StandardOutput.ReadToEnd();
string stderr = p.StandardError.ReadToEnd();
p.WaitForExit();
switch (p.ExitCode)
{
case 0:
Log.Info($@"System ""{system}"" found in Spanshs DB");
break;
case 1:
error = true;
errorMessage = stdout;
Log.Error(errorMessage);
break;
case 3:
exists = false;
Log.Info($@"System ""{system}"" not found in Spanshs DB");
break;
default:
error = true;
Log.Error(stderr);
errorMessage = "Unrecoverable error in plugin.";
break;
}
vaProxy.SetBoolean("~systemExists", exists);
vaProxy.SetBoolean("~error", error);
vaProxy.SetText("~errorMessage", errorMessage);
vaProxy.SetInt("~exitCode", p.ExitCode);
}
private static void Context_Startup(dynamic vaProxy)
{
Log.Notice("Starting up …");
Log.Notice("Finished startup.");
}
#pragma warning restore IDE0060 // Remove unused parameter
}
}

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D2047704-696B-4665-8D37-3AD298A8B9F9}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SpanshAttack</RootNamespace>
<AssemblyName>SpanshAttack</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\SpanshAttack.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\SpanshAttack.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="SpanshAttack.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VoiceAttack-base\VoiceAttack-base.csproj">
<Project>{1c05db3f-3449-4664-b363-a379892995e5}</Project>
<Name>VoiceAttack-base</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -0,0 +1,28 @@
// <copyright file="GlobalSuppressions.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.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.edts")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "just cause", Scope = "namespace", Target = "~N:alterNERDtive.util")]

View file

@ -0,0 +1,55 @@
// <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.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("VoiceAttack-base")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VoiceAttack-base")]
[assembly: AssemblyCopyright("Copyright © 20202022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1c05db3f-3449-4664-b363-a379892995e5")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,25 @@
<UserControl x:Class="alterNERDtive.SettingsDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:alterNERDtive"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<StackPanel>
<TabControl Name="tabs">
<TabItem Name="general" Header="general"></TabItem>
<TabItem Name="EliteAttack" Header="EliteAttack"></TabItem>
<TabItem Name="RatAttack" Header="RatAttack"></TabItem>
<TabItem Name="SpanshAttack" Header="SpanshAttack"></TabItem>
<TabItem Name="StreamAttack" Header="StreamAttack"></TabItem>
</TabControl>
<WrapPanel VerticalAlignment="Bottom" HorizontalAlignment="Right">
<Button Name="applyButton" Click="ApplyButton_Click" Padding="5" Margin="5" Width="100">Apply</Button>
<Button Name="okButton" Click="OkButton_Click" Padding="5" Margin="5" Width="100">Done</Button>
<Button Name="cancelButton" Click="CancelButton_Click" Padding="5" Margin="5" Width="100">Cancel</Button>
</WrapPanel>
</StackPanel>
</Grid>
</UserControl>

View file

@ -0,0 +1,188 @@
// <copyright file="SettingsDialog.xaml.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>
#nullable enable
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace alterNERDtive
{
/// <summary>
/// Interaction logic for SettingsDialog.xaml.
/// </summary>
public partial class SettingsDialog : UserControl
{
private readonly List<Setting> values = new List<Setting>();
private util.Configuration config;
private util.VoiceAttackLog log;
/// <summary>
/// Initializes a new instance of the <see cref="SettingsDialog"/> class.
/// </summary>
/// <param name="config">The plugin Configuration.</param>
/// <param name="log">The plugin Log.</param>
public SettingsDialog(util.Configuration config, util.VoiceAttackLog log)
{
this.InitializeComponent();
this.config = config;
this.log = log;
foreach (TabItem tab in this.tabs.Items)
{
string profile = tab.Name;
if (profile == "general")
{
profile = "alterNERDtive-base";
}
tab.IsEnabled = BasePlugin.IsProfileActive(profile);
StackPanel panel = new StackPanel();
util.Configuration.OptDict<string, util.Configuration.Option> options = util.Configuration.GetOptions(profile);
foreach (dynamic option in options.Values)
{
dynamic value = config.GetConfig(profile, option.Name);
if (option is util.Configuration.Option<bool>)
{
WrapPanel row = new WrapPanel();
CheckBox checkBox = new CheckBox();
checkBox.IsChecked = value;
checkBox.VerticalAlignment = VerticalAlignment.Center;
row.Children.Add(checkBox);
this.values.Add(new Setting(profile, option, value, checkBox));
Label label = new Label();
label.Content = option.Description;
row.Children.Add(label);
panel.Children.Add(row);
}
else
{
StackPanel row = new StackPanel();
Label label = new Label();
label.Content = option.Description;
row.Children.Add(label);
TextBox input = new TextBox();
input.Text = value.ToString();
row.Children.Add(input);
this.values.Add(new Setting(profile, option, value, input));
panel.Children.Add(row);
}
}
tab.Content = panel;
}
}
private bool ApplySettings()
{
bool success = true;
foreach (Setting setting in this.values)
{
dynamic? state = null;
try
{
if (setting.Option is util.Configuration.Option<bool>)
{
state = ((CheckBox)setting.UiElement).IsChecked ?? false;
}
else if (setting.Option is util.Configuration.Option<DateTime>)
{
state = DateTime.Parse(((TextBox)setting.UiElement).Text);
}
else if (setting.Option is util.Configuration.Option<decimal>)
{
state = decimal.Parse(((TextBox)setting.UiElement).Text);
}
else if (setting.Option is util.Configuration.Option<int>)
{
state = int.Parse(((TextBox)setting.UiElement).Text);
}
else if (setting.Option is util.Configuration.Option<short>)
{
state = short.Parse(((TextBox)setting.UiElement).Text);
}
else if (setting.Option is util.Configuration.Option<string>)
{
state = ((TextBox)setting.UiElement).Text;
}
if (state != setting.Value)
{
this.log.Log($@"Configuration changed via settings dialog: ""{setting.Profile}.{setting.Option.Name}"" → ""{state}""", util.LogLevel.DEBUG);
this.config.SetConfig(setting.Profile, setting.Option.Name, state);
}
}
catch (Exception e) when (e is ArgumentNullException || e is FormatException || e is OverflowException)
{
this.log.Log($@"Invalid value for ""{setting.Profile}.{setting.Option.Name}"": ""{((TextBox)setting.UiElement).Text}""", util.LogLevel.ERROR);
success = false;
}
}
return success;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
Window.GetWindow(this).Close();
this.log.Log("Settings dialog cancelled.", util.LogLevel.DEBUG);
}
private void OkButton_Click(object sender, RoutedEventArgs e)
{
if (this.ApplySettings())
{
Window.GetWindow(this).Close();
}
}
private void ApplyButton_Click(object sender, RoutedEventArgs reeargs)
{
this.ApplySettings();
}
private struct Setting
{
public Setting(string profile, dynamic option, dynamic value, dynamic uiElement)
=> (this.Profile, this.Option, this.Value, this.UiElement) = (profile, option, value, uiElement);
public string Profile { get; }
public dynamic Option { get; }
public dynamic Value { get; }
public dynamic UiElement { get; }
}
}
}

View file

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1C05DB3F-3449-4664-B363-A379892995E5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>alterNERDtive</RootNamespace>
<AssemblyName>base</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\base.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\build\alterNERDtive\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\build\alterNERDtive\base.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="base.cs" />
<Compile Include="edts.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SettingsDialog.xaml.cs">
<DependentUpon>SettingsDialog.xaml</DependentUpon>
</Compile>
<Compile Include="util.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="SettingsDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</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" />
</Project>

View file

@ -0,0 +1,691 @@
// <copyright file="base.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>
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using alterNERDtive.util;
namespace alterNERDtive
{
/// <summary>
/// This is the base plugin orchestrating all the profile-specific plugins
/// to work together properly. It handles things like configuration or
/// subscribing to VoiceAttack-triggered events.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "F off :)")]
public class BasePlugin
{
private static readonly Version VERSION = new ("4.5");
private static readonly Dictionary<Guid, string> Profiles = new ()
{
{ new Guid("{F7F59CFD-1AE2-4A7E-8F62-C62372418BAC}"), "alterNERDtive-base" },
{ new Guid("{f31b575b-6ce4-44eb-91fc-7459e55013cf}"), "EliteAttack" },
{ new Guid("{87276668-2a6e-4d80-af77-80651daa58b7}"), "RatAttack" },
{ new Guid("{e722b29d-898e-47dd-a843-a409c87e0bd8}"), "SpanshAttack" },
{ new Guid("{05580e6c-442c-46cd-b36f-f5a1f967ec59}"), "StreamAttack" },
};
private static readonly List<string> ActiveProfiles = new ();
private static readonly List<string> InstalledProfiles = new ();
private static readonly Regex ConfigurationVariableRegex = new (@$"(?<id>({string.Join("|", Profiles.Values)}))\.(?<name>.+)#");
private static VoiceAttackCommands? commands;
private static Configuration? config;
private static VoiceAttackLog? log;
private static VoiceAttackCommands Commands => commands ??= new (VA, Log);
private static Configuration Config => config ??= new (VA, Log, Commands, "alterNERDtive-base");
private static VoiceAttackLog Log => log ??= new (VA, "alterNERDtive-base");
private static dynamic? VA { get; set; }
/*========================================\
| required VoiceAttack plugin shenanigans |
\========================================*/
/// <summary>
/// The plugins GUID, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The GUID.</returns>
public static Guid VA_Id()
=> new ("{F7F59CFD-1AE2-4A7E-8F62-C62372418BAC}");
/// <summary>
/// The plugins display name, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The display name.</returns>
public static string VA_DisplayName()
=> $"alterNERDtive-base {VERSION}";
/// <summary>
/// The plugins description, as required by the VoiceAttack plugin API.
/// </summary>
/// <returns>The description.</returns>
public static string VA_DisplayInfo()
=> "The alterNERDtive plugin to manage all the alterNERDtive profiles!";
/// <summary>
/// The Init method, as required by the VoiceAttack plugin API.
/// Runs when the plugin is initially loaded.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Init1(dynamic vaProxy)
{
VA = vaProxy;
Log.Notice("Initializing …");
VA.SetText("alterNERDtive-base.version", VERSION.ToString());
vaProxy.BooleanVariableChanged += new Action<string, bool?, bool?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
vaProxy.DateVariableChanged += new Action<string, DateTime?, DateTime?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
vaProxy.DecimalVariableChanged += new Action<string, decimal?, decimal?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
vaProxy.IntegerVariableChanged += new Action<string, int?, int?, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
vaProxy.TextVariableChanged += new Action<string, string, string, Guid?>((name, from, to, id) => { ConfigurationChanged(name, from, to, id); });
VA.SetBoolean("alterNERDtive-base.initialized", true);
Commands.TriggerEvent("alterNERDtive-base.initialized", wait: false, logMissing: false);
Log.Notice("Init successful.");
}
/// <summary>
/// The Invoke method, as required by the VoiceAttack plugin API.
/// Runs whenever a plugin context is invoked.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
public static void VA_Invoke1(dynamic vaProxy)
{
string context = vaProxy.Context.ToLower();
Log.Debug($"Running context '{context}' …");
try
{
switch (context)
{
case "startup":
Context_Startup(vaProxy);
break;
case "config.dialog":
// config
Context_Config_Dialog(vaProxy);
break;
case "config.dump":
Context_Config_Dump(vaProxy);
break;
case "config.getvariables":
Context_Config_SetVariables(vaProxy);
break;
case "config.list":
Context_Config_List(vaProxy);
break;
case "config.setup":
Context_Config_Setup(vaProxy);
break;
case "config.versionmigration":
Context_Config_VersionMigration(vaProxy);
break;
case "edsm.bodycount":
// EDSM
Context_EDSM_BodyCount(vaProxy);
break;
case "edsm.distancebetween":
Context_EDSM_DistanceBetween(vaProxy);
break;
case "eddi.event":
// EDDI
Context_Eddi_Event(vaProxy);
break;
case "spansh.outdatedstations":
// Spansh
Context_Spansh_OutdatedStations(vaProxy);
break;
case "log.log":
// log
Context_Log(vaProxy);
break;
case "update.check":
// update
Context_Update_Check(vaProxy);
break;
default:
// invalid
Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
break;
}
}
catch (ArgumentNullException e)
{
Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
}
catch (Exception e)
{
Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
}
}
/// <summary>
/// The Exit method, as required by the VoiceAttack plugin API.
/// Runs when VoiceAttack is shut down.
/// </summary>
/// <param name="vaProxy">The VoiceAttack proxy object.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
public static void VA_Exit1(dynamic vaProxy)
{
}
/// <summary>
/// The StopCommand method, as required by the VoiceAttack plugin API.
/// Runs whenever all commands are stopped using the “Stop All Commands”
/// button or action.
/// </summary>
public static void VA_StopCommand()
{
}
/// <summary>
/// Returns whether a given profile is currently active.
/// </summary>
/// <param name="profileName">The name of the profile in question.</param>
/// <returns>The state of the profile in question.</returns>
public static bool IsProfileActive(string profileName) => ActiveProfiles.Contains(profileName);
private static void CheckProfiles(dynamic vaProxy)
{
ActiveProfiles.Clear();
InstalledProfiles.Clear();
foreach (KeyValuePair<Guid, string> profile in Profiles)
{
if (vaProxy.Command.Exists($"(({profile.Value}.startup))"))
{
// Sadly there is no way to find _active_ profiles, so we have to check the one command that always is in them.
ActiveProfiles.Add(profile.Value);
}
if (vaProxy.Profile.Exists(profile.Key))
{
InstalledProfiles.Add(profile.Value);
}
}
Log.Debug($"Profiles found: {string.Join<string>(", ", ActiveProfiles)}");
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "required by VoiceAttack plugin API")]
private static void ConfigurationChanged(string option, dynamic? from, dynamic? to, Guid? guid = null)
{
try
{
Match match = ConfigurationVariableRegex.Match(option);
if (match.Success)
{
string id = match.Groups["id"].Value;
string name = match.Groups["name"].Value;
Log.Debug($"Configuration has changed, '{id}.{name}': '{from}' → '{to}'");
dynamic o = Configuration.GetOption(id, name);
// When loaded from profile but not explicitly set, will be null.
// Then load default.
// Same applies to resetting a saved option (= saving null to the profile).
if (to == null)
{
_ = to ?? Config.ApplyDefault(id, name);
}
else
{
// When not null, check if theres a constraint on valid values.
if (o.ValidValues != null)
{
if (!o.ValidValues.Contains(to))
{
// Handle “arrays” of values
bool valid = false;
if (to is string && ((string)to).Contains(";"))
{
valid = true;
foreach (string value in ((string)to).Split(';'))
{
if (!o.ValidValues.Contains(value))
{
valid = false;
}
}
}
if (!valid)
{
Log.Error($@"Invalid value ""{to}"" for option ""{id}.{option}"", reverting to default …");
Config.ApplyDefault(id, name);
}
}
}
// if null, EDDI isnt up yet
if (option == "alterNERDtive-base.eddi.quietMode#" && VA!.GetText("EDDI version") != null)
{
Log.Debug($"Resetting speech responder ({(to ?? false ? "off" : "on")}) …");
Commands.Run("alterNERDtive-base.setEDDISpeechResponder");
}
else if (option == "alterNERDtive-base.log.logLevel#")
{
Log.SetCurrentLogLevel(to);
}
}
}
}
catch (Exception e)
{
Log.Error($"Unhandled exception while handling changed variable '{option}'. ({e.Message})");
}
}
private static void UpdateCheck()
{
Version latestVersion;
try
{
latestVersion = new Version(new WebClient().DownloadString("https://raw.githubusercontent.com/alterNERDtive/VoiceAttack-profiles/release/VERSION"));
}
catch (Exception)
{
throw new Exception("Error fetching latest profiles version from Github.");
}
Log.Notice($"Local version: {VERSION}, latest release: {latestVersion}.");
Commands.TriggerEvent(
"alterNERDtive-base.updateCheck",
parameters: new dynamic[] { new string[] { VERSION.ToString(), latestVersion.ToString() }, new bool[] { VERSION.CompareTo(latestVersion) < 0 } });
}
/*================\
| plugin contexts |
\================*/
#pragma warning disable IDE0060 // Remove unused parameter
private static void Context_Config_Dialog(dynamic vaProxy)
{
Thread dialogThread = new Thread(new ThreadStart(() =>
{
System.Windows.Window options = new ()
{
Title = "alterNERDtive Profile Options",
Content = new SettingsDialog(Config, Log),
SizeToContent = System.Windows.SizeToContent.WidthAndHeight,
ResizeMode = System.Windows.ResizeMode.NoResize,
WindowStyle = System.Windows.WindowStyle.ToolWindow,
};
options.ShowDialog();
options.Activate();
}));
dialogThread.SetApartmentState(ApartmentState.STA);
dialogThread.IsBackground = true;
dialogThread.Start();
}
private static void Context_Config_Dump(dynamic vaProxy)
{
Config.DumpConfig();
}
private static void Context_Config_List(dynamic vaProxy)
{
Config.ListConfig();
}
private static void Context_Config_Setup(dynamic vaProxy)
{
Log.Debug("Loading default configuration …");
Config.ApplyAllDefaults();
foreach (System.Type type in new List<System.Type> { typeof(bool), typeof(DateTime), typeof(decimal), typeof(int), typeof(short), typeof(string) })
{
Config.SetVoiceTriggers(type);
}
Config.LoadFromProfile();
Log.Debug("Finished loading configuration.");
}
private static void Context_Config_SetVariables(dynamic vaProxy)
{
string trigger = vaProxy.GetText("~trigger") ?? throw new ArgumentNullException("~trigger");
Log.Debug($"Loading variables for trigger '{trigger}' …");
Config.SetVariablesForTrigger(vaProxy, trigger);
}
private static void Context_Config_VersionMigration(dynamic vaProxy)
{
// =============
// === 4.3.1 ===
// =============
// EliteAttack
foreach (string option in new string[] { "autoStationService" })
{
string name = $"EliteAttack.{option}s#";
string oldName = $"EliteAttack.{option}#";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } });
bool? value = vaProxy.GetBoolean(oldName);
if (value != null)
{
Log.Info($"Migrating option {oldName} …");
Commands.Run("alterNERDtive-base.saveVariableToProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}" }, new bool[] { (bool)value } });
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } });
}
}
// ===========
// === 4.2 ===
// ===========
// SpanshAttack
string edtsPath = $@"{vaProxy.SessionState["VA_SOUNDS"]}\scripts\edts.exe";
if (File.Exists(edtsPath))
{
File.Delete(edtsPath);
}
// ===========
// === 4.0 ===
// ===========
// EliteAttack
string prefix = "EliteAttack";
string oldPrefix = "EliteDangerous";
foreach (string option in new string[] { "announceEdsmSystemStatus", "announceMappingCandidates", "announceOutdatedStationData", "announceR2RMappingCandidates", "autoRestock", "flightAssistOff", "hyperspaceDethrottle" })
{
string name = $"{prefix}.{option}";
string oldName = $"{oldPrefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } });
bool? value = vaProxy.GetBoolean(oldName);
if (value != null)
{
Log.Info($"Migrating option {oldName} …");
Commands.Run("alterNERDtive-base.saveVariableToProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}#" }, new bool[] { (bool)value } });
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{oldName}", "boolean" } });
}
}
// RatAttack
prefix = "RatAttack";
foreach (string option in new string[] { "autoCloseCase", "announceNearestCMDR", "announcePlatform", "confirmCalls", "onDuty" })
{
string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
bool? value = vaProxy.GetBoolean(name);
if (value != null)
{
Log.Info($"Migrating option {name} …");
Commands.Run("alterNERDtive-base.saveVariableToProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}#" }, new bool[] { (bool)value } });
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
}
}
foreach (string option in new string[] { "CMDRs", "platforms" })
{
string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
string value = vaProxy.GetText(name);
if (!string.IsNullOrEmpty(value))
{
Log.Info($"Migrating option {name} …");
Commands.Run("alterNERDtive-base.saveVariableToProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}#", value } });
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
}
}
// SpanshAttack
prefix = "SpanshAttack";
foreach (string option in new string[] { "announceWaypoints", "autoJumpAfterScooping", "autoPlot", "clearOnShutdown", "copyWaypointToClipboard", "defaultToLadenRange", "timeTrip" })
{
string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
bool? value = vaProxy.GetBoolean(name);
if (value != null)
{
Log.Info($"Migrating option {name} …");
Commands.Run("alterNERDtive-base.saveVariableToProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}#" }, new bool[] { (bool)value } });
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "boolean" } });
}
}
foreach (string option in new string[] { "announceJumpsLeft" })
{
string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
string value = vaProxy.GetText(name);
if (!string.IsNullOrEmpty(value))
{
Log.Info($"Migrating option {name} …");
Commands.Run("alterNERDtive-base.saveVariableToProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}#", value } });
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
}
}
// StreamAttack
prefix = "StreamAttack";
foreach (string option in new string[] { "outputDir" })
{
string name = $"{prefix}.{option}";
Commands.Run("alterNERDtive-base.loadVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
string value = vaProxy.GetText(name);
if (!string.IsNullOrEmpty(value))
{
Log.Info($"Migrating option {name} …");
Commands.Run("alterNERDtive-base.saveVariableToProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}#", value } });
Commands.Run("alterNERDtive-base.unsetVariableFromProfile", wait: true, parameters: new dynamic[] { new string[] { $"{name}", "text" } });
}
}
}
private static void Context_Eddi_Event(dynamic vaProxy)
{
string eddiEvent = vaProxy.Command.Name();
string command = eddiEvent.Substring(2, eddiEvent.Length - 4);
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>"
}
private static void Context_EDSM_BodyCount(dynamic vaProxy)
{
string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\scripts\explorationtools.exe";
string arguments = $@"bodycount ""{system}""";
Process p = PythonProxy.SetupPythonScript(path, arguments);
int bodyCount = 0;
bool error = false;
string errorMessage = string.Empty;
p.Start();
string stdout = p.StandardOutput.ReadToEnd();
string stderr = p.StandardError.ReadToEnd();
p.WaitForExit();
switch (p.ExitCode)
{
case 0:
bodyCount = int.Parse(stdout);
Log.Info($"EDSM body count for {system}: {bodyCount}");
break;
case 1:
error = true;
Log.Error(stdout);
errorMessage = stdout;
break;
case 2:
error = true;
Log.Notice($@"System ""{system}"" not found on EDSM");
errorMessage = stdout;
break;
default:
error = true;
Log.Error(stderr);
errorMessage = "Unrecoverable error in plugin.";
break;
}
vaProxy.SetInt("~bodyCount", bodyCount);
vaProxy.SetBoolean("~error", error);
vaProxy.SetText("~errorMessage", errorMessage);
vaProxy.SetInt("~exitCode", p.ExitCode);
}
private static void Context_EDSM_DistanceBetween(dynamic vaProxy)
{
string fromSystem = vaProxy.GetText("~fromSystem") ?? throw new ArgumentNullException("~fromSystem");
string toSystem = vaProxy.GetText("~toSystem") ?? throw new ArgumentNullException("~toSystem");
int roundTo = vaProxy.GetInt("~roundTo") ?? 2;
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\explorationtools.exe";
string arguments = $@"distancebetween --roundto {roundTo} ""{fromSystem}"" ""{toSystem}""";
Process p = PythonProxy.SetupPythonScript(path, arguments);
decimal distance = 0;
bool error = false;
string errorMessage = string.Empty;
p.Start();
string stdout = p.StandardOutput.ReadToEnd();
string stderr = p.StandardError.ReadToEnd();
p.WaitForExit();
switch (p.ExitCode)
{
case 0:
distance = decimal.Parse(stdout);
Log.Info($"{fromSystem} → {toSystem}: {distance}ly");
break;
case 1:
case 2:
error = true;
Log.Error(stdout);
errorMessage = stdout;
break;
default:
error = true;
Log.Error(stderr);
errorMessage = "Unrecoverable error in plugin.";
break;
}
vaProxy.SetDecimal("~distance", distance);
vaProxy.SetBoolean("~error", error);
vaProxy.SetText("~errorMessage", errorMessage);
vaProxy.SetInt("~exitCode", p.ExitCode);
}
private static void Context_Log(dynamic vaProxy)
{
string message = vaProxy.GetText("~message");
string level = vaProxy.GetText("~level");
if (level == null)
{
Log.Log(message);
}
else
{
try
{
Log.Log(message, (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper()));
}
catch (ArgumentNullException)
{
throw;
}
catch (ArgumentException)
{
Log.Error($"Invalid log level '{level}'.");
}
}
}
private static void Context_Spansh_OutdatedStations(dynamic vaProxy)
{
string system = vaProxy.GetText("~system") ?? throw new ArgumentNullException("~system");
int minage = vaProxy.GetInt("~minage") ?? throw new ArgumentNullException("~minage");
bool includeSettlements = vaProxy.GetBoolean("~includeSettlements") ?? throw new ArgumentNullException("~includeSettlements");
string path = $@"{vaProxy.SessionState["VA_SOUNDS"]}\Scripts\spansh.exe";
string arguments = $@"oldstations --system ""{system}"" --minage {minage}{(includeSettlements ? string.Empty : " --nofeet")}";
Process p = PythonProxy.SetupPythonScript(path, arguments);
p.Start();
string stdout = p.StandardOutput.ReadToEnd();
string stderr = p.StandardError.ReadToEnd();
p.WaitForExit();
string message = stdout;
string? errorMessage = null;
bool error = true;
switch (p.ExitCode)
{
case 0:
error = false;
Log.Notice($"Outdated stations for {system}: {message}");
break;
case 1:
error = true;
Log.Error(message);
break;
case 3:
error = true;
Log.Info($@"No outdated stations found for ""{system}""");
break;
default:
error = true;
Log.Error(stderr);
errorMessage = "Unrecoverable error in plugin.";
break;
}
vaProxy.SetText("~message", message);
vaProxy.SetBoolean("~error", error);
vaProxy.SetText("~errorMessage", errorMessage);
vaProxy.SetInt("~exitCode", p.ExitCode);
}
private static void Context_Startup(dynamic vaProxy)
{
Log.Notice("Starting up …");
CheckProfiles(vaProxy);
Log.Notice($"Active profiles: {string.Join(", ", ActiveProfiles)}");
Commands.TriggerEventAll(ActiveProfiles, "startup", logMissing: false);
Log.Notice("Finished startup.");
}
private static void Context_Update_Check(dynamic vaProxy)
{
UpdateCheck();
}
#pragma warning restore IDE0060 // Remove unused parameter
}
}

View file

@ -0,0 +1,81 @@
// <auto-generated/>
// Not really, but this file will not bow to StyleCop tyranny.
// Why? Because it will be obsolete mid term anyway ;)
// <copyright file="edts.cs" company="alterNERDtive">
// Copyright 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>
#nullable enable
using System;
using System.Net.Http;
using System.Net.Http.Headers;
namespace alterNERDtive.edts
{
public struct StarSystem
{
public string Name { get; set; }
public Position Coords { get; set; }
}
public struct Position
{
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
public int Precision { get; set; }
}
public class EdtsApi
{
private static readonly string APIURL = "http://edts.thargoid.space/api/v1/";
private static HttpClient ApiClient;
static EdtsApi()
{
ApiClient = new HttpClient
{
BaseAddress = new Uri(APIURL)
};
ApiClient.DefaultRequestHeaders.Accept.Clear();
ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public static StarSystem GetCoordinates(string name)
{
HttpResponseMessage response = ApiClient.GetAsync($"system_position/{name}").Result;
if (response.StatusCode == System.Net.HttpStatusCode.BadRequest) // 400
{
throw new ArgumentException($"“{name}” is not a valid proc gen system name.", "~system");
}
response.EnsureSuccessStatusCode();
dynamic json = response.Content.ReadAsAsync<dynamic>().Result["result"];
int x = json["position"]["x"];
int y = json["position"]["y"];
int z = json["position"]["z"];
int uncertainty = json["uncertainty"];
return new StarSystem { Name=name, Coords=new Position { X=x, Y=y, Z=z, Precision=uncertainty } };
}
}
}

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

BIN
profiles/RatAttack-Profile.vap Executable file

Binary file not shown.

Binary file not shown.

BIN
profiles/StreamAttack-Profile.vap Executable file

Binary file not shown.

Binary file not shown.

1
requirements.txt Normal file
View file

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

16
stylecop.json Normal file
View file

@ -0,0 +1,16 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"orderingRules": {
"usingDirectivesPlacement": "outsideNamespace"
},
"documentationRules": {
"companyName": "alterNERDtive",
"copyrightText": "Copyright {year} {companyName}.\n\nThis file is part of {application}.\n\n{application} is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\n{application} is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with {application}. If not, see <https://www.gnu.org/licenses/>.",
"variables": {
"application": "alterNERDtive VoiceAttack profiles for Elite Dangerous",
"year": "20192022"
}
}
}
}