Okay. I can't believe this, but I just found out CheatEngine 6.0 has a new table structure.
here you go, this will handle the old and the new.
Code: Select all
function split(str, pat)
local t = {} -- NOTE: use {n = 0} in Lua-5.0
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
function LoadCheatEngine(file,process)
memLocations={};
local mem = xml.open(file);
local cheatVersion = mem:getAttribute("CheatEngineTableVersion");
if(cheatVersion == nil)then
local elements = mem:getElement("CheatEntries"):getElements("CheatEntry");
for i,v in pairs(elements) do
local memLocation=MemoryLocation(v);
memLocations[memLocation.Name] = memLocation;
end
return memLocations;
elseif(cheatVersion==10)then
local elements = mem:getElement("CheatEntries"):getElements("CheatEntry");
for i,v in pairs(elements) do
local memLocation=MemoryLocation10(v,process);
memLocations[memLocation.Name] = memLocation;
end
return memLocations;
else
print("unsupported CheatEngine file");
end
return nil;
end
MemoryLocation10 = class(function(memLoc,CEXMLCheatEntry,process)
memLoc.Name = string.gsub(CEXMLCheatEntry:getElement("Description"):getValue(), '"', "");
local addrS = CEXMLCheatEntry:getElement("Address"):getValue();
local addrList = split(string.gsub(addrS, '"', ""),"+");
if(#addrList == 1) then
memLoc.Address = tonumber(addrList[1],16);
else
local addrOffset = tonumber(addrList[2],16);
local addrModule = getModuleAddress(process, addrList[1]);
memLoc.Address = addrModule + addrOffset;
end
memLoc.Type = CEXMLCheatEntry:getElement("VariableType"):getValue();
memLoc.IsPointer = (CEXMLCheatEntry:getElement("Offsets")~=nil);
memLoc.Offsets = nil;
memLoc.Length = 0;
if(memLoc.IsPointer)then
osets = nil;
of = CEXMLCheatEntry:getElement("Offsets"):getElements("Offset");
if(#of > 1)then
osets = {};
for ii = #of,1,-1 do
table.insert(osets,tonumber(of[ii]:getValue(),16));
end
elseif(#of == 1) then
osets = tonumber(of[1]:getValue(),16);
end
memLoc.Offsets = osets;
end
if(memLoc.Type=="String")then
memLoc.Length = tonumber(CEXMLCheatEntry:getElement("Length"):getValue(),10);
end
if(memLoc.Type=="Array of byte")then
memLoc.Length = tonumber(CEXMLCheatEntry:getElement("ByteLength"):getValue(),10);
end
if(memLoc.Type=="Binary")then
memLoc.Length = tonumber(CEXMLCheatEntry:getElement("ByteLength"):getValue(),10);
memLoc.Start = tonumber(CEXMLCheatEntry:getElement("BitStart"):getValue(),10);
end
end)
MemoryLocation = class(function(memLoc,CEXMLCheatEntry)
memLoc.Name = CEXMLCheatEntry:getElement("Description"):getValue();
memLoc.Address = tonumber(CEXMLCheatEntry:getElement("Address"):getValue(),16);
memLoc.Type = tonumber(CEXMLCheatEntry:getElement("Type"):getValue(),10);
memLoc.IsPointer = (CEXMLCheatEntry:getElement("Pointer")~=nil);
memLoc.Offsets = nil;
memLoc.Length = 0;
if(memLoc.IsPointer)then
memLoc.Address = tonumber(CEXMLCheatEntry:getElement("Pointer"):getElement("Address"):getValue(),16);
osets = nil;
of = CEXMLCheatEntry:getElement("Pointer"):getElement("Offsets"):getElements("Offset");
if(#of > 1)then
osets = {};
for ii = #of,1,-1 do
table.insert(osets,tonumber(of[ii]:getValue(),16));
end
elseif(#of == 1) then
osets = tonumber(of[1]:getValue(),16);
end
memLoc.Offsets = osets;
end
if(memLoc.Type==7 or memLoc.Type==8 or memLoc.Type==5)then
memLoc.Length = tonumber(CEXMLCheatEntry:getElement("Length"):getValue(),10);
end
end)
function MemoryLocation:Value(process)
--tprint(self);
if(self.IsPointer)then
if(self.Type==0)then
return memoryReadBytePtr(process, self.Address, self.Offsets);
elseif(self.Type==1)then
return memoryReadShortPtr(process, self.Address, self.Offsets);
elseif(self.Type==2)then
return memoryReadIntPtr(process, self.Address, self.Offsets);
elseif(self.Type==3)then
return memoryReadFloatPtr(process, self.Address, self.Offsets);
elseif(self.Type==4)then
return memoryReadDoublePtr(process, self.Address, self.Offsets);
elseif(self.Type==5)then
bytes = {};
for i=1,self.Length do
table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets));
end
return bytes;
elseif(self.Type==6)then
return memoryReadDoublePtr(process, self.Address, self.Offsets);
elseif(self.Type==7)then
return memoryReadStringPtr(process, self.Address, self.Offsets, self.Length);
elseif(self.Type==8)then
bytes = {};
for i=1,self.Length do
table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets));
end
return bytes;
end
else
if(self.Type==0)then
return memoryReadByte(process, self.Address);
elseif(self.Type==1)then
return memoryReadShort(process, self.Address);
elseif(self.Type==2)then
return memoryReadInt(process, self.Address);
elseif(self.Type==3)then
return memoryReadFloat(process, self.Address);
elseif(self.Type==4)then
return memoryReadDouble(process, self.Address);
elseif(self.Type==5)then
bytes = {};
for i=1,self.Length do
table.insert(bytes, memoryReadByte(process, self.Address));
end
return bytes;
elseif(self.Type==6)then
return memoryReadDouble(process, self.Address);
elseif(self.Type==7)then
return memoryReadString(process, self.Address, self.Length);
elseif(self.Type==8)then
bytes = {};
for i=1,self.Length do
table.insert(bytes, memoryReadByte(process, self.Address));
end
return bytes;
end
end
end
function MemoryLocation10:Value(process)
--tprint(self);
if(self.IsPointer)then
if(self.Type=="Byte")then
return memoryReadBytePtr(process, self.Address, self.Offsets);
elseif(self.Type=="2 Bytes")then
return memoryReadShortPtr(process, self.Address, self.Offsets);
elseif(self.Type=="4 Bytes")then
return memoryReadIntPtr(process, self.Address, self.Offsets);
elseif(self.Type=="Float")then
return memoryReadFloatPtr(process, self.Address, self.Offsets);
elseif(self.Type=="8 Bytes")then
return memoryReadDoublePtr(process, self.Address, self.Offsets);
elseif(self.Type=="Binary")then
bytes = {};
for i=self.Start,self.Length do
table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets + i));
end
return bytes;
elseif(self.Type=="Double")then
return memoryReadDoublePtr(process, self.Address, self.Offsets);
elseif(self.Type=="String")then
return memoryReadStringPtr(process, self.Address, self.Offsets, self.Length);
elseif(self.Type=="Array of byte")then
bytes = {};
for i=1,self.Length do
table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets + i));
end
return bytes;
end
else
if(self.Type=="Byte")then
return memoryReadByte(process, self.Address);
elseif(self.Type=="2 Bytes")then
return memoryReadShort(process, self.Address);
elseif(self.Type=="4 Bytes")then
return memoryReadInt(process, self.Address);
elseif(self.Type=="Float")then
return memoryReadFloat(process, self.Address);
elseif(self.Type=="8 Bytes")then
return memoryReadDouble(process, self.Address);
elseif(self.Type=="Binary")then
bytes = {};
for i=self.Start,self.Length do
table.insert(bytes, memoryReadByte(process, self.Address + i));
end
return bytes;
elseif(self.Type=="Double")then
return memoryReadDouble(process, self.Address);
elseif(self.Type=="String")then
return memoryReadString(process, self.Address, self.Length);
elseif(self.Type=="Array of byte")then
bytes = {};
for i=1,self.Length do
table.insert(bytes, memoryReadByte(process, self.Address + i));
end
return bytes;
end
end
end