View previous topic :: View next topic |
Author |
Message |
b0g_ How do I cheat? Reputation: 0
Joined: 22 Jan 2022 Posts: 5
|
Posted: Tue Jan 25, 2022 9:27 am Post subject: Using timers/loops properly [solved] |
|
|
I'm currently trying to figure out how to properly use createTimer to loop some code when a table entry is toggled. What I have is this:
Code: |
{$lua}
[ENABLE]
if not timer then
timer = createTimer(nil)
timer.OnTimer = function(timer)
--code here
end
timer.Interval = 250 --delay
timer.Enabled = true
else
timer.Enabled = true
end
[DISABLE]
if (timer) then
timer.Enabled = false
end
|
It works *almost* perfectly, once the entry is toggled it starts looping and once disabled it stops.
Now the issue here is that I have to change the timer name for every different entry, or else it will just do timer.Enabled on the timer that was first initialised.
I'm wondering if I could make a private timer just for the entry, that can't be referenced from a different one, so that I can just copy paste the script for all the cheats that need a loop when toggled.
Or even better is there a completely different way that can achieve that effect without using timers or what I'm currently doing. Thanks in advance!
Last edited by b0g_ on Tue Jan 25, 2022 3:20 pm; edited 1 time in total |
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Tue Jan 25, 2022 9:46 am Post subject: |
|
|
Try this:
Code: |
if not timer then
-- Good practice to ensure that the object has a parent, that way if anything erroroneous happens with the object a memory leak isn't created
-- because it can be destroyed when the parent is destroyed i.e. closed/terminated.
local timer = createTimer(getMainForm(), true)
timer.Interval = 250 --delay
timer.OnTimer = function(timer)
--code here
end
else
timer.Enabled = true
end
[DISABLE]
if timer then
timer.Enabled = false
end
|
You created timer as a global object rather than a private one (local), with the necessary changes you should yield the desired results.
|
|
Back to top |
|
|
b0g_ How do I cheat? Reputation: 0
Joined: 22 Jan 2022 Posts: 5
|
Posted: Tue Jan 25, 2022 10:09 am Post subject: |
|
|
Okay so I tried your code hoping that was the answer but when enabling the entry it seems to create a new timer every time and when disabling the entry it doesn't stop the old timer.
Here's the code, I'm using print to see when the code is being executed:
Code: |
{$lua}
[ENABLE]
if not timer then
local timer = createTimer(getMainForm(), true)
timer.Interval = 250 --delay
timer.OnTimer = function(timer)
--code here
print('test')
end
else
timer.Enabled = true
end
[DISABLE]
if timer then
timer.Enabled = false
end
|
I forgot to mention in the post that I had also tried using local but at the time I thought I was using it wrong but since it means that the timer is created locally I literally have no idea why this is happening...
|
|
Back to top |
|
|
Frouk Master Cheater Reputation: 5
Joined: 22 Jun 2021 Posts: 489 Location: mov dword ptr [Ukraine]
|
Posted: Tue Jan 25, 2022 11:15 am Post subject: |
|
|
i don't think thats Code: | if timer then timer.destroy() timer = nil end |
will work for local timers (the disable part won't do anything to timer since it created in enable section only)
_________________
void(__cdecl *Haxing)(HWND hGameWindow) |
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 142
Joined: 06 Jul 2014 Posts: 4344
|
Posted: Tue Jan 25, 2022 1:24 pm Post subject: |
|
|
b0g_ wrote: | Now the issue here is that I have to change the timer name for every different entry, or else it will just do timer.Enabled on the timer that was first initialised. | That's how global variables work. The easiest solution is to use a unique global name for each timer.
If you really don't want to do that, use the ID of the memory record to index into a global table that contains the timers:
Code: | {$lua}
if syntaxcheck then return end
if not scriptTimers then scriptTimers = {} end
[ENABLE]
local id = memrec.ID
local t = scriptTimers[id]
if t then
t.Enabled = true
else
t = createTimer()
t.Interval = 250
t.OnTimer = function()
-- code
end
scriptTimers[id] = t
end
[DISABLE]
local t = scriptTimers[memrec.ID]
if t then
t.Enabled = false
end |
You can also make the timers local and have them try to automatically disable themselves:
Code: | [ENABLE]
{$lua}
if syntaxcheck then return end
local t = createTimer()
t.Interval = 250
t.OnTimer = function(t)
if not memrec.Enabled then
t.Enabled = false
return
end
-- code
end
{$asm}
[DISABLE] | This has a more generic version of the ABA problem: if the timer is disabled and enabled again between timer invocations, multiple instances of the timer will be running.
You could solve this by introducing a counter that keeps track of which invocation the script is running in, store that in a global, and use it in the OnTimer function; however, you'd have the same problem with that global variable as you do now.
_________________
I don't know where I'm going, but I'll figure it out when I get there.
Last edited by ParkourPenguin on Tue Jan 25, 2022 3:35 pm; edited 1 time in total |
|
Back to top |
|
|
b0g_ How do I cheat? Reputation: 0
Joined: 22 Jan 2022 Posts: 5
|
Posted: Tue Jan 25, 2022 2:11 pm Post subject: |
|
|
ParkourPenguin wrote: | Code: | {$lua}
if syntaxcheck then return end
if not scriptTimers then scriptTimers = {} end
[ENABLE]
local id = memrec.ID
local t = scriptTimers[id]
if t then
t.Enabled = true
else
t = createTimer()
t.Interval = 250
t.OnTimer = function()
-- code
end
end
[DISABLE]
local t = scriptTimers[memrec.ID]
if t then
t.Enabled = false
end |
|
Outstanding, It seems to now work perfectly however I did have to make a small change to createTimer because it wasn't working when done directly to the variable t
So I now have a perfect timer that can be copy/pasted without changes since everything is local to the memrec.
Here you go if anyone needs it:
Code: |
{$lua}
if not scriptTimers then scriptTimers = {} end
local function onTimer(timer)
--code
end
[ENABLE]
local id = memrec.ID
local t = scriptTimers[id]
if t then
t.Enabled = true
else
scriptTimers[id] = createTimer() --changes I made
t = scriptTimers[id]
t.Interval = 250
t.OnTimer = onTimer
end
[DISABLE]
local t = scriptTimers[memrec.ID]
if t then
t.Enabled = false
end
|
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 142
Joined: 06 Jul 2014 Posts: 4344
|
Posted: Tue Jan 25, 2022 3:35 pm Post subject: |
|
|
Right, my bad, forgot this line:
Code: | scriptTimers[id] = t |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
paul44 Expert Cheater Reputation: 2
Joined: 20 Jul 2017 Posts: 152
|
Posted: Thu Mar 21, 2024 12:05 pm Post subject: get a list/status of running timers ? |
|
|
^ I really liked the idea about managing timers via a table. you can then easily show their current status.
However: I also use "instant_kill" timers, primarily for auto-closing scripts. Meaning: upon enabling, the script checks if prerequisites are met (eg pointers/values needed to be populated); and if not, just disables the script (and instructing user what to do next).
When something goes wrong - like game crashing - the timer does not get destroy()-ed; and will (probably) remain running its own instance till one quits the table ?!
=> if so, is there a way to show currently active/instantiated timer(objects) ?
------------------------
show current timers:
[code] local aTimer = { [99889922] = 'System', [88619] = 'Free Roam' }
local sTimer = ''
for k,v in pairs(scriptTimers) do
local sName = aTimer[k]
local sRun = 'OFF'
if (v.enabled) then sRun = 'ON ' end
local sID = string.sub(string.format('[%s]%s',tostring(k),string.rep(" ",10)),1,10)
sTimer = sTimer .. string.format('%5s - %s - %s',sRun,sID,sName) .. '\n'
--print(sTimer)
end
showMessage(sTimer)[/code]
|
|
Back to top |
|
|
|