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

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Функцию смены цвета текста взял у @imring и изменил
почему только центр?
Lua:
function imgui.TextColoredRGB(text, render_text)
    local style = imgui.GetStyle()
    local colors = style.Colors
    local clr = imgui.Col
    local u8 = require 'encoding'.UTF8

    local explode_argb = function(argb)
        local a = bit.band(bit.rshift(argb, 24), 0xFF)
        local r = bit.band(bit.rshift(argb, 16), 0xFF)
        local g = bit.band(bit.rshift(argb, 8), 0xFF)
        local b = bit.band(argb, 0xFF)
        return a, r, g, b
    end

    local getcolor = function(color)
        if color:sub(1, 6):upper() == 'SSSSSS' then
            local r, g, b = colors[1].x, colors[1].y, colors[1].z
            local a = tonumber(color:sub(7, 8), 16) or colors[1].w * 255
            return ImVec4(r, g, b, a / 255)
        end
        local color = type(color) == 'string' and tonumber(color, 16) or color
        if type(color) ~= 'number' then return end
        local r, g, b, a = explode_argb(color)
        return imgui.ImColor(r, g, b, a):GetVec4()
    end

    local function render_text(text)
        for w in text:gmatch('[^\r\n]+') do
            local text, color = {}, {}
            local m = 1
            w = w:gsub('{(......)}', '{%1FF}')
            while w:find('{........}') do
                local n, k = w:find('{........}')
                local color = getcolor(w:sub(n + 1, k - 1))
                if color then
                    text[#text], text[#text + 1] = w:sub(m, n - 1), w:sub(k + 1, #w)
                    colors_[#colors_ + 1] = color
                    m = n
                end
                w = w:sub(1, n - 1) .. w:sub(k + 1, #w)
            end
            local length = imgui.CalcTextSize(u8(w))
            if render_text == 2 then
                imgui.NewLine()
                imgui.SameLine(max_float / 2 - ( length.x / 2 ))
            elseif render_text == 3 then
                imgui.NewLine()
                imgui.SameLine(max_float - length.x - 5 )
            end
            if text[0] then
                for i, k in pairs(text) do
                    imgui.TextColored(color[i] or colors[clr.Text], u8(k))
                    imgui.SameLine(nil, 0)
                end
                imgui.NewLine()
            else imgui.Text(u8(w)) end
        end
    end

    render_text(text)
end
render_text:
1 - слева (можно не указывать, автоматом будет)
2 - в центре
3 - справа
 

ShuffleBoy

Известный
Друг
754
429
Описание: аналог функции из PHP http_build_query. Из таблицы составляет url запрос
Код:
Lua:
function char_to_hex(str)
  return string.format("%%%02X", string.byte(str))
end

function url_encode(str)
  local str = string.gsub(str, "\\", "\\")
  local str = string.gsub(str, "([^%w])", char_to_hex)
  return str
end

function http_build_query(query)
  local buff=""
  for k, v in pairs(query) do
    buff = buff.. string.format("%s=%s&", k, url_encode(v))
  end
  local buff = string.reverse(string.gsub(string.reverse(buff), "&", "", 1))
  return buff
end
Пример использования:
Lua:
http_build_query({a = "привет\nсобака", c = "я люблю писать русский текст с пробелами"})
Вернет:
Код:
a=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82%0A%D1%81%D0%BE%D0%B1%D0%B0%D0%BA%D0%B0&c=%D1%8F%20%D0%BB%D1%8E%D0%B1%D0%BB%D1%8E%20%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C%20%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9%20%D1%82%D0%B5%D0%BA%D1%81%D1%82%20%D1%81%20%D0%BF%D1%80%D0%BE%D0%B1%D0%B5%D0%BB%D0%B0%D0%BC%D0%B8
 
Последнее редактирование:
461
819
Описание: ставит чекпоинт на указанных координатах
Код:
Lua:
function setMarker(type,x,y,z)
    bs = raknetNewBitStream()
    raknetBitStreamWriteInt8(bs, type)
    raknetBitStreamWriteFloat(bs, x)
    raknetBitStreamWriteFloat(bs, y)
    raknetBitStreamWriteFloat(bs, z)
    raknetBitStreamWriteFloat(bs, 0)
    raknetBitStreamWriteFloat(bs, 0)
    raknetBitStreamWriteFloat(bs, 0)
    raknetBitStreamWriteFloat(bs, 6)
    raknetEmulRpcReceiveBitStream(38, bs)
    raknetDeleteBitStream(bs)
end

Пример использования:
Lua:
setMarker(1,1542.6827,-1676.3931,13.5550)
 
Последнее редактирование:

kmsfax

Известный
154
89
Описание: Позволяет узнать, виден ли Name Tag игрока.
Lua:
function GetNameTag(ID)
    local StructPtr = sampGetPlayerStructPtr(ID)
    local StructPtr = readMemory(StructPtr, 4, true)
    return = getStructElement(StructPtr, 179, 2, false)
end
Пример использования:
Lua:
sampRegisterChatCommand('mask', function(Param)
    local ID = string.match(Param, '(%d+)')
    if ID ~= nil then
        if sampIsPlayerConnected(ID) then
            local result, cped = sampGetCharHandleBySampPlayerId(ID)
            if result then
                if GetMaskStats(ID) == 0 then
                    sampAddChatMessage(string.format("NameTag игрока под ID %d скрыт.", ID), 0xFFFFFF)
                else
                    sampAddChatMessage(string.format("NameTag игрока под ID %d виден.", ID), 0xFFFFFF)
                end
            end
        end
    end
end)
 

Вложения

  • NameTag.png
    NameTag.png
    31.4 KB · Просмотры: 784

trefa

Известный
Всефорумный модератор
2,097
1,229
Описание: Получает экранные координаты прицела. Огромная благодарность @san0
Lua:
function get_crosshair_position()
    local vec_out = ffi.new("float[3]")
    local tmp_vec = ffi.new("float[3]")
    ffi.cast(
        "void (__thiscall*)(void*, float, float, float, float, float*, float*)",
        0x514970
    )(
        ffi.cast("void*", 0xB6F028),
        15.0,
        tmp_vec[0], tmp_vec[1], tmp_vec[2],
        tmp_vec,
        vec_out
    )
    return vec_out[0], vec_out[1], vec_out[2]
end
Пример использования:
Lua:
local sx, sy = convert3DCoordsToScreen(get_crosshair_position())











Описание: Скрывает прицел
Lua:
crosshair = {5825260,5825281,5825270,5825265,5825471,5825498,5825489,5825480,5825568,5825587,5825578,5825573,5825633,5825660,5825651,5825638,5825638,5825159,5825180,5825175,5825170}

function crosshair(param)
for i, val in ipairs(crosshair) do
memory.write(val, param and 255 or 0, 1, true)
end
end
Пример использования:
Lua:
sampRegisterChatCommand("off", function()
    cr = not cr
    crosshair(cr)
end)
 
Последнее редактирование:

san0

Известный
Друг
411
267
Описание: Скрывает прицел
Спасибо за публикацию) Если рекомендации уместны, то в языке Lua есть бинарные операторы, с помощью которых можно приблизится к работе тернарного оператора:
Lua:
function crosshair(param)
    for i, val in ipairs(crosshair) do
        memory.write(val, param and 255 or 0, 1, true)
    end
end
И еще хотелось бы посоветовать сделать так:
Lua:
function set_crosshair_render_state(state)
    local restore = memory.unprotect(0x0058FBBF, 5)
    memory.hex2bin(state and "E85CE4FFFF" or string.rep("90", 5), 0x0058FBBF, 5)
    memory.protect(0x0058FBBF, 5, restore)
end
Или вовсе так:
Lua:
function set_crosshair_render_state(state)
    memory.copy(0x0058FBBF, memory.strptr(state and "\xE8\x5C\xE4\xFF\xFF" or string.rep("\x90", 5)), 5, true)
end
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Описание: Переводит секунды сразу в часы:минуты:секунды
Lua:
function get_timer(time)
return string.format("%s:%s:%s",string.format("%s%s",((tonumber(os.date("%H",time)) < tonumber(os.date("%H",0)) and (24 + tonumber(os.date("%H",time))) - tonumber(os.date("%H",0)) or tonumber(os.date("%H",time)) - (tonumber(os.date("%H",0)))) < 10 and 0 or ""),(tonumber(os.date("%H",time)) < tonumber(os.date("%H",0)) and (24 + tonumber(os.date("%H",time))) - tonumber(os.date("%H",0)) or tonumber(os.date("%H",time)) - (tonumber(os.date("%H",0))))),os.date("%M",time),os.date("%S",time))
end
Пример использования:
Lua:
print(get_time(3666))
--вернёт 01:01:06
чебля
Lua:
local timezone_offset = os.date('%H', 0) * 60 * 60
print(os.date('%H:%M:%S', 3666 - timezone_offset))
или
Lua:
local timezone_offset = os.time(os.date("!*t", 0))
if timezone_offset < 0 then timezone_offset = -timezone_offset end
print(os.date('%H:%M:%S', 3666 - timezone_offset))

upd:
Lua:
local function get_timezone()
  local time = 86400
  local ttime = os.date("!*t", time)
  return os.difftime(time, os.time(ttime))
end
local timezone = get_timezone()

local function get_timer(time)
  return os.date('%H:%M:%S', 86400 - timezone + time)
end

print(get_timer(3666))
-- 01:01:06
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Описание: получает кнопки диалога.
Lua:
function sampGetDialogButtons()
    local dialog = ffi.cast('void*', memory.getuint32(sampGetDialogInfoPtr() + 0x1C)) -- CDXUTDialog*
    local func = ffi.cast('char*(__thiscall *)(void*,int,unsigned int)', sampGetBase() + 0x82C50) -- CDXUTControl* GetControl( int ID, UINT nControlType );
    local b1p = func(dialog, 20, 0) + 0x4D
    local b2p = func(dialog, 21, 0) + 0x4D
    return ffi.string(b1p), ffi.string(b2p)
end
спс @4el0ve4ik что проверил функу
 
Последнее редактирование:

Pakulichev

Software Developer & System Administrator
Друг
1,789
2,130
Описание: Получает XYZ координаты перед персонажем с установленной дистанцией.
Lua:
function getCoordinatesInFrontOfChar(handle, distance)
  if not doesCharExist(handle) then return false end -- возвращаем false, если handle неверный
  local atX, atY, atZ = getCharCoordinates(handle) -- получаем текущие координаты персонажа по его handle
  local angle = getCharHeading(handle) -- получаем угол поворота персонажа по его handle
  atX = atX + (distance * math.sin(math.rad(-angle))) -- получаем X-координату через синус
  atY = atY + (distance * math.cos(math.rad(-angle))) -- получаем Y-координату через косинус
  return true, atX, atY, atZ
end
Пример использования:
Lua:
local result, x, y, z = getCoordinatesInFrontOfChar(PLAYER_PED, 3.0)
if result then print(x, y, z) end
Если стоять в координатах 0.0, 0.0, 0.0 под углом 60 градусов, то будет выведено примерно -2.1, 2.1, 0.0.
 
Последнее редактирование:

ШPEK

Известный
1,476
524
Описание: Удаляет строку в чате
Lua:
function deleteString(id)
   memory.fill(sampGetChatInfoPtr() + 306 + id * 252, 0, 252)
   memory.write(sampGetChatInfoPtr() + 0x63DA, 1, 1)
end
Пример использования:
Lua:
local memory = require("memory")
function main()
   while not isSampAvailable() do wait(100) end
   sampRegisterChatCommand("deel", function(param) deleteString(tonumber(param)) end)
   wait(-1)
end

function deleteString(id)
   memory.fill(sampGetChatInfoPtr() + 306 + id * 252, 0, 252)
   memory.write(sampGetChatInfoPtr() + 0x63DA, 1, 1)
end
 

Pakulichev

Software Developer & System Administrator
Друг
1,789
2,130
Заметил, что по умолчанию отсутствует функция, с помощью которой можно было бы удобно получить ID скина у игроков SAMP.
Описание: Получает ID текущего скина, который надет на игрока, по ID игрока SAMP.
Lua:
function sampGetPlayerSkin(id)
    if not id or not sampIsPlayerConnected(tonumber(id)) and not tonumber(id) == select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)) then return false end -- проверяем параметр
    local isLocalPlayer = tonumber(id) == select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)) -- проверяем, является ли цель локальным игроком
    local result, handle = sampGetCharHandleBySampPlayerId(tonumber(id)) -- получаем CharHandle по SAMP-ID
    if not result and not isLocalPlayer then return false end -- проверяем, валиден ли наш CharHandle
    local skinid = getCharModel(isLocalPlayer and PLAYER_PED or handle) -- получаем скин нашего CharHandle
    if skinid < 0 or skinid > 311 then return false end -- проверяем валидность нашего скина, сверяя ID существующих скинов SAMP
    return true, skinid -- возвращаем статус и ID скина
