Expose API for simulated Keyboard/Mouse events
etfre opened this issue ยท 3 comments
I'm working on a mod to play Stardew Valley by voice without using keyboard or mouse. In order to do this the mod needs to simulate keyboard and mouse events when speech is recognized. The keyboard bit is relatively straightforward to imitate with DirectInput, but it seems that mouse clicks are being suppressed. Right now I have the following workaround with SMAPI:
dynamic inputState = Utils.GetPrivateField(helper.Input, "CurrentInputState")();
Utils.GetPrivateField(inputState, "CustomPressedKeys").Add(SButton.MouseLeft);
Utils.SetPrivateField(inputState, "HasNewOverrides", true);
It would be great if there was a public API so this felt a bit less hacky/fragile.
SMAPI has a hidden method for input overrides (mainly meant for Virtual Keyboard on Android):
/// <summary>Override the state for a button.</summary>
/// <param name="button">The button to override.</param>
/// <param name="setDown">Whether to mark it pressed; else mark it released.</param>
public void OverrideButton(SButton button, bool setDown);
You can use reflection to access it like this:
MethodInfo overrideButton = Game1.input.GetType().GetMethod("OverrideButton")
?? throw new InvalidOperationException("Can't find 'OverrideButton' method on SMAPI's input class.");
overrideButton.Invoke(Game1.input, new object[] { SButton.MouseLeft, true });
That should work much more consistently then setting the underlying fields directly. It's not part of the public API (since it hasn't gone through that level of API design/review) so it may change without warning, but it's unlikely to change in the foreseeable future.
This is working well enough that I'll probably end up using it for the keyboard too. Appreciate the help.