<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="45">
  <CheatEntries>
    <CheatEntry>
      <ID>700</ID>
      <Description>"Cell to Singularity — Debug Console v7 (Cheat Engine 7.5)"</Description>
      <GroupHeader>1</GroupHeader>
      <CheatEntries>
        <CheatEntry>
          <ID>701</ID>
          <Description>"ENABLE AND OPEN DEBUG CONSOLE — keep checked"</Description>
          <Color>008000</Color>
          <VariableType>Auto Assembler Script</VariableType>
          <AssemblerScript>[ENABLE]
{$lua}
if syntaxcheck then return end

if process ~= 'CellToSingularity.exe' or not readInteger(process) then
  error('Attach Cheat Engine to CellToSingularity.exe first')
end

if not monopipe then
  local result = LaunchMonoDataCollector()
  if not result or result == 0 then
    error('Unable to activate Mono features')
  end
end

local function resolveMethod(className, methodName)
  local method = mono_findMethod('', className, methodName)
  if not method or method == 0 then
    error(className .. ':' .. methodName .. ' not found')
  end

  local address = mono_compile_method(method)
  if not address or address == 0 then
    error('Unable to compile ' .. className .. ':' .. methodName)
  end

  return method, address
end

local function readByteList(address, count)
  local bytes = {}
  for i = 0, count - 1 do
    bytes[#bytes + 1] = readBytes(address + i, 1, false)
  end
  return bytes
end

local function restoreByteList(address, bytes)
  if not address or not bytes then return end
  for i = 1, #bytes do
    writeBytes(address + i - 1, bytes[i])
  end
end

local checkMethod, checkAddress = resolveMethod('DebugController', 'CheckDebugMode')
local tryMethod, tryAddress = resolveMethod('DebugController', 'TryDisableAll')
local turnOffMethod, turnOffAddress = resolveMethod('DebugController', 'TurnOffDebug')
local showMethod, showAddress = resolveMethod('DebugController', 'ShowDebugUI')

_G.CTS_DebugConsoleV7 = {
  patches = {
    { address = checkAddress, original = readByteList(checkAddress, 3) },
    { address = tryAddress, original = readByteList(tryAddress, 1) },
    { address = turnOffAddress, original = readByteList(turnOffAddress, 1) }
  }
}

-- CheckDebugMode => true
writeBytes(checkAddress, 0xB0, 0x01, 0xC3)

-- Prevent the game from hiding or closing the interface while enabled.
writeBytes(tryAddress, 0xC3)
writeBytes(turnOffAddress, 0xC3)

local invoked = false
local invokeError = nil

-- Proper Mono invocation of the static ShowDebugUI method.
if mono_invoke_method then
  local ok, result = pcall(function()
    local domains = mono_enumDomains and mono_enumDomains() or nil
    local domain = nil
    if type(domains) == 'table' and #domains &gt; 0 then
      domain = domains[1]
    end
    return mono_invoke_method(domain, showMethod, nil, {})
  end)

  if ok then
    invoked = true
  else
    invokeError = tostring(result)
  end
end

-- Fallback for Cheat Engine 7.5 if mono_invoke_method is unavailable.
if not invoked then
  local ok, threadOrError = pcall(function()
    return createThread(showAddress)
  end)
  if ok and threadOrError then
    invoked = true
  else
    invokeError = tostring(threadOrError or invokeError)
  end
end

if not invoked then
  error('The patches were applied, but ShowDebugUI could not be invoked: ' .. tostring(invokeError))
end

beep()
showMessage(
  'Command sent.\n\n'
  .. 'Keep this entry checked.\n'
  .. 'Close and reopen the game menu from the top-right hamburger button if the debug console does not appear immediately.\n\n'
  .. 'To restore normal behavior, simply uncheck this entry.'
)
{$asm}

[DISABLE]
{$lua}
if syntaxcheck then return end

local state = _G.CTS_DebugConsoleV7
if state and state.patches then
  for i = #state.patches, 1, -1 do
    restoreByteList(state.patches[i].address, state.patches[i].original)
  end
end

_G.CTS_DebugConsoleV7 = nil
beep()
{$asm}
</AssemblerScript>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
  <UserdefinedSymbols/>
  <Comments>Version 7 — Cheat Engine 7.5.

Une seule ligne a utiliser :
ENABLE AND OPEN DEBUG CONSOLE — keep checked

Cette version :
- n ouvre aucun dossier Windows ;
- force CheckDebugMode a vrai ;
- bloque temporairement TryDisableAll et TurnOffDebug ;
- appelle directement DebugController:ShowDebugUI ;
- restaure les octets originaux quand la ligne est décochee.

Ne pas utiliser simultanement une ancienne version de la table.</Comments>
</CheatTable>
