Update 3
Launch Game Autorun Files Version 1.02
Added a 'Launch Game' button on the main form of cheat engine. This is useful when opening the table after opening cheat engine, or when game has been closed or crashed and you want to launch it again.
Update 2
Launch Game Autorun Files Version 1.01
I've added a clever trick to make the script compatible with tables that overwrite the onOpenProcess() function. Also fixed a typo that doesn't change any functionality. Basically, when the main form loads, the script stores the old onOpenProcess in another variable, overwrites the onOpenProcess with it's own, then changes it back when it's done.
Update 1
Launch Game Autorun Files Version 1.0
I've rewritten the script to directly read and write necessary data in the .ct file instead of using extra memory records that pollute the table. There's also many new features:
- Launch Game
- Launch With Advanced Options (parameters, debug and BreakOnEntry)
- Ask whether to launch or not when an instance already exists. If not it only attaches to the process. If yes it doesn't attach as there's more than 1 process with same name.
- Advanced Options are saved between sessions so long as the cheat table is also saved.
The code:
Code: Select all
--[[
**************************************
Launch Game Autorun Files Version 1.02
**************************************
--]]
-- Constants
local metadata_name = 'launchgame.dat'
-- Globals
launch_command = {'', '', ' ', false, false}
-- Functions
local launch_gui
local launch_options_gui
local get_path
local write_metadata
local read_metadata
local launch_game
local original_onOpenProcess = onOpenProcess
local custom_onOpenProcess
local create_launch_menu_item
-- [1] = Process Name
-- [2] = Path
-- [3] = Parameters
-- [4] = Debug
-- [5] = BreakOnEntry
launch_gui = function()
read_metadata()
if #launch_command[1] > 0 and #launch_command[2] > 0 then
local message = string.format('Launch %s?', launch_command[1])
local response = messageDialog(message, mtConfirmation, mbYes, mbNo)
if response == mrYes then
launch_options_gui()
end
else
return 1
end
return 0
end
launch_options_gui = function()
local form = createForm()
form.Caption = "Launch Options"
form.Width = 400
form.Height = 150
form.centerScreen()
form.show()
local y = 10
local params_label = createLabel(form)
params_label.Caption = 'Parameters'
params_label.setPosition(10, y)
y = y + 20
local params_input = createEdit(form)
params_input.setPosition(10, y)
params_input.Width = form.Width - 20
if #launch_command[3] > 0 then
params_input.Text = launch_command[3]
end
y = y + 20
local checkBoxes = {};
checkBoxes[1] = createCheckBox( form );
checkBoxes[2] = createCheckBox( form );
local checkbox_captions = {'Debug', 'BreakOnEntry'}
for x = 1, #checkBoxes do
checkBoxes[x].AllowGrayed = false
checkBoxes[x].Caption = checkbox_captions[x]
checkBoxes[x].setPosition(10, y + x * 20)
if launch_command[3 + x] == true then
checkBoxes[x].State = 1
else
checkBoxes[x].State = 0
end
end
y = y + 20 * #checkBoxes
local launch_button = createButton(form)
launch_button.Caption = 'Launch'
launch_button.Width = 60
launch_button.setPosition((form.Width - launch_button.Width)/2,
form.Height - launch_button.Height)
launch_button.onClick = function()
if #params_input.Text > 0 then
launch_command[3] = params_input.Text
else
launch_command[3] = ' '
end
launch_command[4] = checkBoxes[1].Checked
launch_command[5] = checkBoxes[2].Checked
form.destroy()
launch_game()
end
end
create_launch_menu_item = function()
if not has_launch_menu then
local myMenu = createMenuItem(getMainForm())
myMenu.Caption = "Launch Game"
myMenu.onClick = function()
synchronize(function()
local err = launch_gui()
if err ~= 0 then
local str = 'Note: You need to launch game and attach process manually at least once for it to work.'
local message = string.format('Error: unable to launch\nprocess = <%s>\npath = <%s>\n\n%s',
launch_command[1], launch_command[2], str)
showMessage(message)
end
end)
end
getMainForm().Menu.Items.add(myMenu)
has_launch_menu = true
end
end
get_path = function(pid)
local modules = enumModules(pid)
if modules and #modules > 0 then
return modules[1].PathToFile
end
return ''
end
write_metadata = function()
local table_file = findTableFile(metadata_name)
local metadata = ""
for i = 1, #launch_command do
local str = tostring(launch_command[i])
metadata = metadata .. str .. '\n'
end
if not table_file then
table_file = createTableFile(metadata_name)
end
table_file.getData().clear()
table_file.getData().writeString(metadata)
end
read_metadata = function()
-- Original function taken from the wiki:
-- https://wiki.cheatengine.org/index.php?title=Lua:Class:TableFile
local fileStr = nil
local tableFile = findTableFile(metadata_name)
if tableFile ~= nil then
local stringStream = createStringStream()
stringStream.Position = 0 -- if not set before using 'copyFrom' the 'StringStream' object will be inconsistent.
stringStream.copyFrom(tableFile.Stream, tableFile.Stream.Size)
fileStr = stringStream.DataString
stringStream.destroy()
local i = 1
for line in string.gmatch(fileStr, "[^\n]+") do
if i <= 3 then
launch_command[i] = line
elseif line == 'false' then
launch_command[i] = false
elseif line == 'true' then
launch_command[i] = true
end
i = i + 1
end
end
end
launch_game = function()
local process_name = launch_command[1]
if getProcessIDFromProcessName(process_name) then
local message = string.format('%s is already running. Do you want to launch it anyways?', process_name)
local response = messageDialog(message, mtConfirmation, mbYes, mbNo)
if response == mrNo then
openProcess(process_name)
else
createProcess(launch_command[2], launch_command[3], launch_command[4], launch_command[5])
sleep(2000)
end
else
createProcess(launch_command[2], launch_command[3], launch_command[4], launch_command[5])
sleep(2000)
openProcess(process_name)
end
end
custom_onOpenProcess = function(processId)
launch_command[1] = process
launch_command[2] = get_path(processId)
write_metadata()
if original_onOpenProcess then
onOpenProcess = original_onOpenProcess
end
end
createThread(function()
synchronize(create_launch_menu_item())
while (getMainForm() == nil) or (not getMainForm().Visible) do
sleep(1000)
end
synchronize(function()
original_onOpenProcess = onOpenProcess
onOpenProcess = custom_onOpenProcess
launch_gui()
end)
end)
Some Images:
old post
Since I'm too lazy to manually click to open cheat engine, launch the game, minimize the game, attach cheat engine to process, activate cheats, go back to game, I've decided to automate all that. After wasting time messing around with reg query to get game's exe file path from registry, I've realized I was severely over complicating stuff. Thus I came up with a simple script that should work in every game, allowing you to automatically launch the game when you open the cheat table. My knowledge of Lua is still very superficial, and I'm learning as I go, thus it's likely there are many areas where the script could be improved.
A quick explanation of what happens:
1) The first time the table is opened, nothing happens until the user attaches cheat engine to the game's process.
2) When a process is attached, onOpenProcess is executed, saving the game's file path and process name in the addresses of new memory records.
3) When the cheat table is opened again, it prompts the user if they want to launch the game.
4) Using the saved file's path and process name, and createProcess of course, cheat engine launches the game and attaches to the process.
5) After that you can create a favorite group of scripts that are automatically enabled, meaning you never have to minimize the game.Code: Select all
local path_record = AddressList.getMemoryRecordByDescription('GAME PATH') local name_record = AddressList.getMemoryRecordByDescription('PROCESS NAME') local parent = AddressList.getMemoryRecordByDescription('START') function launch_game(path, process_name) if not path then return 2 end createProcess(path) getMainForm().WindowState = 'wsMinimized' sleep(1000) local pid = getProcessIDFromProcessName(process_name) if pid then openProcess(pid) else return 1 end return 0 end local function get_path(pid) local modules = enumModules(pid) if modules and #modules > 0 then return modules[1].PathToFile end return nil end function onOpenProcess(processId) if not parent then parent = AddressList.createMemoryRecord() parent.Description = 'START' parent.IsGroupHeader = true parent.Options = '[moHideChildren]' end if not path_record then path_record = AddressList.createMemoryRecord() path_record.Description = 'GAME PATH' path_record.appendToEntry(parent) end path_record.Address = get_path(processId) if not name_record then name_record = AddressList.createMemoryRecord() name_record.Description = 'PROCESS NAME' name_record.appendToEntry(parent) end name_record.Address = process end if path_record and name_record then local response = messageDialog("Launch Game?", mtConfirmation, mbYes, mbNo) if response == mrYes then local game_path = path_record.Address local game_process = name_record.Address if launch_game(game_path, game_process) ~= 0 then showMessage('Failed to launch game') end end end
