![Cheat Engine Forum Index](templates/subSilver/images/logo_phpBB.gif) |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
panraven Grandmaster Cheater
Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Wed Aug 02, 2017 9:41 pm Post subject: asyncAob aobscan* in async executing memory record |
|
|
Only for ce 6.7+
---
IMPORTANCE:
it seems timer created within an async executing memory record will not ever fire.
---
This is a custom AA command to turn aobscan* command
(aobscan/aobscanModule/aobscanRegion) run in async
execution for a memory record , will error when run in
autoAssemble since it need the memory record ID to properly
run.
Code: |
command:
asyncAob( MRID, timeout, tryinterval, <=aobscan* command=>)
|
It will try run the aobscan* command in period of tryinterval (sec) until the aob is found or timeout (sec) reach.
The MRID should be provided in a lua block befoe the command like:
Code: |
{$lua}
return string.format("define(MRID,%d)",memrec.ID)
{$asm}
...
asyncAob(MRID, 10, 2, aobscan(symbol+0c,ff 22 33 44 55 01 02 03) )
...
|
the Lua variable memrec is only appear in a Lua block of a memory record,
which is the memory record itself.
check test script below.
Just before the actual scan, the associated symbol in aobscan command will be unregistered.
When the aob found, the associated symbol will be automatic registered.
extra: allow symbol offset
eg:
aobscan( symbol +0c, 11 22 33 ...)
if the aob pattern start at 0x10000, then the symbol is registered as 0x1000c, handy to adjust hack point.
---
Attached is a *.CT disguised as *.Lua. remove .lua extension for test.
The custom command asyncAob is defined in Lua engine.
Read the testing memory record script for more detail.
bye~
Description: |
|
![](images/icon_clip.gif) Download |
Filename: |
asyncAob.CT.lua |
Filesize: |
3.73 KB |
Downloaded: |
1737 Time(s) |
_________________
- Retarded. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
mgr.inz.Player I post too much
Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Fri Aug 04, 2017 11:44 am Post subject: |
|
|
Interesting idea. Here my attempt:
The script. Can be used as Lua Extension/Plugin (so, autorun CE folder) or add it to main memory record as Lua block:
Code: | function tryFindingAOB(sc, mr, timeout, aobType, name, a, b, c)
if sc then return 'define('..name..', 00000000)' end
if not mr.Async then print'Only Async memory records. Check "execute asynchronous" option.'; error() end
if not mathrandominit then math.randomseed(os.time()); mathrandominit=true end
local command,script = '',''
local dummySymbol = 'itsjustadummysymbol'..math.random(1E9,9E9)..(mr.ID)
aobType=aobType:lower()
if aobType=='aobscan' and a then
command = 'aobscan('..name..','..a..')'
elseif aobType=='aobscanmodule' and a and b then
command = 'aobscanmodule('..name..','..a..','..b..')'
elseif aobType=='aobscanregion' and a and b and c then
command = 'aobscanregion('..name..','..a..','..b..','..c..')'
else print'wrong "tryFindingAOB" syntax'; error() end
script = command..'\r\nlabel('..dummySymbol..')\r\n'..name..':\r\n'..
dummySymbol..':\r\nregistersymbol('..dummySymbol..')'
local origDesc = mr.Description
local found = false
local counter = 1
while (mr.AsyncProcessingTime < timeout * 1000) and (not found) do
mr.Description = origDesc..' try:'..counter..' timeout:'..((timeout*1000 - mr.AsyncProcessingTime)//100)/10
found = autoAssemble(script)
counter = counter + 1
sleep(100) -- some delay between tries
end
mr.Description = origDesc
if found then
local address = getAddressSafe(dummySymbol) or 0
unregisterSymbol(dummySymbol)
return 'define('..name..','..string.format(' %08X',address)..')'
else
error()
end
end |
then your AA script can be this (timeout set to 20 seconds):
Code: | [ENABLE]
{$Lua}
return tryFindingAOB(syntaxcheck,memrec,20,'aobscan','aobGod','ff 22 33 44 55 01 02 03')
{$Asm}
...
... |
instead of
Code: | [ENABLE]
aobscan(aobGod,ff 22 33 44 55 01 02 03)
...
... |
or
Code: | [ENABLE]
{$Lua}
return tryFindingAOB(syntaxcheck,memrec,20,'aobscanmodule','aobGod','modulename.exe','ff 22 33 44 55 01 02 03')
{$Asm}
...
... |
instead of
Code: | [ENABLE]
aobscanmodule(aobGod,modulename.exe,ff 22 33 44 55 01 02 03)
...
... |
_________________
|
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
panraven Grandmaster Cheater
Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Fri Aug 04, 2017 12:59 pm Post subject: |
|
|
Thanks response~
Would you please confirm or explain that timer created within async memory record will not run?
I've try make a timer within memory record to print some text or change the MainForm Caption in OnTimer function. Without async, it run as expected, with async it just silent. I even make an error (to evaluate 1 + nil) within OnTimer function, async memory record will silent such error too!
_________________
- Retarded. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
mgr.inz.Player I post too much
Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Fri Aug 04, 2017 1:54 pm Post subject: |
|
|
google fu - TTimer created by TThread - https://www.experts-exchange.com/questions/21834535/TTimer-created-by-TThread.html
But, you can use another TThread. In CE Lua it would be something like this:
Code: | [ENABLE]
{$Lua}
if syntaxcheck then return end
function threadFunction(th)
th.freeOnTerminate(false)
th.Name = 'myThread'
while not th.Terminated do
myvar=myvar+1
synchronize(function() MainForm.Caption = 'myvar '..myvar end)
sleep(2000)
end
end
myvar=0
myThread = createNativeThreadSuspended(threadFunction)
myThread.resume()
{$Asm}
[DISABLE]
{$Lua}
if syntaxcheck then return end
if myThread then
myThread.terminate()
myThread.waitfor()
myThread.destroy()
myThread=nil
end
{$Asm} |
_________________
|
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
panraven Grandmaster Cheater
Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Fri Aug 04, 2017 4:12 pm Post subject: |
|
|
oh, I see.
I instead from your code found that this work, without create another native thread. Seem synchronize is the key?
Code: |
local function callnext(n,f,...)
local params = table.pack(...)
local t = createTimer()
t.interval = n
t.OnTimer = function(tm)
tm.Destroy()
pcall(f,table.unpack(params,1,params.n))
end
end
if syntaxcheck then return end
if not tonumber(MainForm.Caption) then MainForm.Caption = '0' end
synchronize(callnext,1,function() MainForm.Caption=tostring(1 + tonumber(MainForm.Caption)) end)
|
_________________
- Retarded. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
mgr.inz.Player I post too much
Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Aug 05, 2017 5:15 pm Post subject: |
|
|
With synchronize you will create TTimer object, and this object will work in main thread... Somewhat pointless.
If you have some heavy operations inside OnTimer function, CE GUI will freeze from time to time. The point of using Async memrec is to run everything in other thread, not main thread. And synchronize is not needed if you do not touch GUI.
Imagine there's more CPU intense operation than "myvar=myvar+1", let's say it takes 1 second, if inside onTimer it will freeze CE for one second every Interval seconds. My example doesn't have this issue.
_________________
|
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
panraven Grandmaster Cheater
Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Sat Aug 05, 2017 7:05 pm Post subject: |
|
|
I think timer function should be lightweight anyway, there should be alternative to do heavy job like aobscan inside a timer function.
And that one of alternative is this async memory record. There may be case need to spawn yet another native thread from an async memory record, but it is enough if a synchronize call done the job.
btw, would you like make me an example how can memscan's OnGuiUpdate work?
Usually when using memscan we add the waitTillDone() to block execution till scan done, then get the scan result to some variable to futher proces; it will freeze UI normally, which seems prevent OnGuiUpdate function properly. If not using waitTillDone, then how to pass the scan result to script (lua or AA) for further process? (some kind of jquery deffered /promise/ future?)
If I want to make an AA custom scan command with the memscan, but also want it work in aysnc memory record execution with OnGuiUpdatem , and also let the OnGuiUpdate work in non-async case , how it can be done? (I try insert synchronize here or there but no success)
Thank you~
_________________
- Retarded. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
Dark Byte Site Admin
Reputation: 458
Joined: 09 May 2003 Posts: 25295 Location: The netherlands
|
Posted: Sat Aug 05, 2017 7:31 pm Post subject: |
|
|
GUIUpdate is just for drawing progressbars, I recommend OnScanDone
Code: |
memscan.OnScanDone=function(ms)
--do something with the results
end
|
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
panraven Grandmaster Cheater
Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Sat Aug 05, 2017 8:35 pm Post subject: |
|
|
but the OnGuiUpdate function signature seems suggest it can draw or
print other thing, after all the ms can attach a progress bar, seems
redundant to another function to draw in another progress bar.
This part of the custom scan so far
Code: |
local ms = createMemScan(MainForm.progressbar)
local done,r = false
ms.OnScanDone = function(m)
done = true
r = m.Result
m.Destroy()
ms = nil
end
ms.OnlyOneResult = true
ms.firstScan(soExactValue, vtByteArray, rtRounded, aob, '', 1, -1, '', fsmNotAligned, '', true, true, false, false)
-- ms.WaitTillDone() -- not use
while not done do
sleep(100)
synchronize(processMessages) --- <--- is it using right?
-- without this and in NON ASYNC case, it seems change of 'done' can't be seen and cause inf looping
-- ok when in ASYNC case
end
if ms then ms.Destroy()end
if not r then return nil,aob ..' not found' end
return fmt("define(%s,%X)",sym,r)
|
using OnScanDone with a sleep loop seems has no help of making some fancy ui (eg. text base progress info) update.
_________________
- Retarded. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
Dark Byte Site Admin
Reputation: 458
Joined: 09 May 2003 Posts: 25295 Location: The netherlands
|
Posted: Sun Aug 06, 2017 2:00 am Post subject: |
|
|
Both OnScanDone and OnGuiUpdate execute in the main thread, so they both can access gui functions.
instead of synchronize(processMessages) use
Code: |
if inMainThread() then
checkSynchronize()
end
|
Also, do gui updates using synchronize, but keep the rest in the thread
If you wish to update the screen constantly, then use OnGuiUpdate as it gets called frequently. (every few milliseconds)
But it depends on what kind of method you use if what you do will be visible.
If your code is running in the main thread doing an infinite loop then the GUI won't visually update unless you force it to. (e.g: controlname.repaint() )
You can also use processMessages inside OnGuiUpdate , but that will enable the user to click on buttons as well, causing more headache than you need
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
mgr.inz.Player I post too much
Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sun Aug 06, 2017 2:20 am Post subject: |
|
|
panraven wrote: | I think timer function should be lightweight anyway, there should be alternative to do heavy job like aobscan inside a timer function. |
Run this script in main thread (execute in 'Lua engine' window)
Code: | createTimer().OnTimer = function () sleep(100) end |
sleep in not heavy operation, but CE GUI will freeze for 0.1 second every second. Just start dragging any CE form to see this effect.
_________________
|
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
Dark Byte Site Admin
Reputation: 458
Joined: 09 May 2003 Posts: 25295 Location: The netherlands
|
Posted: Sun Aug 06, 2017 2:49 am Post subject: |
|
|
You can also just have a thread that sleeps in a loop and every loop call a function (synchronized or not)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
panraven Grandmaster Cheater
Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Sun Aug 06, 2017 4:50 am Post subject: |
|
|
Thanks Dark Byte, the inMainThread/checkSynchonize in OnGuiUpdate work .
Code: |
...
ms.OnlyOneResult = true
local updcnt = 0
ms.OnGuiUpdate = function(m, naddr, nscanned, nresult)
updcnt = updcnt + 1
if updcnt % 10~= 0 then return end -- slower gui update
MainForm.Caption = fmt ("%8d/%8d , so far %s",nscanned, naddr, nresult)
if inMainThread() then checkSynchronize()end
end
ms.firstScan(soExactValue, vtByteArray, rtRounded, aob, '', 1, -1, '', fsmNotAligned, '', true, true, false, false)
ms.WaitTillDone()
r = ms.Result
...
|
It has GuiUpdate with or without async execution.
---
@mgr.inz.Player
sleep (100) is 'heavy' in term of time the timer wait?
I guess normally mixing sleep with timer is not appropriate .
Thank you help me understand the thread thing.
_________________
- Retarded. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
mgr.inz.Player I post too much
Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Aug 12, 2017 10:04 am Post subject: |
|
|
Quote: | I guess normally mixing sleep with timer is not appropriate |
It is just an example to show you that you do not need 50%-100% CPU intense Lua command/function to see CE GUI freeze effect.
Even simple readInteger('$process') in OnTimer function, to check process existence, it adds CE GUI micro-freezing (can be visible when you make D3D animations with Lua in main CE thread)
Other example with bigger freeze time: getAutoAttachList().add('prey.exe')
Autoattaching is using TTimer object, on Windows 10 it is already problematic, there are 130 or more processes. Every 2 seconds CE GUI will freeze for 0.1-0.5 second.
If you want to create trainer with customized/animated GUI... animations won't be smooth.
I solved both problems (process existence and autoattach) with one native thread and global var isAttachedToProcess (other functions are checking this var).
Code: | function OpenProcess_CheckExistence(thread)
thread.name = '"OpenProcess_CheckExistence"'
while true do
if readInteger(processName)==nil then
isAttachedToProcess=false
if openProcess(processName) then
AddressList.disableAllWithoutExecute()
isAttachedToProcess=true
-- call to function, cut for better readability
thread.synchronize( --call to function, cut for better readability )
end
end
sleep(5000)
end
end |
PS: Well, current and future OSes will have more and more processes. I think I will report another suggestion on GitHub (autoattach in separate thread instead of TTimer).
PSS: I'm stopping this off-topic discussion. If you want to talk more about it, open new forum thread and invite me with a link on PM.
_________________
|
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|
|