Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Auto-Activating Records when Possible

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials -> LUA Tutorials
View previous topic :: View next topic  
Author Message
juntalis
Newbie cheater
Reputation: 2

Joined: 13 Mar 2013
Posts: 12

PostPosted: Sat Jan 16, 2016 9:11 pm    Post subject: Auto-Activating Records when Possible Reply with quote

I wrote this for my own convenience when dealing with a recent table that had shit-tons of records to activate. (most of which couldn't be activated until the game reached a certain state) Figured I can't be the only lazy person who hates doing things twice.

To use it, add '[AA]' anywhere in a record's description.

How it works
When Cheat Engine attaches to a process, the script finds all records with '[AA]' in their descriptions and attempts to activate them. If any of the records can't be activated, it add them to a queue and starts a 0.5 second timer that continues trying to activate them until it's managed to activate all of the records. Once all records have been activated, it disables and cleans up the timer and queue. It forgets about a record after activating it, so no need to worry about reactivation, etc.

Notes

  • I used a timer instead of onOpenProcess so that I wouldn't override or be overridden by any existing handlers for that event.
  • Cheat Engine uses the really annoying system beep sound to indicate that a record failed to activate. (apparently does not apply to auto assembler records) I think I managed to catch all records that can't be activated in my canActivate function, but if you start hearing a repeating beep every 0.5 seconds, you know why.
  • While the script will activate header records, it doesn't currently factor in the "Activating this entry activates it's children" option. That said, any child records that won't be ready to activate at the same time as their parent should be marked with an '[AA]' as well. (Empty header records with no address or script are activated pretty much as soon as the process attaches)


Code:

local AUTO_ACTIVATE_TAG = '[AA]'
local AUTO_ACTIVATE_DELAY = 500

local _L = setmetatable({}, {
   __private = {}
})

local function has(T, key)
   if type(T) ~= 'table' then return false end
   for check,unused in pairs(T) do
      if check == key then
         return true
      end
   end
   return false
end

local function contains(S, search)
   return string.find(S, search, 0, true) ~= nil
end

local function __get(key, default)
   local mt = getmetatable(_L)
   local value = rawget(mt.__private, key)
   if not has(mt.__private, key) or type(value) == 'nil' then
      value = default
      rawset(mt.__private, key, value)
   end
   return value
end

local function __set(key, value)
   local mt = getmetatable(_L)
   rawset(mt.__private, key, value)
end

local function __del(key)
   __set(key, nil)
end

local function setTimeout(callback, ms)
   local t_timeout = createTimer(nil, false)
   t_timeout:setOnTimer(function(sender)
      object_destroy(sender)
      callback()
   end)
   t_timeout:setInterval(ms or 1000)
   t_timeout:setEnabled(true)
end

local function isReady()
   local bReady = false
   local hPID = getOpenedProcessID()
   if type(hPID) == 'number' and hPID > 0 then
      local isStr = type(_G.process) == 'string'
      bReady = isStr and string.len(_G.process) > 0
   end
   return bReady
end

local function destroyWatcher()
   local t_autocheck = __get('autocheck')
   t_autocheck:setEnabled(false)
   object_destroy(t_autocheck)
   __del('autocheck')
end

local function onWatcher(sender)
   if isReady() then
      destroyWatcher()
      local addrs = getAddressList()
      local handlers = __get('startup', {})
      for i,callback in ipairs(handlers) do
         callback(addrs)
      end
      __del('startup')
   end
end

local function startup(callback)
   local onStartup = __get('startup', {})
   table.insert(onStartup, callback)
end

local function createWatcher(callback)
   if isReady() then
      callback(getAddressList())
      return
   end
   local t_autocheck = createTimer(nil, false)
   t_autocheck:setOnTimer(onWatcher)
   t_autocheck:setInterval(500)
   t_autocheck:setEnabled(true)
   __set('autocheck', t_autocheck)
   startup(callback)
end

-- Header records have an address of 0, a blank value, and a vtByte type
local function isHeader(record)
   return record.Type == vtByte and record.Value == '' and record.CurrentAddress == 0
end

local function canActivate(record)
   local rType, rAddr, rVal = record.Type, record.CurrentAddress, record.Value
   
   -- There's currently no way to check whether an autoassembler record
   -- can activate, so we'll just say yes and hope for the best. Header records
   -- can activate at any point.
   if record.Type == vtAutoAssembler or isHeader(record) then
      return true
   -- For all other records, we expect a valid address and value.
   elseif record.CurrentAddress ~= 0 and record.Value ~= '??' then
      return true
   else
      return false
   end
end

local function autoActivateProc(sender)
   local aaCount = 0
   local aaQueue = {}
   local addrs = getAddressList()
   
   -- Process our queued records
   local aaOldQueue = __get('aaQueue')
   for unused,id in ipairs(aaOldQueue) do
      local record = addrs:getMemoryRecordByID(id)
      -- Check whether a record can be activated to avoid that annoying
      -- ass fucking beeping.
      if canActivate(record) then
         record.Active = true
      end
      
      -- If a record failed to activate, re-add it to our queue and keep
      -- it moving.
      if not record.Active then
         aaCount = aaCount + 1
         table.insert(aaQueue, record.ID)
      end
   end
   
   -- If we still have unactivated records, update our queue and wait for
   -- the next timer event. Otherwise destroy the queue table, disable the
   -- timer, and destroy the object reference.
   if aaCount > 0 then
      __set('aaQueue', aaQueue)
   else
      __del('aaQueue')
      sender:setEnabled(false)
      object_destroy(sender)
   end
end

-- Does the record's description contain our keyword?
local function shouldActivate(record)
   local desc = string.upper(record:getDescription())
   return contains(desc, AUTO_ACTIVATE_TAG)
end

local function startAutoActivate(addrs)
   local count = addrs.Count - 1
   local aaCount = 0
   local aaQueue = {}
   for idx = 0,count do
      local record = addrs:getMemoryRecord(idx)
      if shouldActivate(record) then
         -- Check whether a record can be activated to avoid that annoying
         -- ass fucking beeping.
         if canActivate(record) then
            record.Active = true
         end
         -- If the record could not be activated, add it to our queue and
         -- increment the count of queued records.
         if not record.Active then
            aaCount = aaCount + 1
            table.insert(aaQueue, record.ID)
         end
      end
   end
   
   if aaCount > 0 then
      __set('aaQueue', aaQueue)
      local t_autocheck = createTimer(nil, false)
      t_autocheck:setOnTimer(autoActivateProc)
      t_autocheck:setInterval(AUTO_ACTIVATE_DELAY)
      t_autocheck:setEnabled(true)
   end
end

createWatcher(startAutoActivate)

-- strings_add(getAutoAttachList(), 'Game.exe')

[/list][/code]
Back to top
View user's profile Send private message
henrysimon
How do I cheat?
Reputation: 0

Joined: 29 May 2015
Posts: 8

PostPosted: Sun Jan 24, 2016 9:52 pm    Post subject: Reply with quote

Hi thanks for the info, really come in handy for recurring game, that you like to play alot, but quite lazy to turn on the trainer everytime (like unlimited stamina for dragon dogma)

anyway i also want to add bat files command for automatic load the cheat engine, then load the game itself, and kill the cheat engine once you quit the game (so you can be more lazy).........Very Happy

Code:

@echo off
d:
cd games\Cheat Engine 6.5\
REM ---------start cheat program
start "Cheat" "Tutorial_AutoAttach_32bit.CT"

REM ---------wait for 2 seconds
ping 127.0.0.1 -n 2 > null

REM ---------start application
start /wait "Tutorial" "Tutorial-i386.exe"

REM ---------kill the cheat program when exiting the application (may require administrator right)
taskkill /F /im cheatengine-x86_64.exe
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials -> LUA Tutorials All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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 cannot download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites