|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Zanzer I post too much Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sun Feb 08, 2015 5:45 pm Post subject: Dropdown Menu Lists |
|
|
Just throwing out this suggestion.
Instead of adding the dropdown options specifically for a single address, I would store the list and give it a name. Then, assign that name to the address.
I only mention this because I was recently hacking a game that had multiple addresses, but each one had the same possibility of values. So I had to add the same list of 100+ values to the 12 separate addresses, increasing the file size dramatically.
|
|
Back to top |
|
|
MindCaged Newbie cheater Reputation: 0
Joined: 25 Apr 2013 Posts: 10
|
Posted: Tue Apr 28, 2015 7:28 pm Post subject: |
|
|
I agree. I just posted a different post about this. First of all it's really time consuming, so it'd also be good if you could modify the dropdown settings of multiple entries at once, currently it only lets you do so on individual ones. I became so desperate that I resorted to opening the file in textpad and copy/pasting the xml tags for the dropdown info to each of 256 inventory slot entries. Which also BTW really inflated the filesize by a lot.
|
|
Back to top |
|
|
predprey Master Cheater Reputation: 24
Joined: 08 Oct 2015 Posts: 486
|
Posted: Tue Jan 19, 2016 1:17 pm Post subject: |
|
|
Would writing in this feature require a major recoding? I'm interested in coding in this function if it's not contradictory to the existing code.
|
|
Back to top |
|
|
panraven Grandmaster Cheater Reputation: 55
Joined: 01 Oct 2008 Posts: 941
|
Posted: Tue Jan 19, 2016 3:46 pm Post subject: |
|
|
Probably by Lua, but the code itself may consider an overhead in size.
This not sure bug free.
Code: | function MRIter(process,filter,mr,parent,lv)
local function strSplit(s,pat)
local find,sub,ps,ds = string.find,string.sub,{},{}
local n,a,b = 1,find(s,pat,1)
while a~=nil do
ps[1+#ps]=sub(s,n,a-1)
ds[1+#ds]=sub(s,a,b)
n = b+1
a,b = find(s,pat,n)
end
ps[1+#ps]=sub(s,n,-1)
return ps,ds
end
lv = lv or 0
if mr==nil then mr = getAddressList()
elseif type(mr)=='string' then
mr = assert(getAddressList().GetMemoryRecordByDescription(mr),"Can't find mr with desc:"..mr)
end
local stop = mr.ID and process(mr,parent,lv) or nil -- not process root (getAddressList)
if stop==nil then
if type(filter)=='string' then
local kv,pair = {},strSplit(filter,';')
if #pair>0 then
for i=1,#pair do
local p = strSplit(pair[i],'=')
if #p==2 then kv[p[1]:match("^%s*(.-)%s*$")] = p[2]:match("^%s*(.-)%s*$") end
end
end
filter = function(mR)
for k,v in pairs(kv) do
if not tostring(mR[k]):match(v) then return false end
end
return true
end
elseif type(filter)~='function' then
filter = false
end
for i=0,mr.Count-1 do
if filter==false or filter(mr[i]) then
stop = MRIter(process,filter,mr[i],mr,lv+1)
if stop~=nil then break end
end
end
end
return stop
end
-- TEST --
MRIter(function(mr,p,lv)
print(string.rep(" ",lv*2)..mr.Description)
mr.DropDownList.Text = "1:AAA\n2:BBB\n3:CCC" -- long text to be applied to multiple records
end,
"Type="..tostring(vtString)..';Address=_res') -- 2 properties to test
-- filter is a string of form "pro1=match1;pro2=match2"
-- where the mr's pro1's value will convert to string and do
-- a string match with match1. Process the mr if all prop1,..propn match.
-- Leave it for process all mr. |
updated:
typo: ... .GetMemoryRecordByDescription(mrdesc) -> .GetMemoryRecordByDescription(mr)
_________________
- Retarded.
Last edited by panraven on Wed Jan 20, 2016 6:19 am; edited 1 time in total |
|
Back to top |
|
|
predprey Master Cheater Reputation: 24
Joined: 08 Oct 2015 Posts: 486
|
Posted: Wed Jan 20, 2016 2:56 am Post subject: |
|
|
how did you come across the DropDownList attribute? neither the wiki page for MemoryRecord class nor CE's help file had any info on it. did you perhaps comb through CE's code to find it? are there a lot more of these hidden functions in CE?
|
|
Back to top |
|
|
panraven Grandmaster Cheater Reputation: 55
Joined: 01 Oct 2008 Posts: 941
|
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Wed Jan 20, 2016 6:56 am Post subject: |
|
|
Add memory records with only one DropDownList entry (not in "value:desc" format):
"myDropDownList"
then you can execute this:
Code: | myDropDownList = [[1:one
2:two
3:three]]
al=getAddressList()
for i=0,al.Count-1 do
if al[i].DropDownList[0]=='myDropDownList' then
al[i].DropDownList.Text = myDropDownList
end
end |
_________________
|
|
Back to top |
|
|
panraven Grandmaster Cheater Reputation: 55
Joined: 01 Oct 2008 Posts: 941
|
Posted: Wed Jan 20, 2016 7:17 am Post subject: |
|
|
mgr.inz.Player wrote: | Add memory records with only one DropDownList entry (not in "value:desc" format):
"myDropDownList"
then you can execute this:
Code: | myDropDownList = [[1:one
2:two
3:three]]
al=getAddressList()
for i=0,al.Count-1 do
if al[i].DropDownList[0]=='myDropDownList' then
al[i].DropDownList.Text = myDropDownList
end
end |
|
The marker "myDropDownList" may got overwritten into the saved *.ct with accidental saving by user, probably some other alternative checking?
ADDED:
oops, nvm, it is not a problem as the option text is static.
_________________
- Retarded. |
|
Back to top |
|
|
TurtleCray How do I cheat? Reputation: 0
Joined: 13 Dec 2009 Posts: 6
|
Posted: Thu Mar 31, 2016 9:34 am Post subject: |
|
|
mgr.inz.Player wrote: | Add memory records with only one DropDownList entry (not in "value:desc" format):
"myDropDownList"
then you can execute this:
Code: | myDropDownList = [[1:one
2:two
3:three]]
al=getAddressList()
for i=0,al.Count-1 do
if al[i].DropDownList[0]=='myDropDownList' then
al[i].DropDownList.Text = myDropDownList
end
end |
|
Hi,
I was trying to use your code to make a table for Factorio but it returns me this error:
Error:List index (0) out of bounds
My list follows this structure:
Code: | HotBarAddress -> XXXXXXXXXX
Slot1 Qtd: -> +0
Type -> +8
Slot2 Qtd: -> +10
Type -> +8
Slot3 Qtd: -> +20
Type -> +8
|
I would want to make the types as a dropdown list. Do you have any advice?
Thanks
|
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Thu Mar 31, 2016 3:22 pm Post subject: |
|
|
Updated script:
function addDropDownList(list, listName, DropDownReadOnly, DropDownDescriptionOnly, DisplayAsDropDownListItem)
list - string with a list
listName - to find this string in existing memoryrecords and replace with list
DropDownReadOnly - optional Boolean, disallow manual user input, default is false
DropDownDescriptionOnly - optional Boolean, only show the description part, default is false
DisplayAsDropDownListItem - optional Boolean, make the record display values like the dropdown list, default is false
Code: | function addDropDownList(list, listName, ...)
local DropDownReadOnly,DropDownDescriptionOnly,DisplayAsDropDownListItem=...
local al=getAddressList()
for i=0,al.Count-1 do
if al[i].DropDownList.Text:match(listName) then
al[i].DropDownList.Text = list
al[i].DropDownReadOnly=DropDownReadOnly
al[i].DropDownDescriptionOnly=DropDownDescriptionOnly
al[i].DisplayAsDropDownListItem=DisplayAsDropDownListItem
end
end
end
myDropDownList = [[
1:one
2:two
3:three]]
myDropDownListName = 'myDropDownList'
addDropDownList(myDropDownList,myDropDownListName,true,false,true) |
_________________
|
|
Back to top |
|
|
akumakuja28 Master Cheater Reputation: 16
Joined: 28 Jun 2015 Posts: 432
|
Posted: Sun Apr 10, 2016 1:39 am Post subject: |
|
|
From my misunderstanding on this post Cheat table to big to upload
about how big a data structure could be(*dont use them) and suggesting he use a "Add Drop Menu" LUA script to add the drop list after Download.
I wrote this up to Add Drop List to Defined Cheat Entries.
It has some redundancy but easier to understand that way. Figure it would be best to post it here vs the thread in question.
Code: |
local Drop_List_Items=[[
0:None
1:One
2:Two
255:MAX
]]---End of Drop List
local Cheat_Entries_For_Drop_Attach = {'Slot 2',"Slot 1","Slot 3"}
local TableCount = getAddressList().Count
for j=0,TableCount-1 do
local CR = getAddressList().getMemoryRecord(j)
local Yada = (CR.Description)
for LC=1,#Cheat_Entries_For_Drop_Attach do
local DropAdd = (Cheat_Entries_For_Drop_Attach[LC])
if DropAdd==Yada then
print('Match Found'..' @ '..Yada)
CR.DropDownList.Text = Drop_List_Items
---------------------
-------- Options ----
CR.DropDownReadOnly=false ---Disallow manual user input
CR.DropDownDescriptionOnly=true ----Only show the description part
CR.DisplayAsDropDownListItem=true ---Make the record display values like the dropdownlist
---------------------
end
end
end |
_________________
|
|
Back to top |
|
|
Rhagic Advanced Cheater Reputation: 4
Joined: 23 Aug 2011 Posts: 94
|
Posted: Sat May 14, 2016 10:43 am Post subject: |
|
|
akumakuja28 wrote: | I wrote this up to Add Drop List to Defined Cheat Entries.
|
Thank you for posting this, it was really helpful and inspiration to write some LUA for creating memory records for repetitive entries.
Off the back of it, I wrote something for the item inventory in for Final Fantasy X. On the github main.lua I found that memory records have a DontSave boolean. So this creates 200+ entries at "run time" that aren't written back to the CT file.
http://forum.cheatengine.org/viewtopic.php?p=5670288#5670288
Here's a snippet that might help inspiration for others, it creates child entries under a pre-defined group header called "Items".
I couldn't find a way of deleting the child records, which would be handy clean up when running the function multiple times. Also couldn't find a way to create Group Headers either.
What would be really neat is to have the LUA executed by expanding the Group Header in the table to create the child entries on the fly then.
Code: | local item_table = {
[0]="Potion",
[1]="Hi-potion",
[2]="X-potion",
--- truncated
[109]="Gambler's Spirit",
[110]="Underdog's Secret",
[111]="Winning Formula",
}
local droplist = "255:NULL\n"
for k,v in pairs(item_table) do
droplist = droplist .. k + 8192 .. ":" .. v .. "\n"
end
local itemCount = 150
local quantity_base = "FFX.exe+D30B5C"
local type_base = "FFX.exe+D3095C"
local addr_list = getAddressList()
local group = addr_list.getMemoryRecordByDescription("Items")
for i=0, itemCount -1 do
local slot_number = i+1
-- Item Type with dropdown
local slot_type = addr_list.createMemoryRecord()
slot_type.setDescription("Slot " .. slot_number .. " Type")
slot_type.setAddress(type_base .. "+2*" .. string.format( '%x', i))
slot_type.DontSave = true
slot_type.Type = vtWord
slot_type.appendToEntry(group)
slot_type.DropDownList.Text = droplist
-------- Options ----
slot_type.DropDownReadOnly=true ---Disallow manual user input
slot_type.DropDownDescriptionOnly=false ----Only show the description part
slot_type.DisplayAsDropDownListItem=true ---Make the record display values like the dropdownlist
-- Item Quantity
local slot_quantity = addr_list.createMemoryRecord()
slot_quantity.setDescription("Slot " .. slot_number .. " Quantity")
slot_quantity.setAddress(quantity_base .. "+" .. string.format( '%x', i))
slot_quantity.DontSave = true
slot_quantity.Type = vtByte
slot_quantity.appendToEntry(group)
end
|
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Thu May 19, 2016 4:53 pm Post subject: |
|
|
It would be nice if DB made the DropDownList property writable, such that we can assign the same stringlist to multiple memory records. That way, when you update one, the others will be updated as well.
I made a function that will forcefully do this, but I'm not sure if it has any other unintended side effects. It will probably break with any future versions of CE, but I figure whoever cares enough about this stuff will be able to figure out the new offsets themselves.
Code: | --[[
memrec - the memory record to update
strlist - the string list to assign to the memory record's DropDownList property
destroy (opt) - indicates whether or not it should destroy the overwritten stringlist. This can cause memory access violations if there are any references to the string list still around (i.e. another memory record is also using this string list).
]]
function setDropDownList(memrec, strlist, destroy)
assert(memrec and memrec.ClassName == "TMemoryRecord", "invalid memrec")
assert(strlist and strlist.ClassName == "TStringList", "invalid strlist")
local oldList
if destroy then oldList = memrec.DropDownList end
if cheatEngineIs64Bit() then
local recBase = assert(readQwordLocal(tostring(memrec):match("%x+$")), "Could not read userdata")
local strBase = assert(readQwordLocal(tostring(strlist):match("%x+$")), "Could not read userdata")
assert(readStringLocal(readQwordLocal(readQwordLocal(readQwordLocal(recBase+0x90))+0x18)+0x1, 11) == "TStringList", "memrec offset 0x90 is not TStringList")
assert(readStringLocal(readQwordLocal(readQwordLocal(strBase)+0x18)+0x1, 11) == "TStringList", "invalid strlist")
writeQwordLocal(recBase+0x90,strBase)
else
local recBase = assert(readIntegerLocal(tostring(memrec):match("%x+$")), "Could not read userdata")
local strBase = assert(readIntegerLocal(tostring(strlist):match("%x+$")), "Could not read userdata")
assert(readStringLocal(readIntegerLocal(readIntegerLocal(readIntegerLocal(recBase+0x54))+0xC)+0x1, 11) == "TStringList", "memrec offset 0x54 is not TStringList")
assert(readStringLocal(readIntegerLocal(readIntegerLocal(strBase)+0xC)+0x1, 11) == "TStringList", "invalid strlist")
writeQwordLocal(recBase+0x54,strBase)
end
if oldList then oldList.destroy() end -- destroyed here just in case CE tries to access the DropDownList while this is assigning the new list
end |
I was sad to figure out that CE saves the text and attributes of the drop down lists on a per memory record basis, so this won't actually help anyone save disk space. Hopefully someone can still make use of it, though.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
Rhagic Advanced Cheater Reputation: 4
Joined: 23 Aug 2011 Posts: 94
|
Posted: Fri May 20, 2016 4:47 am Post subject: |
|
|
ParkourPenguin wrote: | I was sad to figure out that CE saves the text and attributes of the drop down lists on a per memory record basis, so this won't actually help anyone save disk space. Hopefully someone can still make use of it, though. |
Thank you.
Actually, it could help. I've started populating the memory records using LUA and not having them saved back to the CT file with:
Code: | rec.DontSave = true |
|
|
Back to top |
|
|
|
|
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
|
|