View previous topic :: View next topic |
Author |
Message |
Csimbi I post too much
Reputation: 97
Joined: 14 Jul 2007 Posts: 3320
|
Posted: Sat May 31, 2025 3:52 am Post subject: Sideloading data from file |
|
|
Hello LUA Masters!
I would like to save data next to the CT file, in a (preferably) text-based file, load the data from the file whenever the user enables the script and save it whenever the user changes some variable.
INI files come to mind and I found https://github.com/Dynodzzo/Lua_INI_Parser so I am thinking about using that.
If there are better practices, please let me know!
Anyhow, what I would like to understand is how does one locate the file.
- Is there a property for "my cheat table" so the memoryrecord could find out its own CT path?
- Is there a "last opened" somewhere?
- Is there a call to get the name of the CT file?
Thank you!
Last edited by Csimbi on Sat May 31, 2025 8:08 am; edited 1 time in total |
|
Back to top |
|
 |
AylinCE Grandmaster Cheater Supreme
Reputation: 36
Joined: 16 Feb 2017 Posts: 1511
|
Posted: Sat May 31, 2025 7:41 am Post subject: |
|
|
Which of these solutions approaches the problem?
Get the name or path of the opened table (.CT):
( autorun lua code ..)
Code: | mf = getMainForm()
if titleTmr then titleTmr.Destroy() titleTmr=nil end
titleTmr = createTimer(mf)
titleTmr.Interval = 2000
titleTmr.OnTimer=function()
title = mf.SaveDialog1 or mf.OpenDialog1 or nil
filefullpath = title.Filename
pathCut = extractFileName(filefullpath)
if filefullpath then
print(filefullpath)
print(pathCut)
-- load codes
else
print("no title or: " .. mf.caption)
end
titleTmr.Destroy()
end
titleTmr.Enabled=true |
Edit, save or replace:
https://forum.cheatengine.org/viewtopic.php?p=5778791#5778791
I think I deserve a little more explanation.
_________________
|
|
Back to top |
|
 |
Csimbi I post too much
Reputation: 97
Joined: 14 Jul 2007 Posts: 3320
|
Posted: Sat May 31, 2025 8:06 am Post subject: |
|
|
Much obliged, thank you!
I cut out the timer code and I used this:
Code: | mf = getMainForm()
title = mf.SaveDialog1 or mf.OpenDialog1 or nil
filefullpath = title.Filename
pathCut = extractFileName(filefullpath)
if filefullpath then
print(filefullpath)
print(pathCut)
-- load codes
else
print("no title or: " .. mf.caption)
end
|
Works great, thanks!
|
|
Back to top |
|
 |
AylinCE Grandmaster Cheater Supreme
Reputation: 36
Joined: 16 Feb 2017 Posts: 1511
|
Posted: Sat May 31, 2025 9:59 am Post subject: |
|
|
If you are going to use the code with the lua package in the autorun folder, you need to start it with a delay to get the correct result.
If the delay is set to 2-3 seconds with the timer, the program (CT) will not conflict with the loading process and will find a stable reading area.
Also, if you are thinking of using the code globally, you can visit the link below and consider the solution that makes it suitable for "OneDrive" or ASCII characters.
https://forum.cheatengine.org/viewtopic.php?p=5793327#5793327
...
_________________
|
|
Back to top |
|
 |
Csimbi I post too much
Reputation: 97
Joined: 14 Jul 2007 Posts: 3320
|
Posted: Sat May 31, 2025 11:34 am Post subject: |
|
|
Now you are trying to spoil me
Local files are good enough for me.
I actually got it working.
Full autoload when script is enabled and autosave when settings I interested in change.
Playtesting it now.
Thanks!
|
|
Back to top |
|
 |
AylinCE Grandmaster Cheater Supreme
Reputation: 36
Joined: 16 Feb 2017 Posts: 1511
|
Posted: Sat May 31, 2025 1:35 pm Post subject: |
|
|
Ahh, if the code is currently doing a sufficient job, that's fine.
Ignore this, I'm just observing the details out loud..
_________________
|
|
Back to top |
|
 |
Skyrimfus Cheater
Reputation: 1
Joined: 17 Mar 2016 Posts: 43
|
Posted: Sat Aug 02, 2025 7:21 am Post subject: |
|
|
Funny, I wanted to do the same thing and came across this post.
I've already done my research and found out about TrainerOrigin lua variable, which holds the path to the .CT folder, but only if you launch the table by double clicking on the .CT file.
SaveDialog1 and OpenDialog1 work, but if you drag and drop the .CT to CE, after you attach to the process, they just get rewritten to the process name (junk for us)
What works the best for me (credit to Akira Fudo for pointing this out) is the lua function
Code: | lfs.getcurrentdir() |
|
|
Back to top |
|
 |
AylinCE Grandmaster Cheater Supreme
Reputation: 36
Joined: 16 Feb 2017 Posts: 1511
|
Posted: Sat Aug 02, 2025 12:13 pm Post subject: |
|
|
Code: | lfs = require("lfs")
print(lfs.currentdir()) -- = cheatEngineDir() --> No CT Path |
In our case, perhaps the following example would be fun:
Code: | function getProcessHandles(pid)
local outFile = getTempFolder().."handleOut.txt"
if outFile then -- create list file ..
local cmd = 'powershell -Command "Get-CimInstance Win32_Process -Filter \\"ProcessId='..pid..'\\" | Select-Object -ExpandProperty CommandLine | Out-File -FilePath \\"'..outFile..'\\" -Encoding UTF8"'
runCommand(cmd)
local exePath, argList = nil, {}
local f = io.open(outFile, "r")
if f then
for line in f:lines() do
local parts = {}
for quoted in line:gmatch('"([^"]+)"') do table.insert(parts, quoted) end
local raw = line:gsub('"[^"]+"', "")
for arg in raw:gmatch("%S+") do table.insert(parts, arg) end
for i = 1, #parts do print(i,parts[i]) table.insert(argList, parts[i]) end
end
f:close()
end
deleteFile(outFile) -- delete list file ..
return argList
else
print("Something went wrong! Couldn't create output file!")
return nil
end
end
local somePid = getForegroundProcess()
local handleList = getProcessHandles(somePid)
local exePath = handleList[1]
local handlePath = handleList[2] or ""
print("pid: "..somePid)
print("Exe Path: "..extractFilePath(exePath))
print("Exe Name: "..extractFileName(exePath))
print("\nCT Path: "..extractFilePath(handlePath))
print("\nCT Name: "..extractFileName(handlePath)) |
Maybe you want to print this information to the console with a small delay every time CE starts:
Code: | function getProcessHandles(pid)
local outFile = getTempFolder().."handleOut.txt"
if outFile then -- create list file ..
local cmd = 'powershell -Command "Get-CimInstance Win32_Process -Filter \\"ProcessId='..pid..'\\" | Select-Object -ExpandProperty CommandLine | Out-File -FilePath \\"'..outFile..'\\" -Encoding UTF8"'
runCommand(cmd)
local exePath, argList = nil, {}
local f = io.open(outFile, "r")
if f then
for line in f:lines() do
local parts = {}
for quoted in line:gmatch('"([^"]+)"') do table.insert(parts, quoted) end
local raw = line:gsub('"[^"]+"', "")
for arg in raw:gmatch("%S+") do table.insert(parts, arg) end
for i = 1, #parts do print(i,parts[i]) table.insert(argList, parts[i]) end
end
f:close()
end
deleteFile(outFile) -- delete list file ..
return argList
else
print("Something went wrong! Couldn't create output file!")
return nil
end
end
if nameKy then nameKy.Destroy() nameKy=nil end
nameKy=createTimer()
nameKy.Interval=1000 -- Wait for the opening difference
nameKy.OnTimer=function(t)
local somePid = getForegroundProcess()
local handleList = getProcessHandles(somePid)
local exePath = handleList[1]
local handlePath = handleList[2] or ""
print("pid: "..somePid.."\nexePath: "..exePath.."\nCT Path: "..handlePath)
t.Destroy()
end |
_________________
|
|
Back to top |
|
 |
LeFiXER Grandmaster Cheater Supreme
Reputation: 20
Joined: 02 Sep 2011 Posts: 1069 Location: 0x90
|
Posted: Sun Aug 10, 2025 4:39 am Post subject: |
|
|
AylinCE wrote: | Code: | lfs = require("lfs")
print(lfs.currentdir()) -- = cheatEngineDir() --> No CT Path |
|
LFS is bundled with CE already. No need for a separate module. LFS can also be used to navigate directories and check the properties of files/folders.
|
|
Back to top |
|
 |
AylinCE Grandmaster Cheater Supreme
Reputation: 36
Joined: 16 Feb 2017 Posts: 1511
|
Posted: Sun Aug 10, 2025 1:35 pm Post subject: |
|
|
LeFiXER wrote: | AylinCE wrote: | Code: | lfs = require("lfs")
print(lfs.currentdir()) -- = cheatEngineDir() --> No CT Path |
|
LFS is bundled with CE already. No need for a separate module. LFS can also be used to navigate directories and check the properties of files/folders. |
Test the output of this code in two ways.
1)
Code: |
print(lfs.currentdir()) |
2)
Code: | lfs = require("lfs")
print(lfs.currentdir()) |
Result?
_________________
|
|
Back to top |
|
 |
LeFiXER Grandmaster Cheater Supreme
Reputation: 20
Joined: 02 Sep 2011 Posts: 1069 Location: 0x90
|
Posted: Mon Aug 11, 2025 6:20 am Post subject: |
|
|
AylinCE wrote: |
Test the output of this code in two ways.
1)
Code: |
print(lfs.currentdir()) |
2)
Code: | lfs = require("lfs")
print(lfs.currentdir()) |
Result? |
The result is the same path: "C:\Program Files\Cheat Engine".
|
|
Back to top |
|
 |
AylinCE Grandmaster Cheater Supreme
Reputation: 36
Joined: 16 Feb 2017 Posts: 1511
|
Posted: Mon Aug 11, 2025 6:55 am Post subject: |
|
|
Perhaps it's because I tried it on a different configured version (sometimes I can't use the original CE version while the game is running). The first code didn't work for me, because the required LFS code did.
That's why I provided the example as defined.
This might yield different results for some users (on the original or modified CE models).
I shared it because if defining it doesn't produce an error, it might be a workable solution.
_________________
|
|
Back to top |
|
 |
LeFiXER Grandmaster Cheater Supreme
Reputation: 20
Joined: 02 Sep 2011 Posts: 1069 Location: 0x90
|
Posted: Mon Aug 11, 2025 10:05 am Post subject: |
|
|
That's a fair take. I was just mentioning it in case you were unaware, but it seems you need it. Strange situation, but at least you have resolved it .
|
|
Back to top |
|
 |
|