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 


Edit table entry's offsets with Lua?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
Birdi
Expert Cheater
Reputation: 0

Joined: 08 Jun 2020
Posts: 122
Location: Migrating

PostPosted: Wed Jul 28, 2021 5:59 am    Post subject: Edit table entry's offsets with Lua? Reply with quote

I've got no idea how to go about my problem..

I'm detecting the version of a game and need to either alter the offsets of multiple table entries if it's one version over another, or simply make copies with the correct offset and delete them when detecting version.
If I were to delete them, can I get a memrec's offset value to test against with lua, or would I be better off just changing the description after deleting the incorrect offsets?

Both approaches work, but I have no idea how to do either:
Delete/Rename specific memrecs by name or offset
Change Offsets

So far I've got a function to iterate through the table's entries and match based on the DropDownList's text, but I don't know where I'd explore the rest of the memrec object's properties. Just need to read documentation I suppose, but it's a long read haha


They're all pointers [[base]+18]+?] where ? may change between versions, if that helps.
Back to top
View user's profile Send private message Visit poster's website
LeFiXER
Grandmaster Cheater Supreme
Reputation: 20

Joined: 02 Sep 2011
Posts: 1055
Location: 0x90

PostPosted: Wed Jul 28, 2021 7:23 am    Post subject: Reply with quote

Memory record class:
Code:

MemoryRecord Class:
The memoryrecord objects are the entries you see in the addresslist

properties
  ID: Integer - Unique ID
  Index: Integer - The index ID for this record. 0 is top. (ReadOnly)
  Description: string- The description of the memory record
  Address: string - Get/set the interpretable address string. Useful for simple address settings.
  AddressString: string - Get the address string shown in CE (ReadOnly)
  OffsetCount: integer - The number of offsets. Set to 0 for a normal address
  Offset[] : integer - Array to access each offset
  OffsetText[] : string - Array to access each offset using the interpretable text style

  CurrentAddress: integer - The address the memoryrecord points to
  VarType: ValueType (string) - The variable type of this record. See vtByte to vtCustom
  Type: ValueType (number) - The variable type of this record. See vtByte to vtCustom
    If the type is vtString then the following properties are available:
     String.Size: Number of characters in the string
     String.Unicode: boolean
     String.Codepage: boolean

    If the type is vtBinary then the following properties are available
      Binary.Startbit: First bit to start reading from
      Binary.Size : Number of bits

    If the type is vtByteArray then the following properties are available
      Aob.Size : Number of bytes

  CustomTypeName: String - If the type is vtCustom this will contain the name of the CustomType
  Script: String - If the type is vtAutoAssembler this will contain the auto assembler script
  Value: string - The value in stringform.
  NumericalValue: number - The value in numerical form.  nil if it can not be parsed to a number
  Selected: boolean - Set to true if selected (ReadOnly)
  Active: boolean - Set to true to activate/freeze, false to deactivate/unfreeze
  Color: integer
  ShowAsHex: boolean - Self explanatory
  ShowAsSigned: boolean - Self explanatory
  AllowIncrease: boolean - Allow value increasing, unfreeze will reset it to false
  AllowDecrease: boolean - Allow value decreasing, unfreeze will reset it to false
  Collapsed: boolean - Set to true to collapse this record or false to expand it. Use expand/collapse methods for recursive operations.
  IsGroupHeader: boolean - Set to true if the record was created as a Group Header with no address or value info.
  IsAddressGroupHeader: boolean - Set to true if the record was created as a Group Header with address.
  IsReadable: boolean - Set to false if record contains an unreadable address. NOTE: This property will not be set until the value property is accessed at least once. (ReadOnly)

  Options: String set - a string enclosed by square brackets filled with the options seperated by a comma. Valid options are: moHideChildren, moActivateChildrenAsWell, moDeactivateChildrenAsWell, moRecursiveSetValue, moAllowManualCollapseAndExpand, moManualExpandCollapse, moAlwaysHideChildren
 
  DropDownLinked: boolean - if dropdown list refers to list of another memory record eg. (memrec name)
  DropDownLinkedMemrec: string - Description of linked memrec or emptystring if not linked
  DropDownList : StringList - list of "value:description" lines, lists are still separate objects when linked, read-write
  DropDownReadOnly: boolean - true if 'Disallow manual user input' is set
  DropDownDescriptionOnly: boolean - self explanatory
  DisplayAsDropDownListItem: boolean - self explanatory
  DropDownCount: integer - equivalent to .DropDownList.Count
  DropDownValue[index] : Array to access values in DropDownList (ReadOnly)
  DropDownDescription[index] : Array to access Descriptions in DropDownList (ReadOnly)


  Count: Number of children
  Child[index] : Array to access the child records
  [index] = Child[index]
  Parent: MemoryRecord - The parent of the memory record

  HotkeyCount: integer - Number of hotkeys attached to this memory record
  Hotkey[] : Array to index the hotkeys

  Async: Boolean - Set to true if activating this entry will be asynchronious. (only for AA/Lua scripts)
  AsyncProcessing: Boolean - True when async is true and it's being processed
  AsyncProcessingTime: qword - The time that it has been processing in milliseconds

  HasMouseOver: boolean - True if the mouse is currently over it

  OnActivate: function(memoryrecord,before,currentstate):boolean - The function to call when the memoryrecord will change (or changed) Active to true. If before is true, not returning true will cause the activation to stop.
  OnDeactivate: function(memoryrecord,before,currentstate):boolean - The function to call when the memoryrecord will change (or changed) Active to false. If before is true, not returning true will cause the deactivation to stop.
  OnDestroy: function() - Called when the memoryrecord is destroyed.
  OnGetDisplayValue: function(memoryrecord,valuestring):boolean,string - This function gets called when rendering the value of a memory record. Return true and a new string to override the value shown
  DontSave: boolean - Don't save this memoryrecord and it's children

methods
  getDescription()
  setDescription()
  getAddress() : Returns the interpretable addressstring of this record. If it is a pointer, it returns a second result as a table filled with the offsets
  setAddress(string) : Sets the interpretable address string, and if offsets are provided make it a pointer

  getOffsetCount(): Returns the number of offsets for this memoryrecord
  setOffsetCount(integer): Lets you set the number of offsets

  getOffset(index) : Gets the offset at the given index
  setOffset(index, value) : Sets the offset at the given index

  getCurrentAddress(): Returns the current address as an integer (the final result of the interpretable address and pointer offsets)

  appendToEntry(memrec): Appends the current memory record to the given memory record

  getHotkey(index): Returns the hotkey from the hotkey array
  getHotkeyByID(integer): Returns the hotkey with the given id

  reinterpret()
  createHotkey({keys}, action, value OPTIONAL, description OPTIONAL): Returns a hotkey object

  disableWithoutExecute(): Sets the entry to disabled without executing the disable section
  beginEdit() : Call when you wish to take a long time to edit a record. (e.g external editor) It prevents the record from getting deleted
  endEdit() : to mark the end of your long edit sequence

global events
  function onMemRecPreExecute(memoryrecord, newstate BOOLEAN):
    If above function is defined it will be called before action* has been performed.
    Active property is about to change to newState.
 
  function onMemRecPostExecute(memoryrecord, newState BOOLEAN, succeeded BOOLEAN):
    If above function is defined it will be called after action*.
    Active property was supposed to change to newState.
    If 'succeeded' is true it means that Active state has changed and is newState.
   
    newState and succeeded are read only.
 
    *action can be: running auto assembler script (ENABLE or DISABLE section), freezing and unfreezing




But here is some code to loop through the address list and update the very last offset of the memory record based on the description given. It skips over entries that do not have offsets. Hopefully this will put you in the right direction Smile

Code:

function updateOffsets(memRecord, newOffset)
local al = getAddressList()
local c = al.Count - 1
  for i=0, c do
    local offsetToSet = newOffset
    local mr = al.getMemoryRecordByDescription(memRecord)
    if mr == nil then break end
    if mr ~= nil and mr.OffsetCount > 1 then
        local oc = mr.OffsetCount
        local endOffset = oc
        mr.Offset[oc-endOffset] = newOffset
    end
  end
end

updateOffsets('test', 0xE)


Note: make sure you assign the new offsets in hex notation
Back to top
View user's profile Send private message
Birdi
Expert Cheater
Reputation: 0

Joined: 08 Jun 2020
Posts: 122
Location: Migrating

PostPosted: Wed Jul 28, 2021 7:27 am    Post subject: Reply with quote

Crazy how useful Lua can be.. I figured it had access to every part of the memrec but never really looked through much to find all the proper syntax. Many thanks!
Back to top
View user's profile Send private message Visit poster's website
LeFiXER
Grandmaster Cheater Supreme
Reputation: 20

Joined: 02 Sep 2011
Posts: 1055
Location: 0x90

PostPosted: Wed Jul 28, 2021 7:57 am    Post subject: Reply with quote

You're welcome. Feel free to hit the reputation button if I helped you Smile.
Back to top
View user's profile Send private message
Birdi
Expert Cheater
Reputation: 0

Joined: 08 Jun 2020
Posts: 122
Location: Migrating

PostPosted: Wed Jul 28, 2021 8:27 pm    Post subject: Reply with quote

I just get an SQL error when I try, otherwise I would sorry :<

Also, here's my final script for anyone who might want it:

Code:

local function updateOffsets(memRecord, adjustment, memAddress, offsetNumber, alteration)
  local al = getAddressList()
  for i=0, al.Count-1 do
    if al[i].Description == memRecord and al[i].Address:match(memAddress) and al[i].OffsetCount > 0 then
      if alteration == 'add' then
        local mO = al[i].Offset[offsetNumber]
        --print("\nCurrent Description: "..al[i].Description.."\nCurrent Offset: "..mO.."\nCurrent Address: "..al[i].Address)
        al[i].Offset[offsetNumber] = mO + adjustment
      elseif alteration == 'sub' then
        local mO = al[i].Offset[offsetNumber]
        --print("\nCurrent Description: "..al[i].Description.."\nCurrent Offset: "..mO.."\nCurrent Address: "..al[i].Address)
        al[i].Offset[offsetNumber] = mO - adjustment
      else --Set to the Adjustment instead of arithmetic
        local mO = al[i].Offset[offsetNumber]
        --print("\nCurrent Description: "..al[i].Description.."\nCurrent Offset: "..mO.."\nCurrent Address: "..al[i].Address)
        al[i].Offset[offsetNumber] = adjustment
      end
      local mO = al[i].Offset[offsetNumber]
      --print("New Offset: "..mO)
    end
  end
end

--            (Description, Offset Adjustment, Memory Address, Offset#, Add/Sub/Set)
   updateOffsets('Health', 0x60, 'p_vms', 0x0, 'set')


You can probably expand this to include offsets around the offsetNumber, or up until/after it by n... and omit the memAddress in the if-check if you're not using symbols since it'll be dynamic.
Back to top
View user's profile Send private message Visit poster's website
LeFiXER
Grandmaster Cheater Supreme
Reputation: 20

Joined: 02 Sep 2011
Posts: 1055
Location: 0x90

PostPosted: Thu Jul 29, 2021 4:59 am    Post subject: Reply with quote

That's a shame. Not to worry, thank you anyway and thank you for sharing your complete script.
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