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 


Logging "over pointer" values

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

Joined: 30 May 2021
Posts: 6

PostPosted: Sun May 30, 2021 3:06 pm    Post subject: Logging "over pointer" values Reply with quote

I am building an item list with all specific data corresponding to each item.
The issue is that there are over one thousand different items and over a dozen values for each one of them.

I am able to get the values I need using an over pointer : in game I put the mouse over the entry and CE is able to give me all the data I need.

Is it possible to log all desired data using a "trigger" like thing on a pointer address something like "if this particular address changes then log all these values from these addresses" ?
Back to top
View user's profile Send private message
I_was_a_legend
How do I cheat?
Reputation: 0

Joined: 30 May 2021
Posts: 6

PostPosted: Mon May 31, 2021 1:30 pm    Post subject: Reply with quote

Ok so I'm trying to get there, first of all, I'm trying to write any string in a file. So I created a script attached to the Brave browser and the code looks like this :

Code:
alloc(newmem,2048,"brave.exe"+149750)
label(returnhere)
label(originalcode)
label(exit)

newmem:
local f = io.open("C:\Users\SpongeBOB\Desktop\test.txt","w")
f:write("test")
f:close()

originalcode:
sub rsp,28
call brave.exe+149764

exit:
jmp returnhere

"brave.exe"+149750:
jmp newmem
nop 4
returnhere:


I tried different things like moving io.open instruction to the top (before newmem) or removing the path and stay in local with "test.txt" and I always get same error "This instruction cannot be compiled"

What am I missing here ?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4300

PostPosted: Mon May 31, 2021 2:57 pm    Post subject: Reply with quote

Code:
local f = io.open("C:\Users\SpongeBOB\Desktop\test.txt","w")
f:write("test")
f:close()
This is Lua code. Everything else in that script is AA code. You can't fit a square peg into a round hole like that.
If you want to enable/disable Lua code like an AA script, make a new AA script and use this template:
Code:
{$lua}
if sysntaxcheck then return end
[ENABLE]
-- code to enable
[DISABLE]
-- code to disable

If you know enough about computer science and reverse engineering to identify the data structure those items are in (e.g. array, linked list, hash map, tree, etc.), use Lua to iterate over the items and record them.

Otherwise, use a timer to check the item under the mouse every half second and record it if you haven't already done so.
Code:
if t then t.destroy(); t = nil end

-- for testing and changing code, remove "items or "
items = items or {
  contains = function(addr)
    return items[addr] ~= nil
  end,

  record = function(addr)
    items.changed = true
    items[addr] = {
      name = readString(addr+24, 100),
      id = readInteger(addr+8),
      -- etc...
    }

    -- sync at most every 30 seconds
    if os.difftime(os.time(), items.lastSync) > 30 then
      items.flush()
    end
  end,

  flush = function()
    if not items.changed then return end
    -- serialize data to disk
    -- e.g. https://github.com/rxi/json.lua/blob/master/json.lua
    -- for more advanced stuff, CE exposes an API for SQL queries
    items.changed = false
    items.lastSync = os.time()
  end,

  lastSync = os.time(),
  changed = false
}
t = createTimer()
t.Interval = 500
t.OnTimer = function()
  local a = getAddressSafe('[[game.exe+12AC]+34]+0') -- or a registered symbol if you used an injection copy
  if a and not items.contains(a) then
    items.record(a)
  end
end

_________________
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
I_was_a_legend
How do I cheat?
Reputation: 0

Joined: 30 May 2021
Posts: 6

PostPosted: Tue Jun 01, 2021 6:38 am    Post subject: Reply with quote

Thank you for your answer !

Noob question : how do you debug your code ? I wonder where "print" is printing inside Cheat engine, does a popup come up ? Well I'm not on my machine so I cannot test that out yet... Smile

