Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Using notepad as your memoryrecord AA editor

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Extensions
View previous topic :: View next topic  
Author Message
Dark Byte
Site Admin
Reputation: 465

Joined: 09 May 2003
Posts: 25570
Location: The netherlands

PostPosted: Fri Apr 29, 2022 9:44 am    Post subject: Using notepad as your memoryrecord AA editor This post has 1 review(s) Reply with quote

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
View user's profile Send private message MSN Messenger
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Fri Apr 29, 2022 12:45 pm    Post subject: Reply with quote

Thank you for this.

I tried changing the application to notepad++. Any way to make it work?

Thanks.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 465

Joined: 09 May 2003
Posts: 25570
Location: The netherlands

PostPosted: Fri Apr 29, 2022 1:58 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
AylinCE
Grandmaster Cheater Supreme
Reputation: 34

Joined: 16 Feb 2017
Posts: 1432

PostPosted: Fri Apr 29, 2022 3:44 pm    Post subject: This post has 1 review(s) Reply with quote

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.) Wink
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

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Csimbi
I post too much
Reputation: 97

Joined: 14 Jul 2007
Posts: 3229

PostPosted: Sat Apr 30, 2022 3:42 am    Post subject: Reply with quote

Can these be generalized to support other editors like TextPad, HippoEdit, UltraEdit, etc.?
Back to top
View user's profile Send private message
AylinCE
Grandmaster Cheater Supreme
Reputation: 34

Joined: 16 Feb 2017
Posts: 1432

PostPosted: Sat Apr 30, 2022 11:10 am    Post subject: This post has 1 review(s) Reply with quote

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



Ek1.PNG
 Description:
 Filesize:  77.95 KB
 Viewed:  23539 Time(s)

Ek1.PNG



_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Sat Apr 30, 2022 1:22 pm    Post subject: Reply with quote

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
View user's profile Send private message
Csimbi
I post too much
Reputation: 97

Joined: 14 Jul 2007
Posts: 3229

PostPosted: Sun May 01, 2022 7:17 am    Post subject: Reply with quote

++METHOS wrote:

AylinCE wrote:
Just an idea.
-This works great. Thank you.

Yes, this guy knows his s*** Very Happy
Thanks!
Back to top
View user's profile Send private message
AylinCE
Grandmaster Cheater Supreme
Reputation: 34

Joined: 16 Feb 2017
Posts: 1432

PostPosted: Sun May 01, 2022 8:57 am    Post subject: Reply with quote

Csimbi wrote:
++METHOS wrote:

AylinCE wrote:
Just an idea.
-This works great. Thank you.

Yes, this guy knows his s*** Very Happy
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. Twisted Evil Smile

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
wzslrb
How do I cheat?
Reputation: 0

Joined: 10 Feb 2023
Posts: 3

PostPosted: Thu May 02, 2024 9:30 pm    Post subject: Re: Using notepad as your memoryrecord AA editor Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Extensions All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites