AdiBorsos/AutoSteamworks

Send inputs with PostMessage() to avoid having to have the window focused.

Opened this issue · 10 comments

Using PostMessage() to send events to the process would allow for the program to operate out of focus, e.g., while alt tabbed.

I'm afraid if I try to implement this I'll break some stuff because I haven't gone through the entire codebase, however if you want me to I can take a crack at it and submit a PR.

Yea, i was looking into this before this update. Unfortunately i am busy right now and won't be able to continue looking into it.
..plus, have to update the app for the new version of the game.

It not being updated also discouraged me from giving it a shot, since I don't want to waste my coal testing it in random, but if someone else handles that I can take a crack at this.

haha waste your coal :). I am glad making this mod made you think of coal as something valuable :p.

As long as decos are in the loot table, I want to get the most out of the coal. Farming it isn't exactly on the top of my most fun things to do.

I tried some test code with the concept of writing the Ark script previously. It may be that I have insufficient experience with PostMessage. This worked in the mhw's player dialog (will type 'A' key), but the steamworks did not respond.

`
class Program
{
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

static void Main()
{
    Process mhw = Process.GetProcessesByName("MonsterHunterWorld")[0];
    IntPtr hwnd = FindWindow(null, mhw.MainWindowTitle);
    if (mhw != null && hwnd != null)
    {
        PostMessage(hwnd, 0x0100, (IntPtr)Keys.A, (IntPtr)0);
        
        Console.WriteLine(mhw + "(hwnd=" + hwnd + ", handle=" + mhw.Handle + ")" + " -> A");
    }
    Console.Read();
}

}
`

I've given it a shot in many different ways and have gotten the same results.
My wild guess is that the input the Steamworks uses is locked when the window is off focus.
(When using a controller holding R, I noticed that if I alt tabbed it continued to go even after letting go of the button, I don't know enough to know if this supports my guess, or disproves it)

Have you accounted for the input lag? A reason why i spam buttons is that when triggering a key via software, the action happens so fast the game doesn't process it. It is why on some computers the reset animation functionality is not instant.
In short, try setting key down, wait a time period, set key up. This might work..maybe

I tried having 100ms between the keydown and keyup events, didn't help.

After a few tests myself i think i found the issue and a possible solution - even though i don't think it is worth the trouble.
I managed to send input in background and i can write text when the Chat is open, this means we can actually send the keys correctly to the app.
The bad part is that steamworks is not processing keys the same way as chat does - i think it uses getasynckeystate - which can't be fooled by sendmesaage or postmessage. This means we need another solution there.
The solution which MIGHT work is to use a keyboard driver to emulate an actual keyboard device and work through that - i found some code for this but it requires you to install some 3rd party non open source driver (which i can't vouch for) which can be controlled by software calls.
All this MIGHT work because it would be like an actual device sends key presses.

Kinda old issue but just for future reference in case someone wants to implement this. While developing HunterPie I also stumbled with this input issue, and yes, MHW does indeed get the keys pressed in game by calling GetAsyncKeyState, I did manage to find a way to implement an input injection though, here's my solution. Note that although HunterPie does it by injecting a DLL, it is also possible to implement it without injecting anything (by calling WriteProcessMemory.