end
Пример использования:
Lua:
local result, skinid = sampGetPlayerSkin(999)
if result then print('ID скина: ' .. skinid)
else print('Не удалось получить ID скина') end
 
Последнее редактирование:

LUCHARE

Известный
Друг
545
687
Описание: трансформирует точку из 3д пространства в точку на экране (без использования сф)
Lua:
function transform2d(x, y, z)
    local view = require("ffi").cast("float *", 0xB6FA2C)
    local sx, sy = getScreenResolution()
    local nx, ny, nz

    nx = view[0] * x + view[4] * y + view[8] * z + view[12] * 1
    ny = view[1] * x + view[5] * y + view[9] * z + view[13] * 1
    nz = view[2] * x + view[6] * y + view[10] * z + view[14] * 1

    return nx * sx / nz, ny * sy / nz
end
 

ШPEK

Известный
1,476
524
Описание: проводит поиск подстроки нерегистрозависимо
Lua:
function findnr(str, substr, pos, substrpos)
  local alfabet = {}
  for i = 65, 90 do
    alfabet[i] = i + 32
    alfabet[i + 32] = i
  end
  for i = 192, 223 do
    alfabet[i] = i + 32
    alfabet[i + 32] = i
  end
  if not pos then
    pos = 1
  end
  if not substrpos then
    substrpos = 1
  end
  local sbstrp = substrpos
  for i = pos, #str do
    if str:byte(i) == substr:byte(sbstrp) or alfabet[str:byte(i)] == substr:byte(sbstrp) then
      sbstrp = sbstrp + 1
      if sbstrp - 1 >= #substr then
        return true
      end
    else
      sbstrp = substrpos
    end
  end
  return false
end