For the implementation rather than setting a timer I was thinking about an infinite loop which would break once I unable the script. What do you think about that method ? I'm a little afraid about a memory burst somewhere I'm not used to this low level programmation. Usually the framework does all the job for me ahahaha (java, js, php...)
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Tue Jun 01, 2021 7:00 am    Post subject: Reply with quote

if you execute it in lua engine you can set a breakpoint and when executed it will break there. You can then inspect local variables by hovering the mouse over them

so first test your code inside lua engine with test data, before pasting it into a memory record

_________________
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: 140

Joined: 06 Jul 2014
Posts: 4300

PostPosted: Tue Jun 01, 2021 11:11 am    Post subject: Reply with quote

Timers pretty much are infinite loops. They run periodically, forever, until they're disabled or destroyed.
You can't have a simple infinite loop like this:
Code:
while true do
 --...
end
Lua is run on the main thread so it can access GUI elements. If you block the main thread like this, CE freezes and you won't be able to disable the script with the checkbox.
Even if you execute the script asynchronously in a different thread, it's still a waste of CPU cycles to execute that in a busy loop.

I'd write it like this to enable/disable it:
Code:
{$lua}
if syntaxcheck then return end

items = items or {
  -- ...
}

-- for testing / changing, uncomment this line:
--if itemRecordTimer then itemRecordTimer.destroy(); itemRecordTimer = nil end

if not itemRecordTimer then
  itemRecordTimer = createTimer()
  itemRecordTimer.Enabled = false
  itemRecordTimer.Interval = 500
  itemRecordTimer.OnTimer =  -- ...
end

[ENABLE]
itemRecordTimer.Enabled = true
[DISABLE]
itemRecordTimer.Enabled = false

_________________
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
I_was_a_legend
How do I cheat?
Reputation: 0

Joined: 30 May 2021
Posts: 6

PostPosted: Tue Jun 01, 2021 4:38 pm    Post subject: Reply with quote

I have a huge problem : once I am inside a loop any changes in CE will provoke a crash.

Example : I have a for loop of 5 iterations that just prints an address's value, sleeps for 5 sec then repeat.
If I do nothing, it ends well, and I have my 5 prints. If I try to get the focus on CE while the loop is running it crashes instantly (not responding. I wait some time to get it back but I got to quit and restart). It also crashes if one of the values used inside the loop changes too frequently.

Any idea on what's going on here ?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Tue Jun 01, 2021 4:56 pm    Post subject: Reply with quote

never use sleep() unless you use threads
_________________
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
I_was_a_legend
How do I cheat?
Reputation: 0

Joined: 30 May 2021
Posts: 6

PostPosted: Wed Jun 02, 2021 6:38 am    Post subject: Reply with quote

Ok one more thing I have an odd behavior here :

Code:
{$lua}
local f = io.open("C:\\Users\\Bob\\Desktop\\test.txt","a")

if firsTime ~= "yes" then
   f:write("Blablabla".."\n")
   firstTime="yes"
end



[ENABLE]
f:write("Write stuff".."\n")

[DISABLE]
firstTime = ""
f.close()


I want to enter only once in that "if" but when I activate the script it enters in it twice in a row... How can I work around this ? Rolling Eyes

Result :
Quote:
Blablabla
Blablabla
Write stuff
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Wed Jun 02, 2021 8:43 am    Post subject: Reply with quote

1: you're opening the file twice but only close it in disable


2: are you sure the file was empty when you started?
do you have another script that sets firstTime to empty or nil?

3: your lua script doesn't check if syntaxcheck is set. So when editing the script both scripts will execute each time you edit the code

_________________
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
I_was_a_legend
How do I cheat?
Reputation: 0

Joined: 30 May 2021
Posts: 6

PostPosted: Wed Jun 02, 2021 1:45 pm    Post subject: Reply with quote

Thanks to you two I finished the script I wanted ! Thank you very much Very Happy Cool

