|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
juntalis Newbie cheater Reputation: 2
Joined: 13 Mar 2013 Posts: 12
|
Posted: Sat Jan 16, 2016 9:11 pm Post subject: Auto-Activating Records when Possible |
|
|
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 |
|
|
henrysimon How do I cheat? Reputation: 0
Joined: 29 May 2015 Posts: 8
|
Posted: Sun Jan 24, 2016 9:52 pm Post subject: |
|
|
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).........
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 |
|
|
|
|
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
|
|