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 


Access memrec inside registered autoAssemblerCommand

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
Dirael
How do I cheat?
Reputation: 0

Joined: 16 Oct 2022
Posts: 4
Location: Planet Earth

PostPosted: Fri Apr 26, 2024 9:58 am    Post subject: Access memrec inside registered autoAssemblerCommand Reply with quote

Trying to access memrec inside a function registered with:
Code:
registerAutoAssemblerCommand('restoreBytes', function(p, s)
   print(memrec.Id)
end)


I would like to get an id of memrec in the script that called the registered function. Memrec is not available when I try to access it inside the function. Is there any workaround for that?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 459

Joined: 09 May 2003
Posts: 25317
Location: The netherlands

PostPosted: Fri Apr 26, 2024 1:10 pm    Post subject: Reply with quote

commands execute after lua blocks have been parsed so you can likely use that.

e.g a luablock that sets a define of the current memrec.ID and then pass that later as parameter to the command

_________________
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
View user's profile Send private message MSN Messenger
ParkourPenguin
I post too much
Reputation: 141

Joined: 06 Jul 2014
Posts: 4333

PostPosted: Fri Apr 26, 2024 1:29 pm    Post subject: Reply with quote

If you're doing that to save / restore the original injection point, you could use the address of the injection point to index into a table.
Something like this:
https://forum.cheatengine.org/viewtopic.php?p=5773240#5773240

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Dirael
How do I cheat?
Reputation: 0

Joined: 16 Oct 2022
Posts: 4
Location: Planet Earth

PostPosted: Fri Apr 26, 2024 1:57 pm    Post subject: Reply with quote

ParkourPenguin wrote:
If you're doing that to save / restore the original injection point, you could use the address of the injection point to index into a table.
Something like this:


As a matter of fact, I'm using your script and just want to add a new feature to it. Thanks btw Smile
The idea is to use "restore(*)" to restore all backed up symbols in the current assembly script, by accessing memrec.Script and parsing all symbols. That works using getAddressList().getSelectedRecord() but I can't disable several scripts at once this way.


Dark Byte wrote:
commands execute after lua blocks have been parsed so you can likely use that.

e.g a luablock that sets a define of the current memrec.ID and then pass that later as parameter to the command

Could you show an example, please?
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 55

Joined: 01 Oct 2008
Posts: 943

PostPosted: Fri Apr 26, 2024 6:47 pm    Post subject: Reply with quote

Code:

{$lua}
return 'define(MRID,'..memrec.ID..')'
{$asm}
[ENABLE]
 ....

Or,
This will auto add 'define(MRID,<scrip_memrec_id>)' in 1st line of ALL memory record script if not already.
Code:

function onMemRecPreExecute(mr, newstate)
  local def = 'define(MRID,'
  if mr.type == vtAutoAssembler then
    local code = mr.Script
    if code:sub(1,#def)~= def then
      mr.Script = table.concat({
        string.format(def..'%d)',mr.ID),
        mr.Script,
      },'\n')
    end
  end
end

There is only one onMemRecPreExecute definition, check if there is other extension using it and how to combine them.

Then define your command to parse the ID, and use MRID in the command.
Code:

registerAutoAssemblerCommand('restoreBytes', function(p, s)
  local ID, rhs = p:match'^%s*(%d+)(.-)$'
  ...
end)

-- in {$asm} block after MRID is defined
restoreBytes(MRID,...)


_________________
- Retarded.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 141

Joined: 06 Jul 2014
Posts: 4333

PostPosted: Fri Apr 26, 2024 7:11 pm    Post subject: Reply with quote

DB's method looks like this:
Code:
{$lua}
return ('define(MemrecID,%d)'):format(memrec.ID)
{$asm}

[ENABLE]
...
backup(foo+2C,8,MemrecID)
...

[DISABLE]
restore(*,MemrecID)
...


You could automate this using registerAutoAssemblerPrologue, but that code would need to be distributed with the table as well. But since the code defining the custom AA commands also needs to be distributed, I guess that isn't really a problem.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Dirael
How do I cheat?
Reputation: 0

Joined: 16 Oct 2022
Posts: 4
Location: Planet Earth

PostPosted: Sat Apr 27, 2024 1:51 am    Post subject: Reply with quote

Thanks for your help, everyone! That certainly is a workaround I was looking for. But, at this point, it'd be better to parse several symbols at once:
Code:
restoreBytes(symbol1 symbol2 symbol3)


ParkourPenguin wrote:

You could automate this using registerAutoAssemblerPrologue, but that code would need to be distributed with the table as well. But since the code defining the custom AA commands also needs to be distributed, I guess that isn't really a problem.


No, this is for personal use only, so that's not a problem. I couldn't access 'memrec' in 'registerAutoAssemblerPrologue'; it could've made things a bit cleaner.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 141

Joined: 06 Jul 2014
Posts: 4333

PostPosted: Sat Apr 27, 2024 2:37 am    Post subject: Reply with quote

I meant using registerAutoAssemblerPrologue to literally write down what I wrote down as DB's method. Something like this (not fully tested):
Code:
local backuptable = {
  backup = function(self, address, size, id)
    local addr = getAddressSafe(address)
    if not addr then
      return nil, 'Invalid address ' .. address
    end

    size = tonumber(size)
    if not size then
      return nil, 'Invalid size'
    end

    local bytes = readBytes(addr, size, true)
    if not bytes then
      return nil, 'Could not read bytes at address ' .. address
    end

    local t = self:getIDGroup(id)
    t[addr] = bytes

    return ''
  end,

  restore = function(self, address, id)
    local t = self:getIDGroup(id)

    local addr = getAddressSafe(address)
    if not addr then
      return nil, 'Invalid address ' .. address
    end

    local bytes = t[addr]
    if not bytes then
      return nil,'No backup exists for address ' .. address
    end
    t[addr] = nil

    writeBytes(addr, bytes)

    return ''
  end,

  restoreAll = function(self, id)
    local t = self:getIDGroup(id)

    if t == self.default then
      return nil, 'No ID to restore from'
    end

    for addr,bytes in pairs(t) do
      t[addr] = nil
      writeBytes(addr, bytes)
    end

    return ''
  end,

  getIDGroup = function(self, id)
    id = tonumber(id) or 'default'

    local t = self[id]
    if not t then
      t = {}
      self[id] = t
    end

    return t
  end,

  default = {} -- anonymous AA scripts w/o an ID
}

registerAutoAssemblerCommand('backup', function(params, syntaxcheck)
  -- address_string,bytes_to_read,memrec_ID
  -- allow for ',' in address_string
  local addr, size, memrecID = params:match'(.+),([^,]+),(%d*)$'
  if not addr or not size or not memrecID then
    return nil, 'Bad arguments to backup()'
  end

  if syntaxcheck then return '' end

  return backuptable:backup(addr, size, memrecID)
end)

registerAutoAssemblerCommand('restore', function(params, syntaxcheck)
  local memrecID = params:match'^%*,(%d*)$'
  if memrecID then
    -- restore all
    if syntaxcheck then
      return ''
    end
    return backuptable:restoreAll(memrecID)
  else
    -- only restore one
    local addr, memrecID = params:match'(.+),(%d*)$'

    if not addr or not memrecID then
      return nil,'Bad arguments to restore()'
    end

    if syntaxcheck then
      return ''
    end

    return backuptable:restore(addr, memrecID)
  end
end)

registerAutoAssemblerPrologue(function(script, syntaxcheck)
  -- script is `Strings` object
  local didChange = false

  for i = 0, script.Count - 1 do
    local line = script[i]
    local uppercase = line:upper()

    if uppercase:find'^%s*BACKUP%(' or uppercase:find'^%s*RESTORE%(' then
      didChange = true
      script[i] = line:gsub('%)%s*$', ',BACKUP_RESTORE_MEMRECID)')
    end
  end

  if not didChange then return end

  script.insert(0,'')
  script.insert(1,'{$lua}')
  script.insert(2,[[return ('define(BACKUP_RESTORE_MEMRECID,%s)'):format(memrec and memrec.ID or '')]])
  script.insert(3,'{$asm}')
  script.insert(4,'')
end)
Note that this changes the size parameter to decimal by default. This is how readmem works too
_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Dirael
How do I cheat?
Reputation: 0

Joined: 16 Oct 2022
Posts: 4
Location: Planet Earth

PostPosted: Sat Apr 27, 2024 3:27 am    Post subject: Reply with quote

Yes, that works. Thank you very much!
I doubt it only took you 5 minutes to come up with that script, so I really appreciate you taking the time to do it
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 Lua Scripting 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 can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites