Полезные сниппеты и функции

why ega

РП игрок
Модератор
2,539
2,231
Описание: Насилуем CLEO второй раз за сутки. Функция регистрирует cleo опкод
Код:
Lua:
local ffi = require("ffi")



ffi.cdef[[
    int __stdcall CLEO_RegisterOpcode(int a1, int a2);
]]



function registerCleoOpcode(opcode, callback)
    local cleo = ffi.load("CLEO.asi")
    if cleo then
        jit.off(callback)
        local pCallback = tonumber(ffi.cast("uintptr_t", ffi.cast("int(__stdcall*)(void *CScriptThread)", callback)))
        return cleo.CLEO_RegisterOpcode(opcode, pCallback)
    end
end
Пример использования:
Lua:
local ffi = require("ffi")



ffi.cdef[[
    int __stdcall CLEO_RegisterOpcode(int a1, int a2);
]]



function main()
    while not isSampAvailable() do wait(0) end

    print(registerCleoOpcode(0x551B1, function()
        print("hello22")
    end))

    wait(-1)
end



function registerCleoOpcode(opcode, callback)
    local cleo = ffi.load("CLEO.asi")
    jit.off(callback)
    local pCallback = tonumber(ffi.cast("uintptr_t", ffi.cast("int(__stdcall*)(void *CScriptThread)", callback)))
    if cleo then return cleo.CLEO_RegisterOpcode(opcode, pCallback) end
end
 
Последнее редактирование:

g305noobo

Известный
209
176
Описание: Перехват и сохранение серверных текстдравов в удобном формате для их эмуляции
привет тем кто это читает:
local textdrawID_list = {}

function isTextDrawIDInArray(textdrawID, array)
    for _, id in ipairs(array) do
        if id == textdrawID then
            return true
        end
    end
    return false
end

function onReceiveRpc(id, bs)
    if id == 134 then
        local wTextDrawID = raknetBitStreamReadInt16(bs)
        local Flags = raknetBitStreamReadInt8(bs)
        local fLetterWidth = raknetBitStreamReadFloat(bs)
        local fLetterHeight = raknetBitStreamReadFloat(bs)
        local dLetterColor = raknetBitStreamReadInt32(bs)
        local fLineWidth = raknetBitStreamReadFloat(bs)
        local fLineHeight = raknetBitStreamReadFloat(bs)
        local dBoxColor = raknetBitStreamReadInt32(bs)
        local Shadow = raknetBitStreamReadInt8(bs)
        local Outline = raknetBitStreamReadInt8(bs)
        local dBackgroundColor = raknetBitStreamReadInt32(bs)
        local Style = raknetBitStreamReadInt8(bs)
        local Selectable = raknetBitStreamReadInt8(bs)
        local fX = raknetBitStreamReadFloat(bs)
        local fY = raknetBitStreamReadFloat(bs)
        local wModelID = raknetBitStreamReadInt16(bs)
        local fRotX = raknetBitStreamReadFloat(bs)
        local fRotY = raknetBitStreamReadFloat(bs)
        local fRotZ = raknetBitStreamReadFloat(bs)
        local fZoom = raknetBitStreamReadFloat(bs)
        local wColor1 = raknetBitStreamReadInt16(bs)
        local wColor2 = raknetBitStreamReadInt16(bs)
        local szTextLen = raknetBitStreamReadInt16(bs)
        local szText = raknetBitStreamReadString(bs, szTextLen)
        if isTextDrawIDInArray(wTextDrawID, textdrawID_list) then
            local file = io.open(getWorkingDirectory() .. "\\textdraw_rpc.txt", "a")
            if file then
                file:write("--------------------------------\n")
                file:write("bs = raknetNewBitStream()\n")
                file:write("raknetBitStreamWriteInt16(bs, " .. wTextDrawID .. ")\n")
                file:write("raknetBitStreamWriteInt8(bs, " .. Flags .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. string.format("%.12f", fLetterWidth) .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. string.format("%.12f", fLetterHeight) .. ")\n")
                file:write("raknetBitStreamWriteInt32(bs, " .. dLetterColor .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. fLineWidth .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. fLineHeight .. ")\n")
                file:write("raknetBitStreamWriteInt32(bs, " .. dBoxColor .. ")\n")
                file:write("raknetBitStreamWriteInt8(bs, " .. Shadow .. ")\n")
                file:write("raknetBitStreamWriteInt8(bs, " .. Outline .. ")\n")
                file:write("raknetBitStreamWriteInt32(bs, " .. dBackgroundColor .. ")\n")
                file:write("raknetBitStreamWriteInt8(bs, " .. Style .. ")\n")
                file:write("raknetBitStreamWriteInt8(bs, " .. Selectable .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. fX .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. fY .. ")\n")
                file:write("raknetBitStreamWriteInt16(bs, " .. wModelID .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. fRotX .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. fRotY .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. fRotZ .. ")\n")
                file:write("raknetBitStreamWriteFloat(bs, " .. fZoom .. ")\n")
                file:write("raknetBitStreamWriteInt16(bs, " .. wColor1 .. ")\n")
                file:write("raknetBitStreamWriteInt16(bs, " .. wColor2 .. ")\n")
                file:write("raknetBitStreamWriteInt16(bs, " .. #szText .. ")\n")
                file:write("raknetBitStreamWriteString(bs, \"" .. szText .. "\")\n")
                file:write("raknetEmulRpcReceiveBitStream(134, bs)\n")
                file:write("raknetDeleteBitStream(bs)\n")
                file:close()
                print("Файл 'textdraw_rpc.txt' с параметрами ShowTextDraw сохранен.")
            else
                print("Не удалось создать файл.")
            end
        end
    elseif id == 105 then
        local wTextDrawID = raknetBitStreamReadInt16(bs)
        local TextLength = raknetBitStreamReadInt16(bs)
        local Text = raknetBitStreamReadString(bs, TextLength)
        if isTextDrawIDInArray(wTextDrawID, textdrawID_list) then
            local file = io.open(getWorkingDirectory() .. "\\textdraw_rpc.txt", "a")
            if file then
                file:write("--------------------------------\n")
                file:write("bs = raknetNewBitStream()\n")
                file:write("raknetBitStreamWriteInt16(bs, " .. tostring(wTextDrawID) .. ")\n")
                file:write("raknetBitStreamWriteInt16(bs, " .. tostring(TextLength) .. ")\n")
                file:write("raknetBitStreamWriteString(bs, \"" .. Text .. "\")\n")
                file:write("raknetEmulRpcReceiveBitStream(105, bs)\n")
                file:write("raknetDeleteBitStream(bs)\n")
                file:close()
                print("Файл 'textdraw_rpc.txt' с параметрами TextDrawSetString сохранен.")
            else
                print("Не удалось создать файл.")
            end
        end
    end
end
 
Последнее редактирование:

Gorskin

I shit on you
Проверенный
1,246
1,043
Описание: Задает "высокий" приоритет процессу gta_sa.exe
Делает это так, как вы делаете это через --> диспетчер задач --> Задать приоритет.

Lua:
local ffi = require("ffi")

ffi.cdef[[
    int GetPriorityClass(void* hProcess);
    int SetPriorityClass(void* hProcess, int dwPriorityClass);
    void* GetCurrentProcess();
]]

function setHighPriority()
    local processHandle = ffi.C.GetCurrentProcess()
    local originalPriorityClass = ffi.C.GetPriorityClass(processHandle)
    ffi.C.SetPriorityClass(processHandle, 0x00000080)
end

function main()
    setHighPriority()
end
 

why ega

РП игрок
Модератор
2,539
2,231
Описание: Получаем размеры шрифтов, используемого SAMP-ом в диалогах, килллисте и еще какой-то штуке (скорее всего чат, не хочу сейчас разбираться)
Код:
Lua:
local ffi = require("ffi")


--[[
    Оффсеты под R1, но если кому-то надо, отпишите в лс :)
    upd: Добавил и для R3 по просьбе @Double Tap Inside 

    Все те, кто хотят доебаться за то, что тут говнокод,
    в плане одинаковых прототипов и в целом строения функций.
    Сделано так специально для тех, кто хочет просто ctrl+c ctrl+v,
    поэтому сами делайте 3-х этажные абстракции. Ну, а еще мне лень.
 
    Сделайте кто-то пж из этого крутую таблицу с метаметодами
]]


function getFontSizeDeathWindow()
    local sampHandle = getModuleHandle("samp.dll")
    local fontSize = ffi.cast("int(*)()", sampHandle + 0xB3CB0)()
    return fontSize
end


function getFontSizeDeathWindow()
    local sampHandle = getModuleHandle("samp.dll")
    local fontSize = ffi.cast("int(*)()", sampHandle + 0xB3CB0)()
    return fontSize
end


function getFontSizeDialog() -- размер шрифта диалогов
    local sampHandle = getModuleHandle("samp.dll")
    local fontSize = ffi.cast("int(*)()", sampHandle + 0xB3CF0)()
    return fontSize
end


function getFontSize() -- скорее всего общий какой-то шрифт
    local sampHandle = getModuleHandle("samp.dll")
    local fontSize = ffi.cast("int(*)()", sampHandle + 0xB3C60)()
    return fontSize
end
Соррян, я ебанулся и сделал класс:
Lua:
local ffi = require("ffi")



local Fonts = {} do
    local sampHandle = nil
    local proto = "int(*)()"
    local sampVersion = "R1"


    local offsets = {
        deathWindow = {
            ["R1"] = 0xB3CB0,
            ["R3"] = 0xC5B70
        },

        dialog = {
            ["R1"] = 0xB3CB0,
            ["R3"] = 0xC5BB0
        },

        default = {
            ["R1"] = 0xB3C60,
            ["R3"] = 0xC5B20
        }
    }



    local function castSampAddressToFunctionPtr(key)
        return ffi.cast(proto, sampHandle + offsets[key][sampVersion])()
    end


    function Fonts:getDialog()
        return castSampAddressToFunctionPtr("dialog")
    end


    function Fonts:getDeathWindow()
        return castSampAddressToFunctionPtr("deathWindow")
    end


    function Fonts:getDefault()
        return castSampAddressToFunctionPtr("default")
    end



    setmetatable(Fonts, {
        __call = function(self, version)
            sampHandle = getModuleHandle("samp.dll")
            sampVersion = version or sampVersion
            return setmetatable(self, {
                __index = self
            })
        end
    })
end
Пример использования:
Lua:
-- Покажу на примере с классом, т.к. функции вы и сами умеете юзать

local ffi = require("ffi")



local Fonts = {} do
    local sampHandle = nil
    local proto = "int(*)()"
    local sampVersion = "R1"


    local offsets = {
        deathWindow = {
            ["R1"] = 0xB3CB0
        },

        dialog = {
            ["R1"] = 0xB3CB0
        },

        default = {
            ["R1"] = 0xB3C60
        }
    }



    local function castSampAddressToFunctionPtr(key)
        return ffi.cast(proto, sampHandle + offsets[key][sampVersion])()
    end



    function Fonts:getDialog()
        return castSampAddressToFunctionPtr("dialog")
    end


    function Fonts:getDeathWindow()
        return castSampAddressToFunctionPtr("deathWindow")
    end


    function Fonts:getDefault()
        return castSampAddressToFunctionPtr("default")
    end



    setmetatable(Fonts, {
        __call = function(self, version)
            sampHandle = getModuleHandle("samp.dll")
            sampVersion = version or sampVersion
            return setmetatable(self, {
                __index = self
            })
        end
    })
end



local sampFontSize = Fonts("R1")

local deathWindowFont = renderCreateFont("Arial", sampFontSize: getDeathWindow())
local dialogFont = renderCreateFont("Arial", sampFontSize:getDialog())
local defaultFont = renderCreateFont("Arial", sampFontSize:getDefault())



function onD3DPresent()
    renderFontDrawText(deathWindowFont, 'DeathWindowFont', 300, 400, 0xFFFFFFFF)
    renderFontDrawText(dialogFont, 'DialogFont', 1000, 100, 0xFFFFFFFF)
    renderFontDrawText(defaultFont, 'DefaultFont', 100, 500, 0xFFFFFFFF)
end
 
Последнее редактирование:
  • Нравится
Реакции: XRLM

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Lua:
function getFontSizeDeathWindow()
    local sampHandle = getModuleHandle("samp.dll")
    local fontSize = ffi.cast("int(*)()", sampHandle + 0xB3CB0)()
    return fontSize
end
Lua:
local sampHandle = getModuleHandle("samp.dll")
local getFontSizeDeathWindow = ffi.cast('int(*)()', sampHandle + 0xB3CB0)
local getFontSizeDialog = ffi.cast('int(*)()', sampHandle + 0xB3CF0)
-- ...
 
  • Нравится
Реакции: ARMOR

why ega

РП игрок
Модератор
2,539
2,231
Lua:
local sampHandle = getModuleHandle("samp.dll")
local getFontSizeDeathWindow = ffi.cast('int(*)()', sampHandle + 0xB3CB0)
local getFontSizeDialog = ffi.cast('int(*)()', sampHandle + 0xB3CF0)
-- ...
Но так не интересно). Ночной припадок луа кодинга.
С классом можно было много чего реализовать, просто ночью уже руки не дошли (как минимум добавить в классе с названием 'Fonts" не только работу с размером, а то как-то глупо получается). Например хотя бы 3 версии сампа в конструктор и пару других методов, которые что-то дергали из сампа (мб чет в гта ещё прикольное есть)

local getFontSizeDeathWindow = ffi.cast('int(*)()', sampHandle + 0xB3CB0) local getFontSizeDialog = ffi.cast('int(*)()', sampHandle + 0xB3CF0) -- ...
Либо если ты про оффсеты, то тоже заметил, что они одинаковые, надо будет подправить
 

tfornik

Известный
309
222
Описание: Функции для быстрой отправки / чтения SNET BitStream
Авторы: @tfornik , @why ega
Пример использования:
CLIENT:
local snet = require("snet")
local bstream = snet.bstream


SNetClient = snet.client("127.0.0.1", 7777)
send_bs(SNetClient, 1, {
    -2,
    "Test",
    true
})

SERVER:
package.path = package.path .. ';../?.lua;../?.luac;../../?.lua;../../?.luac'
package.cpath = "./?.dll;C:/luajit-compiler/luajit/lua/?.dll;C:/luajit-compiler/luajit/loadall.dll"

local snet = require("snet")
local bstream = snet.bstream




local server = snet.server("*", 7777)


server:add_event_handler('onReceivePacket', function(packet_id, bs, address, port)
    if packet_id == 1 then
        local bitStream = read_bs(bs)
    end
end)

while true do
    server:process()
end
Код:
Запись:
function send_bs(server, packet_id, params)
    if type(params) ~= "table" then print("bad argument #3. table expected, got "..type(params)) return false end;
    if type(packet_id) ~= "number" then print("bad argument #2. number expected, got "..type(packet_id)) return false end;
    if server == nil or type(server) ~= "table" then print("ты забыл подключиться к серверу!") return false end;

    --> Проверка на тип числа
    local bsType=function(b)if not(b%1==0)then return BS_FLOAT end;if b>0 then if b<=255 then return BS_UINT8 end;
    if b>255 and b<=65535 then return BS_UINT16 end;if b>65535 and b<=4294967295 then return BS_UINT32 end elseif b<0 then if b>-127 then return BS_INT8 end;
    if b<-127 and b>-32768 then return BS_INT16 end;if b<-32768 and b>-2147483648 then return BS_INT32 end end end

    local data = {}
    for k,v in ipairs(params) do
        if type(v) == "number" then --> Тип элемента таблицы > Число
            data[#data + 1] = {bsType(v), v}
        elseif type(v) == "boolean" then --> Тип элемента таблицы > Логическая переменная(true/false)
            data[#data + 1] = {BS_BOOLEAN, v}
        elseif type(v) == "string" then --> Тип элемента таблицы > Строка
            data[#data + 1] = {bsType(#v), #v}
            data[#data + 1] = {BS_STRING, v}
        end
    end

    --> Для быстрого чтения битстрима
    local dataJson = {}
    for k,v in ipairs(data) do
        dataJson[#dataJson + 1] = v[1]
    end
    dataJson = encodeJson(dataJson)

    --> Запись битстрима в таблицу
    local bs = bstream.new()

    bs:write(BS_UINT32, #dataJson)
    bs:write(BS_STRING, dataJson)

    for k,v in ipairs(data) do
        bs:write(v[1], v[2])
    end
    data = {}

    server:send(packet_id, bs, SNET_SYSTEM_PRIORITY)
end

Чтение:
function read_bs(bitStream)
    local json = require("cjson")
    local len = bitStream:read(BS_UINT32)
    local data = json.decode(bitStream:read(BS_STRING, len))
    local result = {}

    for k,v in ipairs(data) do
        if v == "string" then    result[#result + 1] = bitStream:read(v, result[#result]) else    result[#result + 1] = bitStream:read(v)  end
    end
    return result
end
Учтите. Что read_bs без send_bs - работать не будет. Они связаны на 100%.
Если вы не хотите, чтобы read_bs был связан с send_bs -> Уберите код на запись таблицы dataJson. ( Тогда вы сами должны будете догадаться, какие типы данных прислал клиент :)) )
 
Последнее редактирование:

JustFedot

Известный
274
272
Описание: Анимированный кружок для imgui с возможность задать кучу параметров. Хоть полный круг, хоть один кружочек. И дофига чего ещё.
Автор
: @JustFedot

Не знаю почему, но из видео Гифка получилась с каким-то дефектом картинки. Ну да ладно.
Видео без названия — сделано в Clipchamp.gif

Функция:
function imgui.circleLoading(text, hint, orbitRadius, circleSize, spacing, speed, arcCoverage, rotateLeft)
    local fullSize = (orbitRadius + circleSize / 2 + spacing) * 2
    local draw_list = imgui.GetWindowDrawList()
    local cursorPos = imgui.GetCursorScreenPos()
    local centerPos = imgui.ImVec2(cursorPos.x + fullSize / 2, cursorPos.y + fullSize / 2)
    local time = os.clock() * speed
    local arc_length = (2 * math.pi) * (arcCoverage / 100)
    local directionMultiplier = rotateLeft and -1 or 1
    imgui.Dummy(imgui.ImVec2(fullSize, fullSize))
    local isHovered = imgui.IsItemHovered()
    local color = isHovered and imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.ButtonHovered]) or imgui.GetColorU32(imgui.ImVec4(1, 1, 1, 1))
    if isHovered then imgui.SetTooltip(hint) end
    for i = 0, math.floor(12 * (arcCoverage / 100)) - 1 do
        local angle = directionMultiplier * arc_length / math.floor(12 * (arcCoverage / 100)) * (i + time)
        draw_list:AddCircleFilled(imgui.ImVec2(centerPos.x + orbitRadius * math.cos(angle), centerPos.y + orbitRadius * math.sin(angle)), circleSize / 2, color)
    end
    local textSize = imgui.CalcTextSize(text)
    if textSize.x < fullSize and textSize.y < fullSize then
        draw_list:AddText(imgui.ImVec2(centerPos.x - textSize.x / 2, centerPos.y - textSize.y / 2), color, text)
    end
    return imgui.IsItemClicked(0)
end


Lua:
-- Пример использования в цикле отрисовки окна

--Для русского текста использовать: u8("Текст")
-- imgui.circleLoading("текст", "подсказка", радиус орбиты, размер кружков, отступ, скорость, процент покрытия, вращение влево)
-- Возвращает true если нажата
if imgui.circleLoading(u8"Загрузка...",u8 "Подсказка", 50, 10, 5, 1.5, 50, false) then
    --Действие
end

P.S.
Если текст больше радиуса орбиты круга, он отображаться не будет. Если у вас текст не отображается, увеличивайте радиус орбиты.
Динамическое изменение радиуса орбиты исходя из длины текста решил не делать, ибо тогда если использовать динамический текст - круг будет прыгать в размерах что не есть красиво.
 
Последнее редактирование:

percheklii

Известный
722
265
Описание: удобная функция для работы с displayText, может кому пригодится.

Lua:
function displayCustomText(entryName, text, x, y, width, height, style, alignment, color)
    if alignment == 1 then
        setTextJustify(true) -- Левое выравнивание.
    elseif alignment == 2 then
        setTextCentre(true) -- Центральное выравнивание.
    elseif alignment == 3 then
        setTextRightJustify(true) -- Правое выравнивание.
    end

    setGxtEntry(entryName, text) -- entryName(Может быть любое название при вызове), текст.
    setTextScale(width, height) -- Ширина, высота.
    setTextColour(unpack(color)) -- Цвет в формате rgba.
    setTextEdge(1, 0, 0, 0, 255) -- Ширина обводки, цвет обводки.
    setTextFont(style) -- Стиль 0-3.
    displayText(x, y, entryName) -- Позиция по оси x и y, и уже наш текст.
end
Lua:
--вызывать в бесконечном цикле.
displayCustomText("MONEY", "$" .. getPlayerMoney(PLAYER_HANDLE), 200, 200, 0.5, 1.5, 3, 1, {255, 255, 255, 255})

AnTbo2g.png
 
Последнее редактирование:

Gorskin

I shit on you
Проверенный
1,246
1,043
Описание: Устанавливает скорость разгона лопастей на вертолетах.
Чем выше скорость - тем быстрее взлет.
Не рекомендую ставить выше 1.000
Меняйте от 0.000 до 1.000
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand("rots", function(param)
        if type(tonumber(param)) == 'number' then
            changeRotorSpeed(param)
        end
    end)
    wait(-1)
end

function changeRotorSpeed(speed)
    local _s = 0xFCE9F5+0x74
    writeMemory(_s, 4, representFloatAsInt(speed), true) -- 0.001 -- std
    writeMemory(0x6C4F29+2, 4, _s, true)
    sampAddChatMessage("Скорость разгона лопастей установлена на: "..speed, -1)
end
 

why ega

РП игрок
Модератор
2,539
2,231
Описание: Возвращает средний и последний пинг клиента
Код:
Lua:
local ffi = require("ffi")



function getAveragePing()
    local sampHandle = getModuleHandle("samp.dll")
    local pRakClientGetAveragePing = ffi.cast("int(__thiscall*)(uintptr_t pRakClient)", sampHandle + 0x308C0)

    return pRakClientGetAveragePing(sampGetRakclientInterface())
end



function getLastPing()
    local sampHandle = getModuleHandle("samp.dll")
    local pRakClientGetLastPing = ffi.cast("int(__thiscall*)(uintptr_t pRakClient)", sampHandle + 0x308F0)
  
    return pRakClientGetLastPing(sampGetRakclientInterface())
end
Пример использования:
Lua:
local ffi = require("ffi")



function main()
    while not isSampAvailable() do wait(0) end

    sampRegisterChatCommand("ping", function()
        print("last:", getLastPing(), "average:", getAveragePing())
    end)

    wait(-1)
end



function getAveragePing()
    local sampHandle = getModuleHandle("samp.dll")
    local pRakClientGetAveragePing = ffi.cast("int(__thiscall*)(uintptr_t pRakClient)", sampHandle + 0x308C0)

    return pRakClientGetAveragePing(sampGetRakclientInterface())
end



function getLastPing()
    local sampHandle = getModuleHandle("samp.dll")
    local pRakClientGetLastPing = ffi.cast("int(__thiscall*)(uintptr_t pRakClient)", sampHandle + 0x308F0)
    return pRakClientGetLastPing(sampGetRakclientInterface())
end
 

Willy4ka

Известный
199
376
Описание: типо чекбокс, тока круглый, я хз как это описать, у меня фантазии нету
Пример использования:
Lua:
imgui.SelectItem('Nick_Name', infoBarNick)
selectitem.gif

Код:
Lua:
function imgui.SelectItem(str_id, bool, size, speed)
    local p         = imgui.GetCursorScreenPos()
    local DL        = imgui.GetWindowDrawList()

    local label     = str_id:gsub('##.+', '') or ""
    local h         = imgui.GetTextLineHeightWithSpacing() + 2
    speed           = speed or 0.1
    size            = size or 10
    local function bringVec2To(from, to, start_time, duration)
        local timer = os.clock() - start_time
        if timer >= 0.00 and timer <= duration then
            local count = timer / (duration / 100)
            return (from + (count * (to - from) / 100)), true
        end
        return (timer > duration) and to or from, false
    end
    local function bringVec4To(from, to, start_time, duration)
        local timer = os.clock() - start_time
        if timer >= 0.00 and timer <= duration then
            local count = timer / (duration / 100)
            return imgui.ImVec4(
                from.x + (count * (to.x - from.x) / 100),
                from.y + (count * (to.y - from.y) / 100),
                from.z + (count * (to.z - from.z) / 100),
                from.w + (count * (to.w - from.w) / 100)
            ), true
        end
        return (timer > duration) and to or from, false
    end
    if UI_SelectItem == nil then UI_SelectItem = {} end
    if UI_SelectItem[str_id] == nil then
        UI_SelectItem[str_id] = {
            from = bool[0] and 0 or size-2,
            to = bool[0] and size-2 or 0,
            start = 0,
            anim = false,
            hovered = false,
            h_start = 0,
        }
    end

    local pool = UI_SelectItem[str_id]

    imgui.BeginGroup()
        imgui.InvisibleButton(str_id, imgui.ImVec2(size*2, size*2))
        local pp = imgui.GetCursorPos()
        imgui.SameLine(pp.x+(size*2))
        pp = imgui.GetCursorPos()
        imgui.SetCursorPos(imgui.ImVec2(pp.x, (pp.y + h/2 - imgui.CalcTextSize(label).y/2)))
        imgui.TextWrapped(label)
    imgui.EndGroup()

    local clicked = imgui.IsItemClicked()
    if pool.hovered ~= imgui.IsItemHovered() then
        pool.hovered = imgui.IsItemHovered()
        local timer = os.clock() - pool.h_start
        if timer <= speed and timer >= 0 then
            pool.h_start = os.clock() - (speed - timer)
        else
            pool.h_start = os.clock()
        end
    end

    if clicked then
        local isAnim = false

        if pool.anim then
            isAnim = true
        end

        if not isAnim then
            bool[0] = not bool[0]
            pool.from = bool[0] and 0 or size-2
            pool.to = bool[0] and size-2 or 0
            pool.start = os.clock()
        end
    end

    local rad = 0
    rad,pool.anim = bringVec2To(
        pool.from,
        pool.to,
        pool.start,
        speed
    )

    local bordercolor = imgui.GetStyle().Colors[imgui.Col.Border]
    local c = imgui.GetStyle().Colors[imgui.Col.ButtonHovered]
    local colorHovered = bringVec4To(
        pool.hovered and imgui.ImVec4(c.x, c.y, c.z, 0) or imgui.ImVec4(c.x, c.y, c.z, 0.2),
        pool.hovered and imgui.ImVec4(c.x, c.y, c.z, 0.2) or imgui.ImVec4(c.x, c.y, c.z, 0),
        pool.h_start,
        speed
    )

    DL:AddCircleFilled(imgui.ImVec2(p.x + size, p.y + size), size, 0x80303030, 25)
    DL:AddCircle(imgui.ImVec2(p.x + size, p.y + size), size+3, imgui.GetColorU32Vec4(bordercolor),25)
    DL:AddCircleFilled(imgui.ImVec2(p.x + size, p.y + size), size, imgui.GetColorU32Vec4(colorHovered), 25)
    DL:AddCircleFilled(imgui.ImVec2(p.x + size, p.y + size), rad, 0x80808080, 25)
    return clicked
end
 

ChromiusJ

x B x A x R x
Друг
4,895
3,183
Описание: Рисует красивый хпбар над головой
Код:
Lua:
-- original source here: https://www.unknowncheats.me/forum/direct3d/488372-health-circle-esp-imgui-function.html
function drawHealthCircle(position, health, max_health, radius)
    local health_text = tostring(health)
    local a_max = (math.pi * 2.0)
    local v1 = health / max_health
    local difference = v1 - 1.0
    imgui.GetForegroundDrawList():PathArcTo(position, radius, (-(a_max / 4.0)) + (a_max / max_health) * (max_health - health), a_max - (a_max / 4.0), 200 - 1)
    imgui.GetForegroundDrawList():PathStroke(imgui.ColorConvertFloat4ToU32({math.abs(v1 - difference), v1, v1, 1.0}), 0, 2.0)
    imgui.GetForegroundDrawList():AddText({position.x - imgui.CalcTextSize(health_text).x / 2.0, position.y - imgui.CalcTextSize(health_text).y / 2.0}, imgui.ColorConvertFloat4ToU32({1, 1, 1, 1.0}), health_text)
end
Пример использования:
Lua:
local getBonePosition = ffi.cast("int (__thiscall*)(void*, float*, int, bool)", 0x5E4280)

function getBodyPartCoordinates(id, handle)
    local pedptr = getCharPointer(handle)
    local vec = ffi.new("float[3]")
    getBonePosition(ffi.cast("void*", pedptr), vec, id, true)
    return vec[0], vec[1], vec[2]
end

local backgroundDraw = imgui.OnFrame(
    function()
        return window[0]
    end,
    function(self)
        self.HideCursor = true
        local dl = imgui.GetBackgroundDrawList()
        local player_pos = {getBodyPartCoordinates(5, PLAYER_PED)}
        player_pos[3] = player_pos[3] - 0.030
        local startX, startY = convert3DCoordsToScreen(player_pos[1], player_pos[2] , player_pos[3] + 0.375)

        drawHealthCircle(imgui.ImVec2(startX, startY), getCharHealth(PLAYER_PED), 100, 20.0)
    end
)

function drawHealthCircle(position, health, max_health, radius)
    local health_text = tostring(health)
    local a_max = (math.pi * 2.0)
    local v1 = health / max_health
    local difference = v1 - 1.0
    imgui.GetForegroundDrawList():PathArcTo(position, radius, (-(a_max / 4.0)) + (a_max / max_health) * (max_health - health), a_max - (a_max / 4.0), 200 - 1)
    imgui.GetForegroundDrawList():PathStroke(imgui.ColorConvertFloat4ToU32({math.abs(v1 - difference), v1, v1, 1.0}), 0, 2.0)
    imgui.GetForegroundDrawList():AddText({position.x - imgui.CalcTextSize(health_text).x / 2.0, position.y - imgui.CalcTextSize(health_text).y / 2.0}, imgui.ColorConvertFloat4ToU32({1, 1, 1, 1.0}), health_text)
end
1702811541920.png
 

percheklii

Известный
722
265
Описание: затемняет основной цвет для второго цвета, я хз как правильно объяснить. Пример я думаю наглядно покажет
factor - это значение на сколько сильно будет затемнен цвет, чем меньше значение, тем больше цвет будет затемнен.
Делал для себя чисто, может кому пригодится

hlHlv3N.png


Lua:
function darkenColor(color, factor)
    local r = math.floor((bit.rshift(bit.band(color, 0xFF0000), 16) * factor))
    local g = math.floor((bit.rshift(bit.band(color, 0x00FF00), 8) * factor))
    local b = math.floor((bit.band(color, 0x0000FF) * factor))
    return (bit.bor(bit.band(color, 0xFF000000), bit.lshift(r, 16), bit.lshift(g, 8), b))
end
Lua:
local font = renderCreateFont("Arial", 11, 13)

function main()
    while true do wait(0)
        drawBar(500, 500 + 16, 130, 16, 0xFFB4191D, font, "25", 100)
        drawBar(500, 500 + 35, 130, 16, 0xFF1D00FA, font, "50", 100)
        drawBar(500, 500 + 52, 130, 16, 0xFF04FA00, font, "75", 100)
    end
end

function darkenColor(color, factor)
    local r = math.floor((bit.rshift(bit.band(color, 0xFF0000), 16) * factor))
    local g = math.floor((bit.rshift(bit.band(color, 0x00FF00), 8) * factor))
    local b = math.floor((bit.band(color, 0x0000FF) * factor))
    return (bit.bor(bit.band(color, 0xFF000000), bit.lshift(r, 16), bit.lshift(g, 8), b))
end

function drawBar(x, y, w, h, mcolor, font, value, maxValue)
    renderDrawBoxWithBorder(x, y, w, h, darkenColor(mcolor, 0.5), 3, 0xFF000000)
    barWidth = math.min(w * value / maxValue - 2 * 3, w - 2 * 3)
    renderDrawBox(x + 3, y + 3, barWidth, h - 2 * 3, mcolor)
    renderFontDrawText(font, tostring(value), x + (w - renderGetFontDrawTextLength(font, tostring(value))) / 2, y - 1, 0xFFFFFFFF)
end
 

why ega

РП игрок
Модератор
2,539
2,231
Описание: Возвращает порт и IP адрес (в виде числа) клиента, через который отправляется трафик на сервер
Код:
Lua:
local ffi = require("ffi")



function getLocalPort()
    local pMyPlayerIdPort= ffi.cast("uint16_t*", sampGetRakpeer() + 0x231)
    return pMyPlayerIdPort[0]
end


function getLocalHost()
    local pMyPlayerIdBinaryAddress = ffi.cast("uint32_t*", sampGetRakpeer() + 0x22D)
    return pMyPlayerIdBinaryAddress[0]
end
Пример использования:
Lua:
print("PORT: ", getLocalPort(), "ADDRESS: ", getLocalHost())
 
Последнее редактирование: