Функции Cleo+ для Moonloader

Mothman

Новичок
Автор темы
2
0
Версия MoonLoader
.026-beta
Понимаю, что крайне редкая проблема, ибо касается по большей части одиночной игры, но:
Как я понимаю, в отличии от newOpcodes в MoonAdditions никто не переносил функционал Cleo+ как библиотеку, а так как у меня с С++ слабо, даже имея исходники данной библиотеки для Cleo шансы сделать с него lua-библиотеку крайне малы. В связи с этим у меня родилась странная идея, но, возможно, кто-то так уже делал: возможно ли вызывать каким-то образом сторонние cleo опкоды, например, через ffi с указанием параметров?

UPD: Я нашёл вот такое:

Lua:
local ffi = require 'ffi'
local memory = require 'memory'

ffi.cdef[[
struct CRunningScript {
  struct CRunningScript *m_pNext;
  struct CRunningScript *m_pPrev;
  char m_szName[8];
  unsigned char *m_pBaseIP;
  unsigned char *m_pCurrentIP;
  unsigned char *m_apStack[8];
  unsigned short m_nSP;
  char _pad3A[2];
  int m_aLocalVars[32];
  int m_anTimers[2];
  unsigned char m_bIsActive;
  unsigned char m_bCondResult;
  unsigned char m_bUseMissionCleanup;
  unsigned char m_bIsExternal;
  unsigned char m_bTextBlockOverride;
  char m_externalType;
  char field_CA[2];
  int m_nWakeTime;
  unsigned short m_nLogicalOp;
  unsigned char m_bNotFlag;
  unsigned char m_bWastedBustedCheck;
  unsigned char m_bWastedOrBusted;
  char _padD5[3];
  void *m_pSceneSkipIP;
  unsigned char m_bIsMission;
  char _padDD[3];
};
]]

local gst_mt = {}
gst_mt.__index = gst_mt

function gst_mt:writeInteger(pos, val)
    self.buf[pos] = 1
    pos = pos + 1
    ffi.cast('int*', self.buf + pos)[0] = val
    pos = pos + 4

    return pos
end

function gst_mt:writeFloat(pos, val)
    self.buf[pos] = 6
    pos = pos + 1
    ffi.cast('float*', self.buf + pos)[0] = val
    pos = pos + 4

    return pos
end

function gst_mt:writeVariable(pos, val)
    self.buf[pos] = 3
    pos = pos + 1
    local idx = #paramvars
    self.paramvars[idx] = val
    self.gst[0].m_aLocalVars[idx] = ffi.cast('int*', val)[0]
    ffi.cast('short*', self.buf + pos)[0] = idx
    pos = pos + 2

    return pos
end

function gst_mt:writeString(pos, val)
    self.buf[pos] = 14
    pos = pos + 1
    ffi.cast('unsigned char*', self.buf + pos)[0] = val:len()
    ffi.copy(self.buf + pos + 1, val)
    pos = pos + 1 + val:len()

    return pos
end

function gst_mt:writeZero(pos)
    self.buf[pos] = 0
    pos = pos + 1

    return pos
end

local CRunningScript__ProcessOneCommand = ffi.cast('void(__thiscall*)(struct CRunningScript*)', 0x469EB0)
function gst_mt:execute()
    -- memory.setuint16(0x469EF5, 0xD2FF) -- only for samp

    self.gst[0].m_pCurrentIP = self.buf
    CRunningScript__ProcessOneCommand(self.gst)

    for i, k in ipairs(self.paramvars) do
        ffi.cast('int*', k)[0] = self.gst[0].m_aLocalVars[i]
    end

    -- memory.setuint16(0x469EF5, 0xD08B) -- only for samp
end

local function new_gst()
    local gst = ffi.new('struct CRunningScript[1]', {})
    local buf = ffi.new('unsigned char[255]', {0})

    return setmetatable({ gst = gst, buf = buf, paramvars = {} }, gst_mt)
end

local gst = new_gst()
local function callOpcode(opcode, ...)
    local bufpos = 2
    ffi.cast('short*', gst.buf)[0] = opcode

    for i = 1, select('#', ...) do
        local v = select(i, ...)
        if v[2] == 'i' then bufpos = gst:writeInteger(bufpos, v[1])
        elseif v[2] == 'f' then bufpos = gst:writeFloat(bufpos, v[1])
        elseif v[2] == 'v' then bufpos = gst:writeVariable(bufpos, v[1])
        elseif v[2] == 's' then bufpos = gst:writeString(bufpos, v[1])
        elseif v[2] == 'z' then bufpos = gst:writeZero(bufpos, v[1]) end
    end

    gst:execute()
end

function main()
    while true do wait(0)
        if testCheat("TEST") then
            print('running...')
            callOpcode(0x00A1, { PLAYER_PED, 'i' }, { 0, 'f' }, { 0, 'f' }, { 0, 'f' })
        end
    end
end

И оно прекрасно работает с стандартными опкодами San Andreas, но cleo+ сразу крашит, есть ли возможность это исправить? И к тому же, возможно ли добавить выведение значений, что возвращает опкод?

Думаю, это рано или поздно кому-то пригодится кроме меня, используя тот большой набор функций, включая тот же рендер объектов
 
Последнее редактирование: