tanrr / Tanrr.VAPlugin.BMSRadio

VoiceAttack Plugin for BMS Radio Menus
GNU General Public License v3.0
2 stars 1 forks source link

Jeeves BMS Radio Menus (Tanrr.VAPlugin.BMSRadio)

v0.2.0 - tested with Falcon BMS 4.37.2 - (for BMS 4.37.1 use plugin v0.1.2)

Jeeves BMS Radio Menus is a powerful plugin for VoiceAttack to work with Falcon BMS radio menus. It is flexible, with a number of features, while being relatively fast and light weight. The plugin is designed to work well for new users learning the radio menus, but has features supporting advanced users who know most of the menus.

Users call up radio menus by saying a menuTarget such as "2" or "Flight" followed by an appropriate menuName, such as "Combat 3". While the menu is displayed the plugin listens for phrases matching menu items. Thus users who are not familiar with the menus can look through them to make their choices.

Calls outside your flight are similar, but may not need the menu name. For example, "Tanker" or "Tower" will just bring up the tanker or tower menu.

You can use over 150 callsigns for AWACS, tankers, JTAC and your own flight! Calls like "Arco 3, Viper 2, Two-Ship F16 - Request Flight Refueling" just work. You can change your own callsign or aircraft type on the fly by voice command. Many variations of phrases are also supported.

It is easy to update JBMS to match updates to the game, and to change recognition phrases for menuTargets, menuNames, and menuItems to work for you.

New for v0.2.0 is the ability to set specific menus to not display while waiting for a response and to add multiple menus to a group menu. See later sections "Direct Menus" and "Group Menus" for details.

Additional ease of use features include adding direct commands that don't leave menus up, as well as the ability to have menu items call your own methods in the VoiceAttack profile.

This is a personal project, so use at your own risk. With that said, I hope to keep this up to date with new versions of Falcon BMS and welcome feedback through GitHub's Issue reporting. The current GitHub project is at https://github.com/tanrr/Tanrr.VAPlugin.BMSRadio.

The extended functionality is what makes this useful:

INSTALLATION:

This plugin uses Newtonsoft.Json.dll version 13.0.2, and Newtonsoft.Json.Schema.dll version 3.0.14.
They are included, or you can download your own versions. Note that STEP 3 copies the Newtonsoft.Json.dll file to a different directory.

Remove Any Previous Install

Install New Version

  1. Make sure that "Enable Plugin Support" is enabled (VoiceAttack Settings (Wrench icon) under "General"), then shut down VoiceAttack
  2. Move the Tanrr.VAPlugin.BMSRadio folder into the folder ..\VoiceAttack\Apps. This should leave the dlls and related files under ..\VoiceAttack\Apps\Tanrr.VAPlugin.BMSRadio.
  3. IMPORTANT: From the Tanrr.VAPlugin.BMSRadio folder, COPY the Newtonsoft.Json.dll file into the ..\VoiceAttack\Shared\Assemblies folder.
    If you have different versions of Newtonsoft.Json.dll installed, you may need to also copy VoiceAttac.exe.config from the plugin folder to the folder that VoiceAttack.exe is in.
  4. Launch VoiceAttack and import Jeeves BMS Radio Menus Profile.vap
  5. Shut down, then relaunch VoiceAttack, so the updated profile can initialize the updated plugin
  6. If you had custom phrases in the JSON file, merge them by hand (usually easy to do).
    If you had custom phrases in the VA profile, copy them to the new profile.
  7. HOTKEYS: The VoiceAttack profile provided only sets a hotkey of F24 (hold to listen) for VoiceAttack. You will want to change the hotkeys to whatever keyboard keys or game controller buttons you use. Hotkeys can be set globally (VoiceAttack Settings, Hotkeys) or just for the profile (Edit Profile, Options, Profile Hotkeys).
  8. Optionally restrict plugin from generating keystrokes if BMS does not have focus. See Restricting Plugin when BMS Not Active

** See recommended VoiceAttack settings at the end of this document **

DETAILS:

Restricting Plugin when BMS Not Active

The plugin can listen for application focus changes so if you alt+tab away from BMS it can stop sending keystrokes until BMS has focus again. To allow the plugin to catch app focus changes, Select "Enable Auto Profile Switching" in VoiceAttack Settings, General Tab and set >JBMS_KEYS_ONLY_TO_BMS to true in JBMS Initial Load Init in VA profile. You will need to restart VoiceAttack after this for the plugin to get focus change events.

You can change enable or disable the focus requirement with the voice command "Enable/Disable B M S Focus Only".

Note that this isn't a perfect solution, but it should avoid most problems. If a menu was up, or you were listing menus, when you alt-tabbed away the plugin will stop listening for menu items or iterating menus. You can still say "Press [0..9]" to choose a menu item for a menu that is up, or just say "Cancel" or "Reset Menu" to bring it down.

BMS Menus

Details of the BMS Radio menus can be found BMS-Comms-Nav-Book.pdf in which is in your BMS folder under Docs\00 BMS Manuals. The relevant sections are:

Direct Menus

Specific menus can be marked in the JSON with "isDirectMenu": true. A user can make the same calls for these menus, but the menu is not displayed while the VoiceAttack listens for menu item choices. This lets a user mark which menus they don't need displayed, since they use them all the time and know them well, while letting other menus they don't have memorized still display normally.

For example, when making the previous a call to "Tower" the plugin would wait till the user had made the full call, including "Request Landing", then it would pop up the menu (briefly) before sending the keystrokes for the "Request Landing" menu item.

NOTE: There will be a slight delay (less than 1/4 second) after the part of the call that brings the menu up, before the system can listen for the menu item - the audible feedback let's you know when the system is listening. Note that single Direct Menus (vs Group Menus) are still a work in progress.

Group Menus

Specific menus can set "directMenuGroup" to a group name in the JSON to allow grouping multiple menus together that listen (like a Direct Menu) for any menu items from all menus in the group without having a menu up.

This is quite useful and STILL ALLOWS NORMAL USE OF THOSE MENUS. Two groups are already set in the JSON, the "Approach" group for Approach 1 & Approach 2 and the "AWACS" group for AWACS Tactical & AWACS Vectors. You can still pull up the specific menu by saying "Approach 1/2" or "AWACS/Overlord Tactical/Vectors". Examples using the groups:

"Tower, Viper 1, Two-Ship F16 - Request Visual Approach"
"Darkstar, Hunter 6, Four-Ship F16 - Request Vector to Tanker"

Group menus dynamically create a new menu you can call up from the VoiceAttack profile. To do this, set >JBMS_MENU_TGT to "group" and >JBMS_MENU_NAME to the "directMenuGroup" name, then execute the profile command JBMS Direct Listen Start. Just duplicate the "Approach" or "AWACS" profile commands to make your own version.

Note when grouping menus that there is a limit of 500 distinct phrases that can be matched (see Limitations).

Limitations

VoiceAttack Variables

>JBMS variables can be changed by the VA profile CAREFULLY, but should only be used in the same way (to pass info to the plugin, or check return states from the plugin). You can set the Boolean _LOG variables (initialized in "JBMS Initial Load Init") to true for additional logging, or you can enable/disable them by voice.

>JBMSI internal variables should NOT be changed by the VA profile, EXCEPT for the provided methods provided that use them. Changes to them could easily break the plugin.

A partial list of variables:

\>JBMS_JSON_LOG       Boolean for logging of JSON parsing
\>JBMS_MENU_LOG       Boolean for logging of menu items (shows list of menu items in log)
\>JBMS_STRUCT_LOG     Boolean for logging of data structures manipulation
\>JBMS_VERBOSE_LOG    Boolean for more verbose general logging

\>JBMS_AUDIO_FEEDBACK    User set boolean to allow audible feedback for commands
\>JBMS_KEYS_ONLY_TO_BMS  User set boolean to restrict keystrokes if BMS does not have focus
\>JBMSI_FOCUS_BMS        Boolean usually set to true if BMS has focus

>JBMS_MENU_TGT     ONLY to set menuTarget before calling plugin w/ context "JBMS_SHOW_MENU"
>JBMS_MENU_NAME    ONLY to set menuName before calling plugin w/ context "JBMS_SHOW_MENU"
>JBMS_DIRECT_CMD   ONLY to set directCommand before calling plugin w/ context "JBMS_DIRECT_CMD"

>JBMSI_NO_SUCH_MENU   READ-ONLY - (Checked & set only by "JBMS Radio Menu Show" command)
>JBMSI_MENU_RESPONSE  READ-ONLY - (Checked & set only by "JBMS Wait For Menu Response" command)

>>JBMSI_CS_MATCH"           READ-ONLY - (Phrase matching callsign with optional flight #: "[Fiend;Fiend 3]")
>>JBMSI_CS_MATCH_EMPTY_OK"  READ-ONLY;  (Allows matching callsign or nothing: "[Fiend;Fiend 3;]"

JSON FORMAT:

The JSON menu file Tanrr.VAPlugin.BMSRadio.Menus.json is a top level array of menus. Each menu has the format shown below.

EXAMPLE JSON MENU:

{
    "menuTarget": "Flight",
    "targetPhrases": "Flight",
    "menuName": "Miscellaneous 1",
    "menuNamePhrases": "[Miscellaneous;Misk] [1;]",
    "isDirectMenu": false,
    "directMenuGroup": "",
    "menuShow": [ "rrrrrrr" ],

    "menuItems": [
        [ "Fence In", "1", "JBMS-FX1-FENCE-IN" ],
        [ "Fence Out", "2" ],
        [ "Lights [S O P;Ess Oh Pea]", "3" ],
        [ "Music On", "4" ],
        [ "Music Off", "5" ],
        [ "[Turn;] Smoke On", "6" ],
        [ "[Turn;] Smoke Off", "7" ],
        [ "[Switch;Push] Flight Uniform", "DC Push Flight Uniform" ],
        [ "[Switch;Push] Flight Victor", "9" ],
        [ "Set Bingo", "0" ]
    ]
},

REQUIRED:

NOTES:

CALLSIGN JSON: The callsign JSON holds arrays of strings for AWACS, Tanker, JTAC, and pilot callsigns. Just follow the format of the config file. Strings containing multiple callsigns (no numbers or spaces allowed) are delimited by semicolons. No semicolons allowed at beginning or end of strings and no double semicolons. Callsigns should not be duplicated between any groups.

Put your desired default callsignFlight, numberFlight, and posInFlight in the "flightInfo" section. "callsignFlight" can not be an empty string nor can it contain spaces or semicolons. numberFlight and PosInFlight can be empty strings, or can be a string holding a single digit, 1-9 for number and 1-4 for position. You can change all these on the fly with a voice command "Update Callsign Plasma 6" or similar.

EDITING JSON FILES:

The menu menu and callsign JSON and schema files are installed in ..\VoiceAttack\Apps\Tanrr.VAPlugin.BMSRadio. You can use an online JSON schema validator, like https://jsonmate.com/ to validate changes you make to the JSON menu/callsign files against their matching schema while you work on it.

Menu JSON: Tanrr.VAPlugin.BMSRadio.Menus.json
Menu Schema JSON: Tanrr.VAPlugin.BMSRadio.Menus.Schema.json
Callsign JSON: Tanrr.VAPlugin.BMSRadio.Callsigns.json
Callsign Schema JSON: Tanrr.VAPlugin.BMSRadio.Callsigns.Schema.json

KEYSTROKES TO SHOW EACH MENU:

menuShow is an array of (possibly) multiple strings that contain the keystrokes to bring up a menu. The list of keystrokes is sent to the command "JBMS Press Key Combo List" in the VA profile. This gives good flexibility but has some restrictions.

A silly example would be if you ran the below menuShow with an empty Notepad active.
It would type Hello then make the text larger and smaller before saying bye.

"menuShow": [ "[SHIFT]H", "ello", "[LCTRL]=", "[RCTRL]=", "[CTRL]-", "[CTRL]-", "[LCTRL]A", "bye" ],

PHRASES TO SELECT MENU ITEMS:

MenuItemPhrases (1st text field in each array within menuItems) are the VoiceAttack command phrases the plugin will listen for while this menu is up. They are the same format as VoiceAttack commands: multiple options, separated by semi-colons, sub-sections specified by [brackets]. Note that sub-sections can match to nothing as well by having a ; with nothing after it.

For example: "[Switch;Push] [Flight;] Uniform" matches all these phrases:

The provided VA profile already includes the command "Press [0..9]"" which will press the number keys for you, and these work even if the menu is not up. DO NOT add the menu number as part of the recognition phrases. It could interfere with other phrases - for example "2" and "3" are used as prefix menuTargets.

KEYSTROKES FOR MENU ITEMS:

MenuItemExecute (2nd text field in each array within menuItems) are normally set to the keystroke(s) to press when that menu item is chosen. These keys will be passed to the the VA profile "JBMS Press Key Combo List" command and are handled like a single string of the menuShow field. This means you can have multiple simple non-shifted keys like "aaa" or a single keystroke or special key with modifiers, like "[LCTRL]a". (Unless they match a VA command as described later.)

You can change the "JBMS Press Key Combo List" command in the VA profile to adjust keypress time and pause times - see the "Press variable keys" and "Quick Input" calls within the command. Those times are set somewhat conservatively long to work on all systems, so if you change the times make sure you test that they work for busy multiplayer servers and your own system.