It took me some time to wrap my head around the timer mechanics for some reason... And after trying lots of different things looking everywhere on Google I realized ... I had the exact same code you @ParkourPenguin provided me right from the beginning ! LOL
At least now I know how and why it works ahaha.

Here is my code if it might be useful to someone passing by :

Code:
{$lua}
if syntaxcheck then return end
local list = getAddressList()
local f = io.open("C:\\Users\\USERNAME\\Desktop\\Biomutant_Item_Values.txt","a")

if itemRecordTimer then itemRecordTimer.destroy(); itemRecordTimer = nil end

--[[if firsTime ~= "yes" then
  f:write("ID;Damage Bonus;Damage Min;Damage Max;Armor Piercing;Fire Rate;Accuracy;Range;Crit;Mag size;Reload Speed;Elemental Damage;Addons;Health;Ki Energy;Armor;"..
  "Loot Chance;Req Level;Price;Energy Regen;Health Regen;Duration;Heat Rez;Cold Rez;Radioactivity Rez;Biohazard Rez;Hypoxia Rez".."\n")
   firstTime="yes"
end]]

local function timer_tick(timer)
  if tmp~=list.getMemoryRecordByDescription("Body").Value then
        f:write(list.getMemoryRecordByDescription("Body").Value .. ";" ..
        list.getMemoryRecordByDescription("Damage Bonus").Value .. ";" ..
        list.getMemoryRecordByDescription("Damage Min").Value .. ";" ..
        list.getMemoryRecordByDescription("Damage Max").Value .. ";" ..
        list.getMemoryRecordByDescription("Armor Piercing").Value .. ";" ..
        list.getMemoryRecordByDescription("Fire Rate").Value .. ";" ..
        list.getMemoryRecordByDescription("Accuracy").Value .. ";" ..
        list.getMemoryRecordByDescription("Range").Value .. ";" ..
        list.getMemoryRecordByDescription("Crit").Value .. ";" ..
        list.getMemoryRecordByDescription("Magazine Size").Value .. ";" ..
        list.getMemoryRecordByDescription("Reload Speed").Value .. ";" ..
        list.getMemoryRecordByDescription("Elemental Damage").Value .. ";" ..
        list.getMemoryRecordByDescription("Addons").Value .. ";" ..
        list.getMemoryRecordByDescription("Health").Value .. ";" ..
        list.getMemoryRecordByDescription("Ki Energy").Value .. ";" ..
        list.getMemoryRecordByDescription("Armor").Value .. ";" ..
        list.getMemoryRecordByDescription("Loot Chance").Value .. ";" ..
        list.getMemoryRecordByDescription("Req Level").Value .. ";" ..
        list.getMemoryRecordByDescription("Price").Value .. ";" ..
        list.getMemoryRecordByDescription("Energy Regen").Value .. ";" ..
        list.getMemoryRecordByDescription("Health Regen").Value .. ";" ..
        list.getMemoryRecordByDescription("Duration").Value .. ";" ..
        list.getMemoryRecordByDescription("Heat rez").Value .. ";" ..
        list.getMemoryRecordByDescription("Cold rez").Value .. ";" ..
        list.getMemoryRecordByDescription("Radioactivity rez").Value .. ";" ..
        list.getMemoryRecordByDescription("Biohazard rez").Value .. ";" ..
        list.getMemoryRecordByDescription("Hypoxia rez").Value.."\n")
        tmp = list.getMemoryRecordByDescription("Body").Value
  end
end

if not itemRecordTimer then
  itemRecordTimer = createTimer()
  itemRecordTimer.Enabled = false
  itemRecordTimer.Interval = 100
  itemRecordTimer.OnTimer =  timer_tick
end


[ENABLE]
itemRecordTimer.Enabled = true
f.close()

[DISABLE]
itemRecordTimer.Enabled = false
firstTime = ""
f.close()


I have still the double f:write issue with my "get in the first time if" and I couldn't fix it despite your pointers @Dark Byte but ... it's good enough ! Embarassed
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