if cheatEngineIs64Bit() then if string.find(package.cpath, 'clibs64')==nil then package.cpath=package.cpath..[[;.\clibs64\?.dll]] end else if string.find(package.cpath, 'clibs32')==nil then package.cpath=package.cpath..[[;.\clibs32\?.dll]] end end require("lfs") function loadMemoryScan_thread(t) --the thread is used to bypasses a bug in 6.3 t.synchronize(function(t) ms=getCurrentMemscan() mf=getMainForm() if getOpenedProcessID()==0 then messageDialog("Open a process first", mtError, mbOk) return end dialog=createOpenDialog() dialog.DefaultExt=".CS" dialog.Filter="Cheat Engine Scan files (*.CS)|*.CS" dialog.FilterIndex=1 if dialog.execute()==false then return end filename=dialog.Filename dialog.destroy() input=io.open(filename,"rb") scanvaluelength=string.byte(input:read(1)) scanvalue=input:read(scanvaluelength) scantype=string.byte(input:read(1)) vartype=string.byte(input:read(1)) savedscancount=string.byte(input:read(1)) savedscans={} for i=1,savedscancount do length=string.byte(input:read(1)) savedscans[i]=input:read(length) end --initial data has been read, now setup the scan state to be compatible with the saved state --easiest is just do a small scan --ms.newscan() --since ms.newScan was never implemented in ce 6.3 click on new scan if needed if ms.LastScanType~="stNewScan" then if mf.btnNewScan==nil then --ce 6.4 uses this name, 6.3 still uses the not so normal name mf.button2.doClick() --new scan else mf.btnNewScan.doClick() --new scan end end mf.scanvalue.Text='982451653' --nice number mf.vartype.itemindex=vartype --while I could have used ms.firstScan this is easier since I don't need to convert itemindex to vartype mf.scantype.itemindex=0 --exact value mf.cbWritable.setState(cbGrayed) mf.cbExecutable.setState(cbGrayed) mf.cbCopyOnWrite.setState(cbGrayed) mf.FromAddress.Lines.Text=string.format("%x", getAddress("kernel32.dll")) mf.ToAddress.Lines.Text=string.format("%x", getAddress("kernel32.dll")+1) --first scan if mf.btnNewScan==nil then --ce 6.4 uses this name, 6.3 still uses the not so normal name mf.button2.doClick() --new scan else mf.btnNewScan.doClick() --new scan end end) ms.waitTillDone() --this would freeze in the main thread in 6.3 t.synchronize(function(t) --tell the memscan that there are saved scans for i=1, savedscancount do ms.saveCurrentResults(savedscans[i]) end local fl=ms.FoundList; fl.deinitialize() --release the file handles --overwrite the files with the ones in this archive local olddir=lfs.currentdir() lfs.chdir(getCurrentMemscan().ScanresultFolder) local filecount=string.byte(input:read(1)) --nr of files for i=1, filecount do --for each file --get the filename local filenamelength=string.byte(input:read(1)) local name=input:read(filenamelength) --get the filesize local filesize=byteTableToQword({string.byte(input:read(8),1,8)}) local output=io.open(name,"wb") while output==nil do --it's possible that the first scan save is in progress, so keep trying sleep(40) output=io.open(name,"wb") end local data j=filesize while j>0 do local block=512*1024 if block>j then block=j end data=input:read(block) output:write(data) j=j-block end output:close() end input:close() lfs.chdir(olddir) fl.initialize() --reopen the files mf.scanvalue.Text=scanvalue --nice number mf.vartype.itemindex=vartype --while I could have used ms.firstScan this is easier since I don't need to convert itemindex to vartype mf.scantype.itemindex=scantype --exact value mf.foundcountlabel.Caption=fl.Count mf.miResetRange.doClick() end) end function loadMemoryScan() createNativeThread(loadMemoryScan_thread) end function saveMemoryScan() local i,j if getOpenedProcessID()==0 then messageDialog("Open a process first and do a scan", mtError, mbOk) return end local dialog=createSaveDialog() dialog.DefaultExt=".CS" dialog.Filter="Cheat Engine Scan files (*.CS)|*.CS" dialog.FilterIndex=1 if dialog.execute()==false then return nil end local filename=dialog.Filename dialog.destroy() --6.3 doesn't have a folder picker, so create one file that holds all data local output=io.open(filename,"wb") --save some settings local mf=getMainForm() --current scanvalue output:write(string.char(#mf.scanvalue.Text)) output:write(mf.scanvalue.Text) output:write(string.char(mf.scantype.ItemIndex)) output:write(string.char(mf.VarType.ItemIndex)) --get the filelist local files={} local olddir=lfs.currentdir() lfs.chdir(getCurrentMemscan().ScanresultFolder) --undocumented features are fun.... for file in lfs.dir('.') do if string.sub(file,1,1)~='.' then local f={} f.name=file f.size=lfs.attributes(file).size table.insert(files, f) end end --check the extensions for other things than first, undo or tmp local savedscans={} for i=1,#files do local ext=files[i].name:match("%.([^%.]+)$") if (string.upper(ext)~='FIRST') and (string.upper(ext)~='TMP') and (string.upper(ext)~='UNDO') then --check if it's already in the list local found=false for j=1,#savedscans do if savedscans[j]==ext then found=true break end end if found==false then table.insert(savedscans, found) end end end output:write(string.char(#savedscans)) for i=1,#savedscans do output:write(string.char(#savedscans[i])) output:write(savedscans[i]) end --now save the files output:write(string.char(#files)) --number of files for i=1, #files do --write the filename output:write(string.char(#files[i].name)) output:write(files[i].name) local input=io.open(files[i].name,"rb") local data --write the filesize (qword) j=files[i].size output:write(string.char(unpack(qwordToByteTable(files[i].size)))) --write the file while j>0 do local block=512*1024 if block>j then block=j end data=input:read(block) output:write(data) j=j-block end input:close() end lfs.chdir(olddir) output:close() end local mf=getMainForm() SaveScanSession={} SaveScanSession.miSaveScanSession=createMenuItem(mf.Menu) SaveScanSession.miSaveScanSession.caption='Save scan session' SaveScanSession.miSaveScanSession.Shortcut='Ctrl+Alt+Shift+S' SaveScanSession.miSaveScanSession.OnClick=saveMemoryScan mf.Menu.Items[0].insert(9, SaveScanSession.miSaveScanSession) SaveScanSession.miLoadScanSession=createMenuItem(mf.Menu) SaveScanSession.miLoadScanSession.caption='Load scan session' SaveScanSession.miLoadScanSession.Shortcut='Ctrl+Alt+Shift+O' SaveScanSession.miLoadScanSession.OnClick=loadMemoryScan mf.Menu.Items[0].insert(10, SaveScanSession.miLoadScanSession) mi=createMenuItem(mf.Menu) --seperator mi.caption='-' mf.Menu.Items[0].insert(11, mi)