Not even one is here every day, have some patience. And the more advanced the question the more time you need to wait for the right person to see it.
As far as saving goes, how are you doing it now. CE does save the last value, but it doesn't load it. You could parse the XML file and use that, or write some Lua to save the values and reload them.
Here is a Lua module I use to save and load which scripts are active, and I set the defaults in the scripts them selves. But you could add some code to save/load values as well.
Code: Select all
local NAME = 'I2 Cheat Engine Table State'
local CLASS_NAME = 'I2CETState'
local VERSION = '1.0.3'
local AUTHOR = 'Matt Irwin'
local LICENSE = [=[MIT License
Copyright (c) 2017 Matt Irwin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]=]
local format = string.format
local strE = string.empty or STRING_EMPTY or ''
local t = translate
if MainForm == nil then
MainForm = getMainForm()
end
if AddressList == nil then
AddressList = getAddressList()
end
I2CETState = {
Name = NAME,
ClassName = CLASS_NAME,
Version = VERSION,
Author = AUTHOR,
License = LICENSE,
DefaultState = 'default',
SaveFileName = 'I2CETState.${StateName}.txt',
UseMemoryRecordDescriptions = false,
LineEnd = '\n',
DisableBeforeLoad = true,
PrintStatus = false, --true,
}
-- local Logger = {
-- LEVELS = {
-- OFF = 0,
-- FATAL = 1,
-- ERROR = 2,
-- WARN = 3,
-- INFO = 4,
-- DEBUG = 5,
-- TRACE = 6
-- },
-- }
-- for k, v in pairs(Logger.LEVELS) do
-- -- Logger[k:lower()] = function( ... ) return end
-- -- Logger[k:lower() .. 'f'] = function( ... ) return end
-- Logger[k:lower()] = function(msg, ex) return print(msg, ex) end
-- Logger[k:lower() .. 'f'] = function(msg, ... ) return print(string.format(msg, ... )) end
-- end
local Logger = Logger
if Logger == nil then
if type(CETrequire) == 'function' then
Logger = CETrequire('I2CETLogger')
else
Logger = require('I2CETLogger')
end
Logger.LogName = 'CETstate'
end
if type(CETrequire) == 'function' then
I2CEHelpers = CETrequire('I2CEHelpers')
else
I2CEHelpers = require('I2CEHelpers')
end
local function split(s, delimiter)
return I2CEHelpers.split(s, delimiter)
end
local function interp(s, tbl)
return I2CEHelpers.interp(s, tbl)
end
function I2CETState.saveTableState(stateName)
Logger.trace()
if not inMainThread() then
return I2CETState.saveTableStateT(stateName)
end
local le = I2CETState.LineEnd
if stateName == nil then
stateName = I2CETState.DefaultState
end
local fileName = interp(I2CETState.SaveFileName, { StateName = stateName } )
local fileStr = strE
for i = 0, AddressList.Count - 1 do
local mr = AddressList.getMemoryRecord(i)
if mr.Description ~= '_[ I2CETState ]_'
and mr.Description ~= '_[ Save Table State ]_'
and mr.Description ~= '_[ Load Table State ]_'
and mr.Description:sub(0, 16) ~= 'Load Table State'
and mr.Description:sub(0, 16) ~= 'Save Table State' then
if mr.Active then
local id = tostring(mr.ID)
if I2CETState.UseMemoryRecordDescriptions then
id = mr.Description
end
fileStr = fileStr .. id .. le
end
end
end
local f, err = io.open(fileName, 'w')
if err then
Logger.errorf('The file could not be opened, "%s", %s', fileName, err)
elseif f and not err then
f:write(fileStr)
f:close()
end
end
local function saveTableStateThread_logError(thread, fileName, err)
Logger.errorf('The file could not be opened, "%s", %s', fileName, err)
checkSynchronize()
thread.terminate()
end
local function saveTableStateThread(thread, stateName)
local le = I2CETState.LineEnd
if stateName == nil then
stateName = I2CETState.DefaultState
end
local fileName = interp(I2CETState.SaveFileName, { StateName = stateName } )
local fileStr = strE
for i = 0, AddressList.Count - 1 do
local mr = AddressList.getMemoryRecord(i)
if mr.Description ~= '_[ I2CETState ]_'
and mr.Description ~= '_[ Save Table State ]_'
and mr.Description ~= '_[ Load Table State ]_'
and mr.Description:sub(0, 16) ~= 'Load Table State'
and mr.Description:sub(0, 16) ~= 'Save Table State' then
if mr.Active then
local id = tostring(mr.ID)
if I2CETState.UseMemoryRecordDescriptions then
id = mr.Description
end
fileStr = fileStr .. id .. le
end
end
end
local f, err = io.open(fileName, 'w')
if err then
synchronize(saveTableStateThread_logError, fileName, err)
elseif f and not err then
f:write(fileStr)
f:close()
end
thread.terminate()
end
function I2CETState.saveTableStateT(stateName)
Logger.trace()
createThread(saveTableStateThread, stateName)
end
function I2CETState.loadTableState(stateName)
Logger.trace()
if not inMainThread() then
return I2CETState.loadTableStateT(stateName)
end
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
getLuaEngine().show()
end
local le = I2CETState.LineEnd
if stateName == nil then
stateName = I2CETState.DefaultState
end
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
print(format('Setting Table State: %s', stateName))
end
local fileName = interp(I2CETState.SaveFileName, { StateName = stateName } )
Logger.debugf('Using state file name: "%s"', fileName)
local fileStr = nil
local f, err = io.open(fileName, 'r')
if err then
Logger.infof('The local file could not be opened, "%s", %s', fileName, err)
local tableFile = findTableFile(fileName)
if tableFile == nil then
Logger.warnf('file not found, "%s"', fileName)
return
end
local stream = tableFile.getData()
local bytes = stream.read(stream.Size)
for i = 1, #bytes do
if fileStr == nil then
fileStr = strE
end
fileStr = fileStr .. string.char(bytes[i])
end
elseif f and not err then
fileStr = f:read('*all')
f:close()
else
Logger.errorf('The file could not be opened, "%s"', fileName)
end
if I2CETState.DisableBeforeLoad then
for i = AddressList.Count - 1, 0, -1 do
local mr = AddressList.getMemoryRecord(i)
if mr.Description ~= '_[ I2CETState ]_'
and mr.Description ~= '_[ Save Table State ]_'
and mr.Description ~= '_[ Load Table State ]_'
and mr.Description:sub(0, 16) ~= 'Load Table State'
and mr.Description:sub(0, 16) ~= 'Save Table State' then
if mr.Active then
Logger.infof('Disabling memory record: %d, %d, "%s"', mr.Index, mr.ID, mr.Description)
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
print(format('Disabling: %s', mr.Description))
end
mr.Active = false
while mr.Async and mr.AsyncProcessing do
checkSynchronize()
end
sleep(0)
end
end
end
sleep(0)
end
if fileStr == nil then
Logger.info('File string was nil')
return
end
local lines = split(fileStr, I2CETState.LineEnd)
for i, v in ipairs(lines) do
if v ~= nil and v ~= strE then
local mr = nil
if I2CETState.UseMemoryRecordDescriptions then
mr = AddressList.getMemoryRecordByDescription(v)
else
mr = AddressList.getMemoryRecordByID(tonumber(v))
end
if mr ~= nil then
if not mr.Active then
Logger.infof('Enabling memory record: %d, %d, "%s"', mr.Index, mr.ID, mr.Description)
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
print(format('Enabling: %s', mr.Description))
end
mr.Active = true
while mr.Async and mr.AsyncProcessing do
checkSynchronize()
end
sleep(0)
end
end
end
end
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
print(format('Table State Set: %s', stateName))
getLuaEngine().hide()
end
end
local function loadTableStateThreadSynced(thread, stateName)
Logger.trace()
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
getLuaEngine().show()
end
local le = I2CETState.LineEnd
if stateName == nil then
stateName = I2CETState.CurrentStateName or I2CETState.DefaultState
end
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
print(format('Setting Table State: %s', stateName))
end
local fileName = interp(I2CETState.SaveFileName, { StateName = stateName } )
Logger.debugf('Using state file name: "%s"', fileName)
local fileStr = nil
local f, err = io.open(fileName, 'r')
if err then
Logger.infof('The local file could not be opened, "%s", %s', fileName, err)
local tableFile = findTableFile(fileName)
if tableFile == nil then
Logger.warnf('file not found, "%s"', fileName)
return
end
local stream = tableFile.getData()
local bytes = stream.read(stream.Size)
for i = 1, #bytes do
if fileStr == nil then
fileStr = strE
end
fileStr = fileStr .. string.char(bytes[i])
end
elseif f and not err then
fileStr = f:read('*all')
f:close()
else
Logger.errorf('The file could not be opened, "%s"', fileName)
end
if I2CETState.DisableBeforeLoad then
for i = AddressList.Count - 1, 0, -1 do
local mr = AddressList.getMemoryRecord(i)
if mr.Description ~= '_[ I2CETState ]_'
and mr.Description ~= '_[ Save Table State ]_'
and mr.Description ~= '_[ Load Table State ]_'
and mr.Description:sub(0, 16) ~= 'Load Table State'
and mr.Description:sub(0, 16) ~= 'Save Table State' then
if mr.Active then
Logger.infof('Disabling memory record: %d, %d, "%s"', mr.Index, mr.ID, mr.Description)
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
print(format('Disabling: %s', mr.Description))
end
mr.Active = false
AddressList.setSelectedRecord(mr)
while mr.Async and mr.AsyncProcessing do
checkSynchronize()
MainForm.repaint()
sleep(0)
end
sleep(0)
end
end
end
sleep(0)
end
if fileStr == nil then
Logger.info('File string was nil')
return
end
local lines = split(fileStr, I2CETState.LineEnd)
for i, v in ipairs(lines) do
if v ~= nil and v ~= strE then
local mr = nil
if I2CETState.UseMemoryRecordDescriptions then
mr = AddressList.getMemoryRecordByDescription(v)
else
mr = AddressList.getMemoryRecordByID(tonumber(v))
end
if mr ~= nil then
if not mr.Active then
Logger.infof('Enabling memory record: %d, %d, "%s"', mr.Index, mr.ID, mr.Description)
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
print(format('Enabling: %s', mr.Description))
end
mr.Active = true
AddressList.setSelectedRecord(mr)
while mr.Async and mr.AsyncProcessing do
checkSynchronize()
MainForm.repaint()
sleep(0)
end
sleep(0)
end
end
end
end
if I2CETState.PrintStatus and Logger.Level <= Logger.LEVELS.WARN then
print(format('Table State Set: %s', stateName))
getLuaEngine().hide()
end
I2CETState.CurrentStateName = nil
checkSynchronize()
if thread ~= nil and type(thread.terminate) == 'function' then
thread.terminate()
end
end
local function loadTableStateThread(thread, stateName)
synchronize(loadTableStateThreadSynced, stateName)
thread.terminate()
end
function I2CETState.loadTableStateT(stateName)
Logger.trace()
I2CETState.CurrentStateName = stateName
createThread(loadTableStateThread, stateName)
end
function I2CETState.setAllScriptsToAsync()
Logger.trace()
for i = 0, AddressList.Count - 1 do
local mr = AddressList.getMemoryRecord(i)
if mr.Type == vtAutoAssembler and not mr.Async then
Logger.infof('Set memory record async: %d, %d, "%s"', mr.Index, mr.ID, mr.Description)
mr.Async = true
end
end
end
function I2CETState.setAllScriptsToNoAsync()
Logger.trace()
for i = 0, AddressList.Count - 1 do
local mr = AddressList.getMemoryRecord(i)
if mr.Type == vtAutoAssembler and mr.Async then
Logger.infof('Set memory record no async: %d, %d, "%s"', mr.Index, mr.ID, mr.Description)
mr.Async = false
end
end
end
return I2CETState