  | 
				
				Cheat Engine The Official Site of Cheat Engine   
				
 
				 | 
			 
		 
		 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		panraven Grandmaster Cheater
  Reputation: 62
  Joined: 01 Oct 2008 Posts: 958
 
  | 
		
			
				 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: | 
		
			
		 | 
		  Download | 
	 
	
		|  Filename: | 
		 asyncAob.CT.lua | 
	 
	
		|  Filesize: | 
		 3.73 KB | 
	 
	
		|  Downloaded: | 
		 2587 Time(s) | 
	 
	 
	 
 _________________
 - Retarded.  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		mgr.inz.Player I post too much
  Reputation: 222
  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 | 
		 | 
	 
	
		  | 
	 
	
		panraven Grandmaster Cheater
  Reputation: 62
  Joined: 01 Oct 2008 Posts: 958
 
  | 
		
			
				 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 | 
		 | 
	 
	
		  | 
	 
	
		mgr.inz.Player I post too much
  Reputation: 222
  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 | 
		 | 
	 
	
		  | 
	 
	
		panraven Grandmaster Cheater
  Reputation: 62
  Joined: 01 Oct 2008 Posts: 958
 
  | 
		
			
				 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 | 
		 | 
	 
	
		  | 
	 
	
		mgr.inz.Player I post too much
  Reputation: 222
  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 | 
		 | 
	 
	
		  | 
	 
	
		panraven Grandmaster Cheater
  Reputation: 62
  Joined: 01 Oct 2008 Posts: 958
 
  | 
		
			
				 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 | 
		 | 
	 
	
		  | 
	 
	
		Dark Byte Site Admin
  Reputation: 470
  Joined: 09 May 2003 Posts: 25807 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 | 
		 | 
	 
	
		  | 
	 
	
		panraven Grandmaster Cheater
  Reputation: 62
  Joined: 01 Oct 2008 Posts: 958
 
  | 
		
			
				 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 | 
		 | 
	 
	
		  | 
	 
	
		Dark Byte Site Admin
  Reputation: 470
  Joined: 09 May 2003 Posts: 25807 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 | 
		 | 
	 
	
		  | 
	 
	
		mgr.inz.Player I post too much
  Reputation: 222
  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 | 
		 | 
	 
	
		  | 
	 
	
		Dark Byte Site Admin
  Reputation: 470
  Joined: 09 May 2003 Posts: 25807 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 | 
		 | 
	 
	
		  | 
	 
	
		panraven Grandmaster Cheater
  Reputation: 62
  Joined: 01 Oct 2008 Posts: 958
 
  | 
		
			
				 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 | 
		 | 
	 
	
		  | 
	 
	
		mgr.inz.Player I post too much
  Reputation: 222
  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 | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  | 
   
 
		 |