See the "DC Push Flight Uniform" command in the VA profile as an example of how to use MenuItemExecute as a command. The profile command includes comments on how to edit the menu JSON to call it.

MAPPING VOICEATTACK PHRASES DIRECTLY TO MENU ITEMS:

Direct Command Calls (to execute a menu item directly from a VA command phrase without leaving a menu up and waiting for a menu selection) are made possible by adding a third menuItemDirectCmd string to the array for that menu item in menuItems. These should be unique and preferably identify the menuTarget, menuName, and menuItem they're for, as described in the menuTarget/menuName abbreviations section later on.

To use this functionality, add your own command phrase to the VA profile, and have it set the >JBMS_DIRECT_CMD variable to the command name before calling the plugin with context set to JBMS_DIRECT_CMD.

The provided VA profile has some examples of this:

Note that it is OKAY for your VA profile to use phrases that duplicate the phrases for the various menu items, because (1) the menu item phrases are only listened for when the specific menu is up, and (2) duplicate phrases that call JBMS_DIRECT_CMD while a menu is up will be dropped as the menu phrases have priority.

MAPPING MENU ITEMS TO YOUR OWN CUSTOM COMMANDS:

If you set menuItemExecute (2nd text field in each array within menuItems) to match the name of a unique command within the VA profile, the plugin will execute that command, instead of pressing keys matching the letters in the string. It is strongly recommended that you make such commands NOT callable by voice to avoid conflicting menu states. Your implementation of such a VA command should NOT call back into the plugin with a "JBMS_DIRECT_COMMAND" for the same menu item as this would create a never-ending loop.

Your menuItemExecute VA command (if not keypresses) should not be long running as the plugin will wait for it to return. Your command can look at the >JBMS_MENU_TGT and >JBMS_MENU_NAME variables which will still be valid till your command returns. Your command is responsible for making sure the menu is dismissed, either by pressing a key to choose a menu item, or by executing "Dismiss Menu Only" command in the VA profile. Your command SHOULD NOT call the plugin with context JBMS_RESET_MENU_STATE as that will be done by the plugin after your command finishes.

CUSTOMIZING THE VOICEATTACK PROFILE

The profile command "JBMS Initial Load Init" sets default logging options.
You can change these to have more logging. You can also change log settings on the fly with the voice command "[Enable;Disable] [Jason;Menu;Struct;Struture;Verbose] Logging".

The amount of time the profile waits for responses for a menu before dismissing it is set in "JBMS Wait For Menu Response" command, within the "Wait for spoken response" call. It is currently left at 15 seconds, which is pretty long. Change it to whatever works for you.

As mentioned earlier, you can change the timing for keypresses and pauses in the "JBMS Press Key Combo List" command. Make sure you verify changes work for your system and the servers you play on.

Though you can add your own commands directly to this JBMS Radio profile, it is probably better to make your own separate profile and include it from this profile. This can be done by editing the JBMS Radio profile, clicking OPTIONS, going to the General tab, and adding your profile to the *"Include Commands from Other Profiles" section. NOTE: This can strongly effect the accuracy of the VA profile by adding many or conflicting commands, so make sure your additional profile is lightweight and does not include tons of commands.

Note that Voice Attack commands that call the "Internal Reset Menu" command need to have "Allow Other Commands to Execute While This One is Running" checked.

VOICEATTACK BASICS & RECOMMENDED SETTINGS

BASICS:

RECOMMENDED SETTINGS:

VoiceAttack Settings, Recognition tab: See VA docs under "Recognition Tab" for deeper descriptions.

TROUBLESHOOTING

MENUTARGET & MENUNAME ABBREVIATIONS USED FOR DIRECT COMMANDS (NOT REQUIRED BUT HELPFUL):

menuTarget abbreviations:
  W-ingman
  E-lement
  F-light
  T-ATC
  Q-AWACS
  Y-Tanker/JTAC

menuName abbreviations (followed by 1 or 2/3 etc. for multiples)
  C-ombat
  M-ission
  F-ormation
  X-Misc
  R-unway

  G-round
  T-ower
  A-pproach
  D-eparture
  N-Common
  C-arrior & LSO
  B-Abort

  Q-Awacts Tactical (so QQ)
  V-Awacs Vectors   (so QV)

  T-Tanker (so YT)
  J-JTAC (so YJ)

For example, Wingman, Combat 1 menu for Attack My Target would be "JBMS-WC1-ATTACK-TGT" or something similar.