  | 
				
				Cheat Engine The Official Site of Cheat Engine   
				
 
				 | 
			 
		 
		 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		Dark Byte Site Admin
  Reputation: 470
  Joined: 09 May 2003 Posts: 25807 Location: The netherlands
  | 
		
			
				 Posted: Fri Apr 29, 2022 9:44 am    Post subject: Using notepad as your memoryrecord AA editor | 
				        | 
			 
			
				
  | 
			 
			
				I'm sure everyone wishes they could edit their addresslist memoryrecord AA scripts using notepad instead of ce's built-in editor
 
 
you can do that with this script
 
 
Just doubleclick on the script part and instead of opening the CE AA editor, notepad will pop up with the curent script. 
 
 
Do not forget to save the script before closing notepad
 
 
 	  | Code: | 	 		  
 
function LaunchCommandAndWait(command)
 
  local lpStartupInfo=createMemoryStream()
 
  local lpProcessInfo=createMemoryStream()
 
  local sisize
 
  local pisize
 
  local r
 
 
  local result
 
 
  if cheatEngineIs64Bit() then
 
    sisize=104
 
    pisize=24
 
  else
 
    sisize=68
 
    pisize=16
 
  end
 
  lpStartupInfo.writeDword(sisize)
 
  lpStartupInfo.Size=sisize
 
  lpProcessInfo.Size=pisize
 
 
  r=executeCodeLocalEx('CreateProcessA',0,command,0,0,0,0,0,0,lpStartupInfo.Memory,lpProcessInfo.Memory);
 
 
  if r~=0 then
 
    lpProcessInfo.Position=0
 
    local hProcess
 
    local hThread
 
    if cheatEngineIs64Bit() then
 
      hProcess=lpProcessInfo.readQword()
 
      hThread=lpProcessInfo.readQword()
 
    else
 
      hProcess=lpProcessInfo.readDword()
 
      hThread=lpProcessInfo.readDword()
 
    end
 
 
    r=executeCodeLocalEx('WaitForSingleObject', hProcess, 0xffffffff)
 
    local ExitCode=createMemoryStream()
 
    ExitCode.Size=4
 
    if executeCodeLocalEx('GetExitCodeProcess', hProcess, ExitCode.Memory)~=0 then
 
      result=ExitCode.readDword()
 
    end
 
    ExitCode.destroy()
 
 
    --cleanup handles
 
    executeCodeLocalEx('CloseHandle', hProcess)
 
    executeCodeLocalEx('CloseHandle', hThread)
 
  end
 
 
  lpProcessInfo.destroy()
 
  lpStartupInfo.destroy()
 
 
  return result
 
end
 
 
local counter=0
 
 
local active={}
 
 
AddressList.OnAutoAssemblerEdit=function(al,mr)
 
 -- print("editing aa script")
 
  if active[mr.ID] then return true end --already editing
 
 
  mr.beginEdit()
 
 -- print("memrec has been marked as editing")
 
  local sl=createStringList()
 
  sl.Text=mr.Script
 
 
  local path
 
  if getTempFolder then
 
    path=getTempFolder()
 
  else
 
    path=getCheatEngineDir()
 
  end
 
  lfs.mkdir(path.."editing-ceaascripts") --assume it works, or it already exists
 
  path=path.."editing-ceaascripts\\"
 
 
  --printf("initial path=%s", path)
 
 
  local ms=createMemoryStream()
 
  ms.size=260
 
  if executeCodeLocalEx("GetTempFileNameA", path,"CEA",0,ms.Memory) ~=0 then
 
    path=readStringLocal(ms.Memory,260)
 
    --printf("final path=%s", path)
 
 
    ms.destroy()
 
 
    --printf("saving script to %s", path)
 
    sl.saveToFile(path)
 
    active[mr.ID]=true
 
 
    createThread(function(t)
 
      --print("AA editorthread: Launching notepad and wait")
 
      LaunchCommandAndWait('notepad.exe '..path)
 
 
      --print("AA editorthread: Finished waiting")
 
      sl.loadFromFile(path)
 
      mr.Script=sl.Text
 
      mr.endEdit()
 
      sl.destroy()
 
 
      active[mr.ID]=nil
 
     -- print("done editing")
 
    end)
 
    return true
 
  else
 
    print("GetTempFileNameA failed")
 
    sl.destroy()
 
    ms.destroy()
 
    return false
 
  end
 
end
 
 | 	 
  _________________
 Do not ask me about online cheats. I don't know any and wont help finding them.
 
 
Like my help? Join me on Patreon so i can keep helping  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		++METHOS I post too much
  Reputation: 92
  Joined: 29 Oct 2010 Posts: 4197
 
  | 
		
			
				 Posted: Fri Apr 29, 2022 12:45 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				Thank you for this.
 
 
I tried changing the application to notepad++. Any way to make it work?
 
 
Thanks. | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Dark Byte Site Admin
  Reputation: 470
  Joined: 09 May 2003 Posts: 25807 Location: The netherlands
  | 
		
			
				 Posted: Fri Apr 29, 2022 1:58 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				How do you intend to signal CE that you're done editing ? Once you have that, it can be implemented instead of using waitforsingleobject _________________
 Do not ask me about online cheats. I don't know any and wont help finding them.
 
 
Like my help? Join me on Patreon so i can keep helping  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		AylinCE Grandmaster Cheater Supreme
  Reputation: 37
  Joined: 16 Feb 2017 Posts: 1530
 
  | 
		
			
				 Posted: Fri Apr 29, 2022 3:44 pm    Post subject:  | 
				        | 
			 
			
				
  | 
			 
			
				Just an idea.
 
1) You can report the end of editing to CE by closing Notepad++. Otherwise Notepad++ should not be open.
 
2) Edit the file path for Notepad++. In my case this code works.
 
3) Notepad or Notepad++ looks plain in my opinion. Color accents are more useful in the original. (Just an opinion.)   
 
4) To avoid unnecessary garbage in the file, I added a code to delete the file when the editing is finished. Otherwise the folder will be filled with many tmps.
 
5) Be sure to save the final version of the edit before closing Notepad++.
 
 
 
 	  | Code: | 	 		  local result1=1
 
 
function LaunchCommandAndWait(command)
 
 local proc=getProcessIDFromProcessName(command)
 
 --print(proc)
 
  if proc==nil then
 
   result1=0
 
   else
 
   result1=1
 
  end
 
 
  return result1
 
end
 
 
local counter=0
 
 
local active={}
 
 
AddressList.OnAutoAssemblerEdit=function(al,mr)
 
 -- print("editing aa script")
 
  if active[mr.ID] then return true end --already editing
 
 
  mr.beginEdit()
 
 -- print("memrec has been marked as editing")
 
  local sl=createStringList()
 
  sl.Text=mr.Script
 
 
  local path
 
  if getTempFolder then
 
    path=getTempFolder()
 
  else
 
    path=getCheatEngineDir()
 
  end
 
  lfs.mkdir(path.."editing-ceaascripts") --assume it works, or it already exists
 
  path=path.."editing-ceaascripts\\"
 
 
  --printf("initial path=%s", path)
 
 
  local ms=createMemoryStream()
 
  ms.size=260
 
  if executeCodeLocalEx("GetTempFileNameA", path,"CEA",0,ms.Memory) ~=0 then
 
    path=readStringLocal(ms.Memory,260)
 
    --printf("final path=%s", path)
 
 
    ms.destroy()
 
 
    --printf("saving script to %s", path)
 
    sl.saveToFile(path)
 
    active[mr.ID]=true
 
 
      local open=shellExecute([[C:\Program Files\Notepad++\notepad++.exe]],shellExecute(path))
 
      sleep(200)
 
 
      if Thread1 then Thread1.Destroy() Thread1=nil end
 
      Thread1=createTimer() Thread1.Interval=3100
 
      Thread1.OnTimer=function()
 
      aa=LaunchCommandAndWait([[notepad++.exe]]) --..path)
 
 
      --print("AA editorthread: Finished waiting")
 
      if aa==0 then
 
       sl.loadFromFile(path)
 
       mr.Script=sl.Text
 
       --print(sl.Text)
 
       mr.endEdit()
 
       sl.destroy()
 
 
       active[mr.ID]=nil
 
       os.remove(path)
 
       Thread1.Enabled=false
 
       return true
 
      end
 
     -- print("done editing")
 
    end
 
    Thread1.Enabled=true
 
  else
 
      if Thread1 then Thread1.Destroy() Thread1=nil end
 
    print("GetTempFileNameA failed")
 
    sl.destroy()
 
    ms.destroy()
 
    return false
 
  end
 
end | 	 
  _________________
  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Csimbi I post too much
  Reputation: 97
  Joined: 14 Jul 2007 Posts: 3327
 
  | 
		
			
				 Posted: Sat Apr 30, 2022 3:42 am    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				| Can these be generalized to support other editors like TextPad, HippoEdit, UltraEdit, etc.? | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		AylinCE Grandmaster Cheater Supreme
  Reputation: 37
  Joined: 16 Feb 2017 Posts: 1530
 
  | 
		
			
				 Posted: Sat Apr 30, 2022 11:10 am    Post subject:  | 
				        | 
			 
			
				
  | 
			 
			
				An example of user editing based on the original topic;
 
 
1) Notepad and Notepad++ added. (You can add more editors)
 
2) Added to the popup menu by right-clicking instead of double-clicking on the script.
 
3) A hotkey is assigned. (Default is Ctrl+E, edit it to your liking)
 
4) Added an annoying Input query. (Option menu for those using multiple editing programs)
 
5) In order to process (Save) the edit, the final version should be saved and the editing program should be closed before exiting the editing program. Otherwise, CE script will not be able to receive commands for content change.
 
 
 
 	  | Code: | 	 		  local result1=1
 
al = getAddressList()
 
pathOrg=getCheatEngineDir()
 
local pathtbl={pathOrg.."editing-ceaascripts"}
 
 
local progtbl={{[[notepad.exe]],[[notepad.exe]]},
 
               {[[C:\Program Files\Notepad++\notepad++.exe]],[[notepad++.exe]]}
 
}
 
 
local pthText=[[Just type the number of titles and confirm:
 
1) Notepad.exe
 
2) Notopad++.exe]]
 
 
function editPath(ePath,editName)
 
  local path = ePath
 
  lfs.mkdir(path) --assume it works, or it already exists
 
  path=path.."\\"..editName..".tmp"
 
    return path
 
end
 
 
function LaunchCommandAndWait(command)
 
 local proc=getProcessList()[tonumber(command)]
 
 --print(proc)
 
  if proc==nil then
 
   result1=0
 
   else
 
   result1=1
 
  end
 
  return result1
 
end
 
 
function EditPad()
 
local mr=AddressList.getSelectedRecord()
 
  --print(mr.Script)
 
local sl=createStringList()
 
sl.Text=mr.Script
 
  --print(mr.Script)
 
local path1=pathtbl[1]
 
path=editPath(path1,mr.Description)
 
--print(path)
 
--printf("initial path=%s", path)
 
 if path then
 
  sl.saveToFile(path)
 
  progIdx=inputQuery('Select Edit Program', pthText, progIdx)
 
  progIdx=tonumber(progIdx)
 
  if progIdx==nil then showMessage("Just type the number!")
 
   else
 
   if progIdx>0 and progIdx<=#progtbl then
 
   if progIdx==1 then
 
    shellExecute(path)
 
    else
 
    prg1=progtbl[progIdx][1]
 
    shellExecute(prg1,shellExecute(path))
 
    --print(progtbl[progIdx][1])
 
   end
 
   sleep(200)
 
   prog1=getForegroundProcess() or getProcessIDFromProcessName(progtbl[progIdx][2])
 
   --print(1,prog1)
 
    if Thread1 then Thread1.Destroy() Thread1=nil end
 
     Thread1=createTimer() Thread1.Interval=1100
 
     Thread1.Enabled=true
 
     Thread1.OnTimer=function()
 
     aa=LaunchCommandAndWait(prog1)
 
 
      if aa==0 then
 
       sl.loadFromFile(path)
 
       mr.Script=sl.Text
 
       sl.destroy()
 
       --print(mr.Script)
 
       os.remove(path)
 
       Thread1.Enabled=false
 
       return true
 
      end
 
     end
 
     end
 
    end
 
  end
 
end
 
 
local mm = al.Parent.PopupMenu
 
if nm==nil then
 
  nm = createMenuItem(mm)
 
  nm.Caption = "Edit Notepad++"
 
  menuItem_setShortcut(nm, "Ctrl+E")
 
  nm.OnClick = EditPad
 
 
  mm.Items.insert(15,nm)
 
end
 
 
if oldOnPopup==nil then
 
  oldOnPopup=mm.OnPopup
 
 
  mm.OnPopup=function(sender)
 
               nm.Visible=al.SelCount>0
 
               oldOnPopup(sender)
 
             end
 
end | 	 
  _________________
  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		++METHOS I post too much
  Reputation: 92
  Joined: 29 Oct 2010 Posts: 4197
 
  | 
		
			
				 Posted: Sat Apr 30, 2022 1:22 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				 	  | Dark Byte wrote: | 	 		  | How do you intend to signal CE that you're done editing ? Once you have that, it can be implemented instead of using waitforsingleobject | 	  -This is over my head. Sorry. I just assumed that it could be done in a similar fasion.
 
 
 	  | AylinCE wrote: | 	 		  | Just an idea. | 	  -This works great. Thank you. | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Csimbi I post too much
  Reputation: 97
  Joined: 14 Jul 2007 Posts: 3327
 
  | 
		
			
				 Posted: Sun May 01, 2022 7:17 am    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				 	  | ++METHOS wrote: | 	 		  
 
 	  | AylinCE wrote: | 	 		  | Just an idea. | 	  -This works great. Thank you. | 	  
 
Yes, this guy knows his s***  
 
Thanks! | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		AylinCE Grandmaster Cheater Supreme
  Reputation: 37
  Joined: 16 Feb 2017 Posts: 1530
 
  | 
		
			
				 Posted: Sun May 01, 2022 8:57 am    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				 	  | Csimbi wrote: | 	 		   	  | ++METHOS wrote: | 	 		  
 
 	  | AylinCE wrote: | 	 		  | Just an idea. | 	  -This works great. Thank you. | 	  
 
Yes, this guy knows his s***  
 
Thanks! | 	  
 
 
Thanks.
 
The appreciation of the masters is priceless.
 
Thanks to @DarkByte for the main idea.
 
 
PS: I still can't write code. Most are memorized.
 
I think my vision is; To bring different ideas to existing codes.
 
I love Lua.       _________________
  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		wzslrb How do I cheat?
  Reputation: 0
  Joined: 10 Feb 2023 Posts: 3
 
  | 
		
			
				 Posted: Thu May 02, 2024 9:30 pm    Post subject: Re: Using notepad as your memoryrecord AA editor | 
				       | 
			 
			
				
  | 
			 
			
				 	  | Code: | 	 		  
 
[ENABLE]
 
{$lua}
 
if syntaxcheck then return end
 
 
local isDebug = false
 
local isDefEditor = false   --设置为默认脚本编辑器
 
local isRecordRightMenu = true  --添加的右键菜单
 
local Waitsaveteim = 3600;  --检测保存间隔
 
local active = {}
 
Editor_Thread_npp2 = nil; --后台检测线程
 
local editor = [[D:\Program Files\npp.8.6.5.portable.x64\notepad++.exe]]
 
local Proc = extractFileName(editor);  --编辑器进程名称
 
--临时目录
 
local tmppath = (getTempFolder and getTempFolder() or (os.getenv('temp')..'\\')).."Cheat Engine";
 
lfs.mkdir(tmppath);   --临时目录
 
local function editPath(id, editName)
 
  return string.format('%s\\%s_%s.lua',tmppath, id, editName)
 
end
 
local function removetmpfile(path)
 
  return deleteFile and deleteFile(path) or os.remove(path) or os.remove(utf8ToAnsi(path))
 
end
 
function removetmpfiles_npp2()
 
  for _,x in pairs (active) do
 
    x.mr.endEdit();
 
    x.mr.OnDestroy = x.oldDestroy;
 
    removetmpfile(x.path);
 
  end
 
  active = {};
 
end
 
local function LaunchCommandAndWait(thr, command)
 
  thr.freeOnTerminate(true)
 
  if isDebug then print('进入后台检测更改...'); end
 
  local sl = createStringList()
 
  while (not thr.Terminated) do
 
    local len = 0
 
    for _,x in pairs (active) do  --ID md5 path
 
      local md5 = md5file(x.path)
 
      if md5 ~= x.md5 then
 
        x.md5 = md5
 
        sl.loadFromFile(x.path)
 
        x.mr.Script = sl.Text
 
        if isDebug then print('保存修改.'..x.mr.getDescription()); end
 
      end
 
      len = len + 1
 
    end
 
    local aa = getProcessIDFromProcessName(Proc);
 
    --if isDebug then print(len, tostring(aa)); end
 
    if len == 0 or aa == nil then break; end
 
    sleep(Waitsaveteim)
 
  end
 
  removetmpfiles_npp2();
 
  if isDebug then print('退出后台检测程序.清除缓存'); end
 
  Editor_Thread_npp2 = nil
 
  sl.Destroy()
 
  thr.Destroy()
 
end
 
local function EditRecord(al, mr)
 
  local sl=createStringList()
 
  sl.Text = mr.Script
 
  local path = editPath(mr.ID, mr.Description)
 
  if not sl.saveToFile(path) then
 
    sl.Destroy()
 
    if isDebug then print('保存临时文件失败'); end
 
   return;
 
  end
 
  sl.destroy()
 
  --createNativeThread(function() runCommand(editor, path); end)
 
  local r = executeCodeLocalEx('ShellExecuteW',{type=0,value=0},{type=4,value='open'},{type=4,value=editor},
 
  {type=4,value='"'..path..'"'},{type=0,value=0},{type=0,value=1});
 
  if isDebug then printf('ShellExecuteW 返回:%s',r); end
 
  if r ~= 42 then
 
    removetmpfile(path);
 
    if isDebug then print('打开编辑器失败'); end
 
    return;
 
  end
 
  if active[mr.ID] == nil then
 
    if isDefEditor then
 
      mr.beginEdit();
 
      if isDebug then print('开始长编辑模式. '..mr.Description); end
 
    end
 
    local oldDestroy = mr.OnDestroy;
 
    active[mr.ID] = {mr = mr, md5 = md5file(path), path = path, oldDestroy = oldDestroy} -- name=mr.Description
 
    function mr:OnDestroy()
 
      removetmpfile(path)
 
      if isDebug then print('[内存记录]已经删除. '..mr.Description); end
 
      active[mr.ID] = nil;
 
      return oldDestroy and oldDestroy()
 
    end
 
  else
 
    active[mr.ID].md5 = md5file(path)
 
    if active[mr.ID].path ~= path then
 
      removetmpfile(active[mr.ID].path);
 
      if isDebug then print('删除旧文件.'..active[mr.ID].path); end
 
      active[mr.ID].path = path;
 
    end
 
  end
 
  Editor_Thread_npp2 = Editor_Thread_npp2 or createNativeThread(LaunchCommandAndWait)
 
end
 
local function EditPad()
 
  local selectedItems = getAddressList().getSelectedRecords();
 
  if (selectedItems) then
 
    for k,memrecord in pairs(selectedItems) do
 
      if (memrecord.Type == vtAutoAssembler) then --自动汇编脚本
 
        createNativeThread(function() EditRecord(AddressList, memrecord); end);
 
      end
 
    end
 
  end
 
end
 
 
--备份原有编辑函数
 
Bak_AutoAssemblerEdit_Func = Bak_AutoAssemblerEdit_Func or getAddressList().OnAutoAssemblerEdit
 
--设置默认编辑器
 
if isDefEditor then
 
  getAddressList().OnAutoAssemblerEdit = EditRecord
 
end
 
local al = getAddressList();
 
if (isRecordRightMenu and al.PopupMenu) then
 
  local popMenu = al.PopupMenu;
 
  local ItemExists = popMenu.open_in_Notepad;
 
  if (ItemExists) then
 
    ItemExists.name = '';
 
    ItemExists.destroy();
 
  end
 
  local Item = createMenuItem(popMenu);
 
  Item.Name = 'open_in_Notepad';
 
  Item.Shortcut = "CTRL+E";
 
  Item.Caption = '打开到 Notepad++';
 
  Item.OnClick = EditPad
 
  local _onpopup = popMenu.OnPopup;
 
  if (_onpopup) then
 
    popMenu.OnPopup = function(sender)
 
      Item.Visible = al.SelCount > 0;
 
      _onpopup(sender);
 
    end
 
  else
 
    popMenu.OnPopup = function(sender)
 
      Item.Visible = al.SelCount > 0;
 
    end
 
  end
 
  popMenu.Items.add(Item);
 
end
 
{$asm}
 
 
[DISABLE]
 
{$lua}
 
if syntaxcheck then return end
 
 
if Editor_Thread_npp2 then
 
  removetmpfiles_npp2()
 
  --print('停止线程');
 
  Editor_Thread_npp2.terminate()
 
  Editor_Thread_npp2 = nil
 
end
 
getAddressList().OnAutoAssemblerEdit = Bak_AutoAssemblerEdit_Func
 
local al = getAddressList();
 
if (al.PopupMenu) then
 
  local popMenu = al.PopupMenu;
 
  local ItemExists = popMenu.open_in_Notepad;
 
  if (ItemExists) then
 
    ItemExists.name = '';
 
    ItemExists.destroy();
 
  end
 
end
 
{$asm}
 
 | 	 
  | 
			 
		  | 
	 
	
		| 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
  | 
   
 
		 |