the reason CE can recognize the input 22531 is because it's made explicitly aware of this, and sends itself that message.
-Thanks, DB. I figured as much.
Unfortunately, nothing that I have tried thus far has worked, and I have tried many different things. You would think that even if the target interprets the data differently, that just figuring out what windows uses would be sufficient here since the target can clearly recognize the external input correctly that it is receiving.
I made my timer-based state machine and the internal flags look good, I get the following trace output (print) as required:
Quote:
Foreground
Normal
Foreground
Normal
Foreground
Normal
Block -> keyDown(VK_NUMPAD0)
Foreground
Release -> keyUp(VK_NUMPAD0)
Foreground
Normal
Foreground
Normal
Where it says "Foreground", the focus is on the game (correct).
Where it says "Normal", the focus is on the game (correct) and we have nothing to do.
Where it says "Block" after "Normal", I have a call to keyDown(VK_NUMPAD0) but it does nothing.
Where it says "Release", the focus is on the game (correct), I have a call to keyUp(VK_NUMPAD0). I can't tell whether this works because the KeyDown does not work.
Any ideas?
Thank you!
I assume you have tested this code and keyboard keystrokes are working properly.
Code:
function postFrm1()
keyDown(VK_NUMPAD0)
sleep(400)
keyUp(VK_NUMPAD0)
end
if niceKy1 then niceKy1.Destroy() niceKy1=nil end
niceKy1=createHotkey(postFrm1, VK_O)
-------------------------- test foreground
Put the following code into the lua script in a separate CE window and open a blank notepad.
Game window: If CE is in the foreground
out of window (key down): If Notepad is in the foreground.
Note: When Notepad is in the foreground, click it to write "0".
Code:
if tmr22 then tmr22.Destroy() tmr22=nil end
tmr22=createTimer()
tmr22.Interval=500
tmr22.Enabled=false
--------------------------------
local ctpid = 0
--Get the trainer window ID.
if ctpid==0 then ctpid = getForegroundProcess() end
print(ctpid)
local gmpid = getProcessIDFromProcessName("notepad.exe")
-- no focused lua engine ..
getLuaEngine().cbShowOnPrint.Checked=false
--------------------------------
kyPrss = 0
function foregroundW1()
pd = getForegroundProcess()
if tonumber(pd)==tonumber(ctpid) then
print("Foreground")
print("Normal")
if kyPrss==1 then
print("Release - > keyDown(VK_NUMPAD0) ")
kyPrss=0
end
elseif tonumber(pd)==tonumber(gmpid) then -- notepad
if kyPrss==0 then
print("Block - > keyDown(VK_NUMPAD0) ")
keyDown(VK_NUMPAD0)
kyPrss=1
end
end
end
tmr22.OnTimer = foregroundW1
tmr22.Enabled=true
result:
Foreground
Normal
Foreground
Normal
Foreground
Normal
Block - > keyDown(VK_NUMPAD0)
Foreground
Normal
Release - > keyDown(VK_NUMPAD0)
Foreground
Normal
Foreground _________________
I assume you have tested this code and keyboard keystrokes are working properly.
Not really, I need to send keystrokes to a process based on a flag and a timer, not when CE detects a keystroke.
AylinCE wrote:
-------------------------- test foreground
Put the following code into the lua script in a separate CE window and open a blank notepad.
This is a single keystroke, not holding a key for a specified amount of time (not that doKeyPress works).
Here's what I have:
Code:
globalalloc(bShouldWeBlock,4)
{$lua}
if not syntaxcheck then synchronize(function()
local name = 'autoBlockTimer'
local autoBlockTimer = MainForm.findComponentByName(name)
if autoBlockTimer and autoBlockTimer.destroy() then autoBlockTimer=nil end
autoBlockTimer = createTimer(MainForm,false)
autoBlockTimer.Name = name
autoBlockTimer.Interval = 100
autoBlockTimer.OnTimer = function(autoBlockTick)
--print("----- Tick")
local waitTimeNormal = 100
local waitTimeBlocking = 1000
if getOpenedProcessID()==getForegroundProcess() then
print("Foreground")
if autoBlockTimer.Interval==waitTimeNormal then
print("Normal")
if readInteger('bShouldWeBlock')==1 then
print("Block -> keyDown(VK_NUMPAD0)")
-- We start blocking
keyDown(VK_NUMPAD0) -- https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
-- Switch mode
autoBlockTimer.Interval=waitTimeBlocking -- we go wait longer for the block to complete
end
elseif autoBlockTimer.Interval==waitTimeBlocking then
print("Release -> keyUp(VK_NUMPAD0)")
-- We stop blocking
keyUp(VK_NUMPAD0) -- https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
-- Switch mode (reset)
autoBlockTimer.Interval=waitTimeNormal -- we go back to normal wait time (detection)
writeInteger('bShouldWeBlock',0)
end
end
end -- OnTimer
autoBlockTimer.Enabled = true
end) --[[ synchronize]] end -- syntaxcheck
{$asm}
Everything works as intended, except nothing happens in-game (as if NUM0 is never pressed).
Press "NUM0" is running.
But since the transition is fast, you, windows, keyboard, game cannot detect it.
With the "PressBlock" factor, hits are detected as seen in the picture.
"if pressBlck==2 then" detects only on the 2nd hit.
If you do more "if pressBlck==5 then", you will see 3 "0"s.
Also, I could not see the benefit of the "synchronized" option and I did not understand the assignment of a separate "Name" for "Timer".
The code works flawlessly in this state.
Game window and selected action; Notebook.
I recommend you test it as it is and then adapt it to your scenario.
Code:
--local name = 'autoBlockTimer'
--local autoBlockTimer = MainForm.findComponentByName(name)
addr1 = "2188D753A90" -- notepad.exe search: 1000
if autoBlockTimer and autoBlockTimer.destroy() then autoBlockTimer=nil end
autoBlockTimer = createTimer(MainForm,false)
--autoBlockTimer.Name = name
local waitTimeNormal = 100
local waitTimeBlocking = 1000
autoBlockTimer.Interval = waitTimeNormal
local pressBlck=0
if getOpenedProcessID()==getForegroundProcess() then
print("Foreground")
if autoBlockTimer.Interval==waitTimeBlocking then
print("Release -> keyUp(VK_NUMPAD0)")
-- We stop blocking
keyUp(VK_NUMPAD0) -- https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
-- Switch mode (reset)
autoBlockTimer.Interval=waitTimeNormal -- we go back to normal wait time (detection)
writeInteger(addr1,0)
pressBlck=0
end
if autoBlockTimer.Interval==waitTimeNormal then
print("Normal "..readInteger(addr1))
if readInteger(addr1)==1 then
-- We start blocking
keyDown(VK_NUMPAD0)
pressBlck=tonumber(pressBlck) + 1
if pressBlck==2 then
print("Block -> keyDown(VK_NUMPAD0)")
autoBlockTimer.Interval=waitTimeBlocking
end
-- Switch mode
-- we go wait longer for the block to complete
end
end
end
end -- OnTimer
function start()
autoBlockTimer.Enabled = true
end
start()
-------------------------------------------------
Off-topic: I coded your recommendation for the "getMemoryViewForm()" form.
It will take some time since I haven't used "structure dissect" before.
I will update the article when I complete it.
Thanks for the feedback and insight. _________________
Also, I could not see the benefit of the "synchronized" option and I did not understand the assignment of a separate "Name" for "Timer".
Oh, the code above is a partial copy from an AA script - there's a lot more in there with detecting and setting the flag in the first place. There's also code in the DISABLE section to find the timer and destroy it. Hence, a specific name is needed to find the right timer.
Thanks for your inputs, I will go through it once I got some sleep
This part I did not get:
AylinCE wrote:
But since the transition is fast, you, windows, keyboard, game cannot detect it.
As far as I know, keydown() presses the key down without release. Then I wait a second before calling keyup(). How come it's "too fast"?
AylinCE wrote:
Off-topic: I coded your recommendation for the "getMemoryViewForm()" form.
Since the "sleep()" factor will affect the entire code, I added "pressBlck".
Code:
pressBlck=tonumber(pressBlck) + 1
if pressBlck==2 then
-- code
end
So, when "NUM0" is clicked, you, game and windows will see or feel the keystroke.
I think "writeInteger" works faster than a keystroke, and after setting the value to "0", the "100" range code passes faster.
You can also use "pressBlck" there to guarantee the up position of the key as well.
Of course, when it comes to the target limit, don't forget to set it back to "0" before exiting.
Code:
pressBlck=tonumber(pressBlck) + 1
if pressBlck==2 then
-- code
pressBlck=0
end
----------------------------------
Based on your answer for Timer naming;
You can kill at the end of the code (on Closing), not within the code.
Look at this example;
Code:
[ENABLE]
{$lua}
if syntaxcheck then return end -- ops ..! "not" !
local indx = 0
Since the "sleep()" factor will affect the entire code, I added "pressBlck".
Well, your state machine works as well as mine, and yet, nothing happens in the game.
My code, having adopted yours (just the core):
Code:
autoBlockTimer.OnTimer = function(autoBlockTick)
if getOpenedProcessID()==getForegroundProcess() then
print("Foreground, interval: "..autoBlockTimer.Interval.." pressBlck: "..pressBlck)
if autoBlockTimer.Interval==waitTimeBlocking then
print("Release -> keyUp(VK_NUMPAD0)")
-- We stop blocking
keyUp(VK_NUMPAD0) -- https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
-- Switch mode (reset)
autoBlockTimer.Interval=waitTimeNormal -- we go back to normal wait time (detection)
writeInteger('bShouldWeBlock',0)
pressBlck=0
end
if autoBlockTimer.Interval==waitTimeNormal then
print("Normal "..readInteger('bShouldWeBlock'))
if readInteger('bShouldWeBlock')==1 then
-- We start blocking
keyDown(VK_NUMPAD0)
pressBlck=tonumber(pressBlck) + 1
if pressBlck==2 then
print("Block -> keyDown(VK_NUMPAD0)")
autoBlockTimer.Interval=waitTimeBlocking
end
-- Switch mode
-- we go wait longer for the block to complete
end
end
And its output:
Code:
Foreground, interval: 100 pressBlck: 0
Normal 0
Foreground, interval: 100 pressBlck: 0
Normal 1
Foreground, interval: 100 pressBlck: 1
Normal 1
Block -> keyDown(VK_NUMPAD0)
Foreground, interval: 1000 pressBlck: 2
Release -> keyUp(VK_NUMPAD0)
Normal 0
Foreground, interval: 100 pressBlck: 0
Normal 0
As you can see, all the triggers are there... yet nothing...
AylinCE wrote:
Based on your answer for Timer naming;
You can kill at the end of the code (on Closing), not within the code.
Look at this example;
if autoBlockTimer then autoBlockTimer.Destroy() autoBlockTimer=nil end
autoBlockTimer = createTimer(MainForm,false)
--autoBlockTimer.Name = name
local waitTimeNormal = 100
local waitTimeBlocking = 1000
autoBlockTimer.Interval = waitTimeNormal
local pressBlck=0
bShouldWeBlock = "0x151550F95C8"
autoBlockTimer.OnTimer = function(autoBlockTick)
if getOpenedProcessID()==getForegroundProcess() then
print("Foreground, interval: "..autoBlockTimer.Interval.." address: "..readInteger(bShouldWeBlock))
if autoBlockTimer.Interval==waitTimeBlocking then
print("Release -> keyUp(VK_NUMPAD0)")
-- We stop blocking
autoBlockTimer.Interval=waitTimeNormal
keyUp(VK_NUMPAD0) -- https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
-- Switch mode (reset)
-- we go back to normal wait time (detection)
writeInteger(bShouldWeBlock,0)
pressBlck=0
end
if autoBlockTimer.Interval==waitTimeNormal then
print("Normal "..readInteger(bShouldWeBlock))
if readInteger(bShouldWeBlock)==1 then
-- We start blocking
keyDown(VK_NUMPAD0)
pressBlck=tonumber(pressBlck) + 1
print(" pressBlck: "..pressBlck)
if pressBlck==2 then
print("Block -> keyDown(VK_NUMPAD0)")
autoBlockTimer.Interval=waitTimeBlocking
end
-- Switch mode
-- we go wait longer for the block to complete
end
end
end
end
autoBlockTimer.Enabled=true
Looks, nice, thanks!
Yes, it works fine in Notepad.
What I am trying to say is that it does not work in a game.
Do you have Kingdom Come Deliverance?
See how it works there
Autohotkey works - it sends keys correctly, but I have not way to detect an attack.
CE does not send keys correctly, but I know exactly when an attack is coming.
Go figure.
This post started 2 years ago but I noticed there are recent additions. Here's my 2 bits:
I have a working timer that regularly sends a keystroke to a game when the game is the foreground process -- this is the easy part (as long as the keystroke/controller input is recognized by CE and the game) which everybody here seems to know how to do [or has agreed cannot be done for certain specific inputs].
Now about the flag in the game: why not expose the flag itself to Lua via a memrec (as opposed to doing the check within ASM and then attempting to get Lua to send the keystroke)? Wherever you are checking for the flag in ASM:
Enable this script and create a memrec in the table with address ShouldPress+24. Then the timer would need to continuously check this flag value (memrec.Value -- remember, this is a string) and send or not send keys if the game is in the foreground -- all while keeping the Lua and ASM parts separate.
Unless one of you can point out a serious flaw with this approach, I believe this would be a more universal -- or at least more easily understandable -- solution for the OP's question. Of course, feel free to scold/chide me if I'm on the totally wrong track here. _________________
I have a working timer that regularly sends a keystroke to a game when the game is the foreground process -- this is the easy part (as long as the keystroke/controller input is recognized by CE and the game) which everybody here seems to know how to do [or has agreed cannot be done for certain specific inputs].
Well, to me, it's the hard part because the game I was working on - Kingdom Come Deliverance - never got any keypresses.
Notepad did.
I have a working timer that regularly sends a keystroke to a game when the game is the foreground process -- this is the easy part (as long as the keystroke/controller input is recognized by CE and the game) which everybody here seems to know how to do [or has agreed cannot be done for certain specific inputs].
Well, to me, it's the hard part because the game I was working on - Kingdom Come Deliverance - never got any keypresses.
Notepad did.
Have you try AHK script for your game?
If it works, try to call AHK within Lua script, it may seems extra work but it work for me in some game in this case.
I have a working timer that regularly sends a keystroke to a game when the game is the foreground process -- this is the easy part (as long as the keystroke/controller input is recognized by CE and the game) which everybody here seems to know how to do [or has agreed cannot be done for certain specific inputs].
Well, to me, it's the hard part because the game I was working on - Kingdom Come Deliverance - never got any keypresses.
Notepad did.
While browsing for a different topic, I came across a different idea from @Corroder.
Maybe calling the game keystroke directly from Windows will make a difference.
Let me know when you try it.
Here is the code:
Code:
function KeyboardEvent(bVk, bScan, dwFlags, dwExtraInfo)
return executeCodeLocalEx("user32.keybd_event", bVk, bScan, dwFlags, dwExtraInfo)
end
KEYEVENTF_KEYUP = 0x2
function keyOpt(ky,s)
sleep(100)
if s==1 then
KeyboardEvent(ky, 0, 0, 0)
print(ky.." pressed!")
elseif s==0 then
KeyboardEvent(ky, 0, KEYEVENTF_KEYUP, 0)
print(ky.." released!")
end
end
-- key down:
keyOpt(VK_NUMPAD0,1)
-- key up:
keyOpt(VK_NUMPAD0,0)
Your code:
Code:
function KeyboardEvent(bVk, bScan, dwFlags, dwExtraInfo)
return executeCodeLocalEx("user32.keybd_event", bVk, bScan, dwFlags, dwExtraInfo)
end
KEYEVENTF_KEYUP = 0x2
function keyOpt(ky,s)
sleep(100)
if s==1 then
KeyboardEvent(ky, 0, 0, 0)
print(ky.." pressed!")
elseif s==0 then
KeyboardEvent(ky, 0, KEYEVENTF_KEYUP, 0)
print(ky.." released!")
end
end
-----------------------------------------------------
if autoBlockTimer then autoBlockTimer.Destroy() autoBlockTimer=nil end
autoBlockTimer = createTimer(MainForm,false)
--autoBlockTimer.Name = name
local waitTimeNormal = 100
local waitTimeBlocking = 1000
autoBlockTimer.Interval = waitTimeNormal
local pressBlck=0
bShouldWeBlock = "0x151550F95C8"
autoBlockTimer.OnTimer = function(autoBlockTick)
if getOpenedProcessID()==getForegroundProcess() then
print("Foreground, interval: "..autoBlockTimer.Interval.." address: "..readInteger(bShouldWeBlock))
if autoBlockTimer.Interval==waitTimeBlocking then
print("Release -> keyUp(VK_NUMPAD0)")
-- We stop blocking
autoBlockTimer.Interval=waitTimeNormal
keyOpt(VK_NUMPAD0,0) -- https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
-- Switch mode (reset)
-- we go back to normal wait time (detection)
writeInteger(bShouldWeBlock,0)
pressBlck=0
end
if autoBlockTimer.Interval==waitTimeNormal then
print("Normal "..readInteger(bShouldWeBlock))
if readInteger(bShouldWeBlock)==1 then
-- We start blocking
keyOpt(VK_NUMPAD0,1)
pressBlck=tonumber(pressBlck) + 1
print(" pressBlck: "..pressBlck)
if pressBlck==2 then
print("Block -> keyDown(VK_NUMPAD0)")
autoBlockTimer.Interval=waitTimeBlocking
end
-- Switch mode
-- we go wait longer for the block to complete
end
end
end
end
autoBlockTimer.Enabled=true
All times are GMT - 6 Hours Goto page Previous1, 2
Page 2 of 2
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum