LUA Timer to read changing values in memory

H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
So im making this D3D menu and i don't understand how to create timer and to read memory address with it every 3 seconds or so. I have a pointer to it, i made it with AOB scan.
Code:
local RacePointer = getAddress("[Racetime]")
RacePointer = readPointer(RacePointer + 0x1C)
local function MyTimer()
if timer ~= nil
then
timer.Enabled = true
else
timer = createTimer()
timer.Interval = 3000
end
timer.Enabled = false
end

Option2=d3dhook_createTextContainer(fontmap,1,50+lineheight,'Race Timer: '..RacePointer)
The value shows up correctly but its only read if i click the execute.
 
TheyCallMeTim13

TheyCallMeTim13

Enchanter
Staff member
Administrator
Fearless Donors
Talents
Joined
Mar 3, 2017
Messages
1,793
You never actually create the timer with that code, since you never call mytimer. What you need to do is put the update code inside the timer function and the timer create code outside the function.

Here are some eample timers. https://fearlessrevolution.com/viewtopic.php?f=11&t=6492
Just note that the first example is a one shot timer, the third one will run as long as the memory record script is enabled.
 
H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
TheyCallMeTim13 said:
You never actually create the timer with that code, what you need to do is put the update code inside the timer function and the timer create code outside the function.

Here are some eample timers. https://fearlessrevolution.com/viewtopic.php?f=11&t=6492
I actually got this working
Code:
al = getAddressList()
mr = al.getMemoryRecordByDescription("My RaceTimer")
mra = al.getMemoryRecordByDescription("My RaceName")
mrb = al.getMemoryRecordByDescription("Player Size")
mrc = al.getMemoryRecordByDescription("Player Size Starter")
mr.OnGetDisplayValue = function(mr,valuestring)
mra.OnGetDisplayValue = function(mra,valuestringa)
mrb.OnGetDisplayValue = function(mrb,valuestringb)

  Option1.Text = 'Player Size: '..valuestringb
  Option2.Text = 'Race Timer: '..valuestring -- print value
  Option3.Text = 'Race Name: '..valuestringa
end
end
end
but now my problem is that when i load the CT file, i need to manually activate my Auto Assembler Scripts and then execute the LUA code. But i need the LUA to activate/enable my Auto Assembler scripts because i need to read stuff from my AOB Injections.
 
TheyCallMeTim13

TheyCallMeTim13

Enchanter
Staff member
Administrator
Fearless Donors
Talents
Joined
Mar 3, 2017
Messages
1,793
Is there a reason you have all the OnGetDisplayValue nested together like that? Seems like you should create one function for each that updates that one record using the "valuestring" parameter. With that the first two just sets the others OnGetDisplayValue repetedly and only the third one actually updates the option text. But to activate a memory record just set mr.Active to true. You can look in the celua.txt file in the CE folder for documentation, and the CE Wiki has a fair amount of this stuff documented with examples.
 
H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
TheyCallMeTim13 said:
Is there a reason you have all the OnGetDisplayValue nested together like that? Seems like you should create one function for each that updates that one record using the "valuestring" parameter. With that the first two just sets the others OnGetDisplayValue repetedly and only the third one actually updates the option text. But to activate a memory record just set mr.Active to true. You can look in the celua.txt file in the CE folder for documentation, and the CE Wiki has a fair amount of this stuff documented with examples.
Okay i changed it so it uses just one function
Code:
mr.OnGetDisplayValue = function(mr,mra,mrb,mrc,valuestring,valuestringa,valuestringb)

mr.Active=true
and i added the mr.Active=true but i still keep getting error of it not figuring out what the address name is (it can't read it because the AA scripts aren't enabled by the LUA even though i added the mr.Active=true.
 
TheyCallMeTim13

TheyCallMeTim13

Enchanter
Staff member
Administrator
Fearless Donors
Talents
Joined
Mar 3, 2017
Messages
1,793
That function only has two parameters "memoryrecord" and "valuestring", so "mr" will be "memoryrecord" and "mra" will be "valuestring". and with "mr.Active" "mr" needs to be the memory record that is the AA script.
Here's an example of one I use to format a game time record from seconds to a readable time.
Code:
TIME_MR.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' and tonumber(valuestring) ~= nil then
		local secs = tonumber(valuestring)
		if secs < 0 then
			return false, ''
		end
		local h = math.floor(secs / (60 * 60))
		local m = math.floor(secs / 60 % 60)
		local s = math.floor(secs % 60)
		return true, string.format("%.2d:%.2d:%.2d", h, m, s)
	else
		return false, valuestring
	end
end
EDIT:
and here's an example of one script enabling another. Basically "No Reload" enabling "Infinite Ammo".
Code:
{$lua}
if syntaxcheck then return end
local mr = AddressList.getMemoryRecordByID(78796)
------------------------------ ENABLE ------------------------------
[ENABLE]
if not mr.Active then
    AmmoClipWrtHook_InfiniteAmmo_Active = true
    mr.Active = true
end
------------------------------ DISABLE ------------------------------
[DISABLE]
if AmmoClipWrtHook_InfiniteAmmo_Active then
    AmmoClipWrtHook_InfiniteAmmo_Active = nil
    mr.Active = false
end
I have to get to work, so hopefully someone else will help. If not I'll check back after work today.
 
H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
TheyCallMeTim13 said:
That function only has two parameters "memoryrecord" and "valuestring", so "mr" will be "memoryrecord" and "mra" will be "valuestring". and with "mr.Active" "mr" needs to be the memory record that is the AA script.
Here's an example of one I use to format a game time record from seconds to a readable time.
Code:
TIME_MR.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' and tonumber(valuestring) ~= nil then
		local secs = tonumber(valuestring)
		if secs < 0 then
			return false, ''
		end
		local h = math.floor(secs / (60 * 60))
		local m = math.floor(secs / 60 % 60)
		local s = math.floor(secs % 60)
		return true, string.format("%.2d:%.2d:%.2d", h, m, s)
	else
		return false, valuestring
	end
end
EDIT:
and here's an example of one script enabling another. Basically "No Reload" enabling "Infinite Ammo".
Code:
{$lua}
if syntaxcheck then return end
local mr = AddressList.getMemoryRecordByID(78796)
------------------------------ ENABLE ------------------------------
[ENABLE]
if not mr.Active then
    AmmoClipWrtHook_InfiniteAmmo_Active = true
    mr.Active = true
end
------------------------------ DISABLE ------------------------------
[DISABLE]
if AmmoClipWrtHook_InfiniteAmmo_Active then
    AmmoClipWrtHook_InfiniteAmmo_Active = nil
    mr.Active = false
end
I have to get to work, so hopefully someone else will help. If not I'll check back after work today.
So you put lua code in the AOB? Also whats that getMemoryRecordByID(78796) ID value here?
 
H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
TheyCallMeTim13 said:
That function only has two parameters "memoryrecord" and "valuestring", so "mr" will be "memoryrecord" and "mra" will be "valuestring". and with "mr.Active" "mr" needs to be the memory record that is the AA script.
Here's an example of one I use to format a game time record from seconds to a readable time.
Code:
TIME_MR.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' and tonumber(valuestring) ~= nil then
		local secs = tonumber(valuestring)
		if secs < 0 then
			return false, ''
		end
		local h = math.floor(secs / (60 * 60))
		local m = math.floor(secs / 60 % 60)
		local s = math.floor(secs % 60)
		return true, string.format("%.2d:%.2d:%.2d", h, m, s)
	else
		return false, valuestring
	end
end
EDIT:
and here's an example of one script enabling another. Basically "No Reload" enabling "Infinite Ammo".
Code:
{$lua}
if syntaxcheck then return end
local mr = AddressList.getMemoryRecordByID(78796)
------------------------------ ENABLE ------------------------------
[ENABLE]
if not mr.Active then
    AmmoClipWrtHook_InfiniteAmmo_Active = true
    mr.Active = true
end
------------------------------ DISABLE ------------------------------
[DISABLE]
if AmmoClipWrtHook_InfiniteAmmo_Active then
    AmmoClipWrtHook_InfiniteAmmo_Active = nil
    mr.Active = false
end
I have to get to work, so hopefully someone else will help. If not I'll check back after work today.

Okay i tried these now and its super glitchy https://prnt.sc/qij2d8 and when i click ok to script i get https://prnt.sc/qij2p5

and the Lua script just prints same value for different strings https://prnt.sc/qij2z2 EDIT: i fixed the button click for the script but putting that mr.Active=true inside that script im trying to enable with it is not going to work so i need to put this somehow inside my LUA script that has the timer. Also it still prints those string names but they have same values, does this work? https://prnt.sc/qijtv2
 
TheyCallMeTim13

TheyCallMeTim13

Enchanter
Staff member
Administrator
Fearless Donors
Talents
Joined
Mar 3, 2017
Messages
1,793
Hereisme said:
...
Okay i tried these now and its super glitchy https://prnt.sc/qij2d8 and when i click ok to script i get https://prnt.sc/qij2p5

and the Lua script just prints same value for different strings https://prnt.sc/qij2z2 EDIT: i fixed the button click for the script but putting that mr.Active=true inside that script im trying to enable with it is not going to work so i need to put this somehow inside my LUA script that has the timer. Also it still prints those string names but they have same values, does this work? https://prnt.sc/qijtv2
Try something more like this:
Code:
al = getAddressList()
mrHS = al.getMemoryRecordByDescription('HamsterBall Size')
mrRT = al.getMemoryRecordByDescription('My RaceTimer')
mrRN = al.getMemoryRecordByDescription('My RaceName')
mrHS.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option1.Text = 'Player Size: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
mrRT.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option2.Text = 'Race Timer: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
mrRN.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option3.Text = 'Race Name: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
 
H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
TheyCallMeTim13 said:
Hereisme said:
...
Okay i tried these now and its super glitchy https://prnt.sc/qij2d8 and when i click ok to script i get https://prnt.sc/qij2p5

and the Lua script just prints same value for different strings https://prnt.sc/qij2z2 EDIT: i fixed the button click for the script but putting that mr.Active=true inside that script im trying to enable with it is not going to work so i need to put this somehow inside my LUA script that has the timer. Also it still prints those string names but they have same values, does this work? https://prnt.sc/qijtv2
Try something more like this:
Code:
al = getAddressList()
mrHS = al.getMemoryRecordByDescription('HamsterBall Size')
mrRT = al.getMemoryRecordByDescription('My RaceTimer')
mrRN = al.getMemoryRecordByDescription('My RaceName')
mrHS.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option1.Text = 'Player Size: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
mrRT.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option2.Text = 'Race Timer: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
mrRN.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option3.Text = 'Race Name: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
Okay that almost fixes all my problems, so it does create these texts and give them values properly though some of these don't work (mainly the race timer) https://prnt.sc/qina6n And i still don't know where i activate my Player Size AA AOB script? Also not sure if i should improve these
Code:
lineheight=d3dhook_texture_getHeight(fontmap) --fontmap inherits from texture so this can be used
Option1=d3dhook_createTextContainer(fontmap,1,50,'Player Size: '..PlayerSize)
Option2=d3dhook_createTextContainer(fontmap,1,50+lineheight,'Race Timer: '..RacePointer)
Option3=d3dhook_createTextContainer(fontmap,1,50+lineheight*2,'Race Name: '..RaceName)
In a sense that the concatenate strings are the functions that get the addresses... EDIT: hmm the race timer actually works now,weird so my current problem would be starting the AA AOB script after i click execute, also wanted to ask that how would i setup something like this https://prnt.sc/qino6j so that it would print text 'Camera Positions: (x,y,z)' ?
 
TheyCallMeTim13

TheyCallMeTim13

Enchanter
Staff member
Administrator
Fearless Donors
Talents
Joined
Mar 3, 2017
Messages
1,793
Hereisme said:
...

Okay that almost fixes all my problems, so it does create these texts and give them values properly though some of these don't work (mainly the race timer) https://prnt.sc/qina6n And i still don't know where i activate my Player Size AA AOB script? Also not sure if i should improve these
Code:
lineheight=d3dhook_texture_getHeight(fontmap) --fontmap inherits from texture so this can be used
Option1=d3dhook_createTextContainer(fontmap,1,50,'Player Size: '..PlayerSize)
Option2=d3dhook_createTextContainer(fontmap,1,50+lineheight,'Race Timer: '..RacePointer)
Option3=d3dhook_createTextContainer(fontmap,1,50+lineheight*2,'Race Name: '..RaceName)
In a sense that the concatenate strings are the functions that get the addresses... EDIT: hmm the race timer actually works now,weird so my current problem would be starting the AA AOB script after i click execute, also wanted to ask that how would i setup something like this https://prnt.sc/qino6j so that it would print text 'Camera Positions: (x,y,z)' ?
No sure where to put the activator for the AA script. How are you attaching to the process, and where is the rest of the script, is this a table or a trainer? You could try a timer and check for the process, then enable the AA script. Or just have the AA script also run the Lua code, and just nane the script "Enable This" or something like that.

As for the coordinates, just use "string.format".

So something like this.
Code:
//------------------------------ ENABLE ------------------------------
[ENABLE]
// AOB script enable section here
{$lua}
al = getAddressList()
mrHS = al.getMemoryRecordByDescription('HamsterBall Size')
mrRT = al.getMemoryRecordByDescription('My RaceTimer')
mrRN = al.getMemoryRecordByDescription('My RaceName')
mrHS.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option1.Text = 'Player Size: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
mrRT.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option2.Text = 'Race Timer: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
mrRN.OnGetDisplayValue = function(memoryrecord, valuestring)
	local x = readFloat('[playerpos]+758')
	local y = readFloat('[playerpos]+75C')
	local z = readFloat('[playerpos]+760')
	if x ~= nil and y ~= nil and z ~= nil then
		OptionPOS.Text = string.format('Camera Position: %.2f, %.2f, %.2f', x, y, z)
	end
	if type(valuestring) == 'string' then
		Option3.Text = 'Race Name: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
{$asm}
//------------------------------ DISABLE ------------------------------
[DISABLE]
// AOB script disable section here
 
H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
TheyCallMeTim13 said:
Hereisme said:
...

Okay that almost fixes all my problems, so it does create these texts and give them values properly though some of these don't work (mainly the race timer) https://prnt.sc/qina6n And i still don't know where i activate my Player Size AA AOB script? Also not sure if i should improve these
Code:
lineheight=d3dhook_texture_getHeight(fontmap) --fontmap inherits from texture so this can be used
Option1=d3dhook_createTextContainer(fontmap,1,50,'Player Size: '..PlayerSize)
Option2=d3dhook_createTextContainer(fontmap,1,50+lineheight,'Race Timer: '..RacePointer)
Option3=d3dhook_createTextContainer(fontmap,1,50+lineheight*2,'Race Name: '..RaceName)
In a sense that the concatenate strings are the functions that get the addresses... EDIT: hmm the race timer actually works now,weird so my current problem would be starting the AA AOB script after i click execute, also wanted to ask that how would i setup something like this https://prnt.sc/qino6j so that it would print text 'Camera Positions: (x,y,z)' ?
No sure where to put the activator for the AA script. How are you attaching to the process, and where is the rest of the script, is this a table or a trainer? You could try a timer and check for the process, then enable the AA script. Or just have the AA script also run the Lua code, and just nane the script "Enable This" or something like that.

As for the coordinates, just use "string.format".

So something like this.
Code:
//------------------------------ ENABLE ------------------------------
[ENABLE]
// AOB script enable section here
{$lua}
al = getAddressList()
mrHS = al.getMemoryRecordByDescription('HamsterBall Size')
mrRT = al.getMemoryRecordByDescription('My RaceTimer')
mrRN = al.getMemoryRecordByDescription('My RaceName')
mrHS.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option1.Text = 'Player Size: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
mrRT.OnGetDisplayValue = function(memoryrecord, valuestring)
	if type(valuestring) == 'string' then
		Option2.Text = 'Race Timer: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
mrRN.OnGetDisplayValue = function(memoryrecord, valuestring)
	local x = readFloat('[playerpos]+758')
	local y = readFloat('[playerpos]+75C')
	local z = readFloat('[playerpos]+760')
	if x ~= nil and y ~= nil and z ~= nil then
		OptionPOS.Text = string.format('Camera Position: %.2f, %.2f, %.2f', x, y, z)
	end
	if type(valuestring) == 'string' then
		Option3.Text = 'Race Name: ' .. valuestring
		return true, valuestring
	else
		return false, valuestring
	end
end
{$asm}
//------------------------------ DISABLE ------------------------------
[DISABLE]
// AOB script disable section here
Okay one more thing, how do i hide/disable all these texts if i press button lets say tilde button (0xc0)?
 
TheyCallMeTim13

TheyCallMeTim13

Enchanter
Staff member
Administrator
Fearless Donors
Talents
Joined
Mar 3, 2017
Messages
1,793
You can use a script with a hotkey that toggles the script then in that script set the fonmap's "Visible" property to false if true and true if false (or a simple "fm.Visible = not fm.Visible") in the main section of the script so it runs when enabled and disabled. Not really sure thought, never messed with the D3D mutch.
 
H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
TheyCallMeTim13 said:
You can use a script with a hotkey that toggles the script then in that script set the fonmap's "Visible" property to false if true and true if false (or a simple "fm.Visible = not fm.Visible") in the main section of the script so it runs when enabled and disabled. Not really sure thought, never messed with the D3D mutch.
Thank you so much for helping me with everything so far, i tried
Code:
function keydown(virtualkey,char)
  if (virtualkey==VK_UP) then
  fontmap.destroy=true
  else
  fontmap=d3dhook_createFontmap(font)
end
end
as i can't find fontmap function in any cheat engine wiki page and even this sadly doesn't work..
 
TheyCallMeTim13

TheyCallMeTim13

Enchanter
Staff member
Administrator
Fearless Donors
Talents
Joined
Mar 3, 2017
Messages
1,793
Hereisme said:
TheyCallMeTim13 said:
You can use a script with a hotkey that toggles the script then in that script set the fonmap's "Visible" property to false if true and true if false (or a simple "fm.Visible = not fm.Visible") in the main section of the script so it runs when enabled and disabled. Not really sure thought, never messed with the D3D mutch.
Thank you so much for helping me with everything so far, i tried
Code:
function keydown(virtualkey,char)
  if (virtualkey==VK_UP) then
  fontmap.destroy=true
  else
  fontmap=d3dhook_createFontmap(font)
end
end
as i can't find fontmap function in any cheat engine wiki page and even this sadly doesn't work..
Yeah, sometimes it's best to look in the "celua.txt" file in the CE folder, it has a list of functions and classes. Then I hit ctrl-f and enter what I'm looking for. The return from "createD3DHook" has a "OnKeyDown" property as well. And see if toggling the fontmap's "Visible" property works, you could create the fontmap then set visible to false and only show the text after the key is pressed. And in the code above you'll be creating a new fontmap every time a key is pressed except when it's the up key, so you'll want to move where you create the fontmap, or at least check for nil and create a font map only if it hasn't been created yet.
 
H

Hereisme

Noobzor
Joined
Jan 2, 2020
Messages
9
TheyCallMeTim13 said:
Hereisme said:
TheyCallMeTim13 said:
You can use a script with a hotkey that toggles the script then in that script set the fonmap's "Visible" property to false if true and true if false (or a simple "fm.Visible = not fm.Visible") in the main section of the script so it runs when enabled and disabled. Not really sure thought, never messed with the D3D mutch.
Thank you so much for helping me with everything so far, i tried
Code:
function keydown(virtualkey,char)
  if (virtualkey==VK_UP) then
  fontmap.destroy=true
  else
  fontmap=d3dhook_createFontmap(font)
end
end
as i can't find fontmap function in any cheat engine wiki page and even this sadly doesn't work..
Yeah, sometimes it's best to look in the "celua.txt" file in the CE folder, it has a list of functions and classes. Then I hit ctrl-f and enter what I'm looking for. The return from "createD3DHook" has a "OnKeyDown" property as well. And see if toggling the fontmap's "Visible" property works, you could create the fontmap then set visible to false and only show the text after the key is pressed. And in the code above you'll be creating a new fontmap every time a key is pressed except when it's the up key, so you'll want to move where you create the fontmap, or at least check for nil and create a font map only if it hasn't been created yet.
Thank you again. Can you explain to me that why using 2 D3D LUA scripts makes the virtual keys keydown function not working? on script A i have
Code:
function keydown(virtualkey,char)
if (virtualkey==49) then
  hiddenbyusera=not hiddenbyusera
    ShowMenu1()
    return true
  end
  end
d3dhook_onKey(keydown)
on LUA script B i have
Code:
function keydown1(virtualkey,char)
if (virtualkey==200) then
   hiddenbyuser=not hiddenbyuser
    ShowMenu()
    return true
  end


  setHighlighterToSelectedOption()

  return true
end
d3dhook_onKey(keydown1)
The scripts work fine when executed individually, but when same time then either one of those work or neither.
 
TheyCallMeTim13

TheyCallMeTim13

Enchanter
Staff member
Administrator
Fearless Donors
Talents
Joined
Mar 3, 2017
Messages
1,793
Hereisme said:
...
Thank you again. Can you explain to me that why using 2 D3D LUA scripts makes the virtual keys keydown function not working? on script A i have
Code:
function keydown(virtualkey,char)
if (virtualkey==49) then
  hiddenbyusera=not hiddenbyusera
    ShowMenu1()
    return true
  end
  end
d3dhook_onKey(keydown)
on LUA script B i have
Code:
function keydown1(virtualkey,char)
if (virtualkey==200) then
   hiddenbyuser=not hiddenbyuser
    ShowMenu()
    return true
  end


  setHighlighterToSelectedOption()

  return true
end
d3dhook_onKey(keydown1)
The scripts work fine when executed individually, but when same time then either one of those work or neither.
Not sure why both would stop working, but I can say when you set the "OnKeyDown" function it only takes one function. So whatever one you set last will be the only one that gets called. Best I can say is maybe setting it twice causes it to call neither function. Try running the same code twice and see if it stops work then too. But ultimately you'll need to combine the two functions and check for the different keys, and you can add a check to see if a memory record is active to have one or the other only work if a memory record has been enabled.
 
Top