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

The Spark

Известный
656
688
P/s функция не моя, просто переписал говнокод, а оригинал @Carrentine удалили...

Описание: Отправляет RPC о нанесении урона другому игроку. Урон подбирает автоматически.
Lua:
function SendDamage(id, weap, bone)
    local damage = {
        [22] = 8.25,
        [23] = 13.2,
        [24] = 46.2,
        [25] = 3.3,
        [26] = 3.3,
        [27] = 4.95,
        [28] = 6.6,
        [29] = 8.25,
        [30] = 9.9,
        [31] = 9.9,
        [32] = 6.6,
        [33] = 24.75,
        [34] = 41.25,
        [38] = 46.2
    }
    if damage[weap] ~= nil then
        sampSendGiveDamage(id, damage[weap], weap, bone)
    end
end
Пример использования:
Lua:
SendDamage(154, 22, 4)
 
Последнее редактирование:

deddosouru

Смотрю аниме, служу Сатане
Друг
2,036
1,323
Описание: отправка в чат нескольких сообщений с определенной задержкой(да да, пинаться не надо).

Lua:
function sampSendChatArray(delay, ...)
    lua_thread.create(function()
        for i, v in ipairs({...}) do
            sampSendChat(v)
            wait(delay)
        end
    end)
end

Пример использования:
Lua:
sampSendChatArray(1200, 'Привет, это мое первое сообщение', 'а это мое второе сообщение!') -- где 1200 - это задержка(указывается первым аргументом).
Описание: аналог функции выше, но используя многострочный текст

Lua:
function multiStringSendChat(delay, multiStringText)   
    lua_thread.create(function()
        multiStringText = multiStringText..'\n'
        for s in multiStringText:gmatch('.-\n') do
            sampSendChat(s)
            wait(delay)
        end
    end)
end
Пример использования:
Lua:
text = [[Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Neque viverra justo nec ultrices dui sapien.
Cras semper auctor neque vitae tempus.
Mauris pellentesque pulvinar pellentesque habitant morbi.
Urna duis convallis convallis tellus.
Dictum non consectetur a erat nam at lectus urna.
Diam in arcu cursus euismod quis viverra nibh.
Proin gravida hendrerit lectus a.
Amet aliquam id diam maecenas ultricies mi eget mauris pharetra.
Dis parturient montes nascetur ridiculus mus mauris vitae ultricies.
Velit aliquet sagittis id consectetur purus ut faucibus pulvinar elementum.
Leo urna molestie at elementum eu facilisis sed odio morbi.
Elit sed vulputate mi sit amet mauris commodo.
Massa id neque aliquam vestibulum morbi blandit cursus risus at.
]]
multiStringSendChat(1200, text)
 

ШPEK

Известный
1,474
525
Описание: делает скриншот
Lua:
function takeScreen()
  if isSampLoaded() then
    require("ffi").cast("void (*__stdcall)()", sampGetBase() + 0x70FC0)()
  end
end
Пример использования:
Lua:
function main()
    sampRegisterChatCommand("takescreen", function()
        takeScreen()
    end)
    wait(-1)
end
 

ImPasha

Software Developer & System Administrator
Друг
1,789
2,141
Описание: делает скриншот при помощи встроенной библиотеки «memory»
ШРЕК выше опубликовал способ с использованием FFI, только я не совсем понял для каких целей он использовал FFI.
Lua:
function makeScreenshot(disable) -- если передать true, интерфейс и чат будут скрыты
    if disable then displayHud(false) sampSetChatDisplayMode(0) end
    require('memory').setuint8(sampGetBase() + 0x119CBC, 1)
    if disable then displayHud(true) sampSetChatDisplayMode(2) end
end
Пример использования:
Lua:
if isKeyJustPressed(VK_F9) then makeScreenshot() end -- обычный скриншот игры
if isKeyJustPressed(VK_F10) then makeScreenshot(true) end -- скриншот без чата и HUD'a
 

Legal_Space

Новичок
12
17
Описание: проверка на оригинальность названия
Lua:
function hasRename()
    local SCRIPT_NAME = "Имя скрипта"
    local SCRIPT_EXTENSION = ".lua"
    if thisScript().name ~= string.format("%s%s", tostring(SCRIPT_NAME), tostring(SCRIPT_EXTENSION)) then
        return true
    else
        return false
    end
end

Пример использования:
Lua:
function main()
    if hasRename() then
        thisScript():unload()
    end
end
 

astynk

Известный
Проверенный
742
532
Описание: функция для нацеливания на координаты, взято из сурсов собейта.
Lua:
function targetAtCoords(x, y, z)
    local cx, cy, cz = getActiveCameraCoordinates()

    local vect = {
        fX = cx - x,
        fY = cy - y,
        fZ = cz - z
    }

    local screenAspectRatio = representIntAsFloat(readMemory(0xC3EFA4, 4, false))
    local crosshairOffset = {
        representIntAsFloat(readMemory(0xB6EC10, 4, false)),
        representIntAsFloat(readMemory(0xB6EC14, 4, false))
    }

    -- weird shit
    local mult = math.tan(getCameraFov() * 0.5 * 0.017453292)
    fz = 3.14159265 - math.atan2(1.0, mult * ((0.5 - crosshairOffset[1]) * (2 / screenAspectRatio)))
    fx = 3.14159265 - math.atan2(1.0, mult * 2 * (crosshairOffset[2] - 0.5))

    local camMode = readMemory(0xB6F1A8, 1, false)

    if not (camMode == 53 or camMode == 55) then -- sniper rifle etc.
        fx = 3.14159265 / 2
        fz = 3.14159265 / 2
    end

    local ax = math.atan2(vect.fY, -vect.fX) - 3.14159265 / 2
    local az = math.atan2(math.sqrt(vect.fX * vect.fX + vect.fY * vect.fY), vect.fZ)

    setCameraPositionUnfixed(az - fz, fx - ax)
end

Пример использования:
Lua:
-- СЛИВ ПРИВАТ АИМА
while true do
    wait(1)
    if isKeyDown(1) then
        local _, ped = storeClosestEntities(1)
        if ped ~= -1 then
            local x, y, z = getCharCoordinates(ped)
            targetAtCoords(x, y, z)
        end
    end
end
 
Последнее редактирование:

Carrentine

Потрачен
569
463
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Описание: аналог функции @iAmerican, возвращает ID игрока, на заданном радиусе от прицела.
Lua:
local ffi = require "ffi"
local getBonePosition = ffi.cast("int (__thiscall*)(void*, float*, int, bool)", 0x5E4280)

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

function GetPlayerTarget(radius)
    for i = 0, sampGetMaxPlayerId(true) do
        if sampIsPlayerConnected(i) then
            local find, handle = sampGetCharHandleBySampPlayerId(i)
            if find then
                if isCharOnScreen(handle) then
                    local vecX, vecY, vecZ = getBodyPartCoordinates(3, handle)
                    local centerX, centerY = convert3DCoordsToScreen(get_crosshair_position())
                    local posX, posY = convert3DCoordsToScreen(vecX, vecY, vecZ)
                    if posX > (centerX + radius) or posY > (centerY + radius) or posX < (centerX - radius) or posY < (centerY - radius) then result = false else result = true end
                    if result then return i end
                end
            end
        end
    end
    return -1
end

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
Пример использования:
Lua:
local iID = GetPlayerTarget(300)
Описание: функция для нацеливания на координаты, взято из сурсов собейта.
Lua:
function targetAtCoords(x, y, z)
    local cx, cy, cz = getActiveCameraCoordinates()

    local vect = {
        fX = cx - x,
        fY = cy - y,
        fZ = cz - z
    }

    local screenAspectRatio = representIntAsFloat(readMemory(0xC3EFA4, 4, false))
    local crosshairOffset = {
        representIntAsFloat(readMemory(0xB6EC10, 4, false)),
        representIntAsFloat(readMemory(0xB6EC14, 4, false))
    }

    -- weird shit
    local mult = math.tan(getCameraFov() * 0.5 * 0.017453292)
    fz = 3.14159265 - math.atan2(1.0, mult * ((0.5 - crosshairOffset[1]) * (2 / screenAspectRatio)))
    fx = 3.14159265 - math.atan2(1.0, mult * 2 * (crosshairOffset[2] - 0.5))

    local camMode = readMemory(0xB6F1A8, 1, false)

    if not (camMode == 53 or camMode == 55) then -- sniper rifle etc.
        fx = 3.14159265 / 2
        fz = 3.14159265 / 2
    end

    local ax = math.atan2(vect.fY, -vect.fX) - 3.14159265 / 2
    local az = math.atan2(math.sqrt(vect.fX * vect.fX + vect.fY * vect.fY), vect.fZ)

    setCameraPositionUnfixed(az - fz, fx - ax)
end

Пример использования:
Lua:
-- СЛИВ ПРИВАТ АИМА
while true do
    wait(1)
    if isKeyDown(1) then
        local _, ped = storeClosestEntities(1)
        if ped ~= -1 then
            local x, y, z = getCharCoordinates(ped)
            targetAtCoords(x, y, z)
        end
    end
end
Без Crosshair Offset, корректно работает без широкоэкранного режима
Lua:
function TurnCamTo(coordX, coordY, coordZ)
    local camX, camY, camZ = getActiveCameraCoordinates()
    local vector = {
        fX = camX - coordX,
        fY = camY - coordY,
        fZ = camZ - coordZ
    }
    local AngleX = math.atan2(vector.fY, -vector.fX) - (math.pi / 2)
    local AngleZ = math.atan2(math.sqrt((vector.fX * vector.fX) + (vector.fY * vector.fY)), -vector.fZ)
    local FIXED_X = AngleX - (math.pi / 2 + 0.04)
    local FIXED_Z = AngleZ - (math.pi / 2 - 0.103)
    setCameraPositionUnfixed(-FIXED_Z, -FIXED_X)
end
 
Последнее редактирование:

ШPEK

Известный
1,474
525
Описание: fps unlock
Lua:
local memory = require("memory")

function fpsUnlock(status)
    if isSampLoaded() then
        memory.setuint8(getModuleHandle("samp.dll") + 0x9D170, status and 0xC3 or 0x51, true)
    end
end
Пример использования:
Lua:
function main()
    while not isSampAvailable() do wait(1000) end
    sampRegisterChatCommand("fpsunlock", function(param) local stat = tonumber(param) ~= 0 fpsUnlock(stat) sampAddChatMessage(stat and "включен" or "выключен", -1) end)
    wait(-1)
end
 

ШPEK

Известный
1,474
525
Описание: Удаление клиентской команды по названию
Lua:
local memory = require("memory")

function deleteClientCommand(name)
    local input = sampGetInputInfoPtr()
    local c = memory.getuint8(input + 0x14DC)
    local nc
    for i = 0, 143 do
        if memory.tostring(input + 0x24C + i * 0x21) == name then
            nc = i 
            break 
        end
    end
    if not nc then return false end
    local addr = input + 0x24C + nc * 0x21
    memory.fill(addr, 0, 0x21)
    memory.copy(addr, addr + 0x21, (143 - nc) * 0x21)
    local addr = input + 0xC + nc * 0x4
    memory.fill(addr, 0, 4)
    memory.copy(addr, addr + 4, (143 - nc) * 4)
    memory.setuint8(input + 0x14DC, c - 1)
    memory.fill(input + 0x24C + c * 0x21, 0, 0x21)
    memory.setuint32(input + 0xC + c * 0x4, 0)
    return true
end
 
Последнее редактирование:

savvin

Известный
406
139
Описание: расчет расстояния Левенштейна
Lua:
function string.levenshtein(string1, string2)
    local string1_len = string.len(string1)
    local string2_len = string.len(string2)
    local matrix = {}
    local cost = 0
 
    if (string1_len == 0) then
        return string2_len
    elseif (string2_len == 0) then
        return string1_len
    elseif (string1 == string2) then
        return 0
    end
 
    for i = 0, string1_len, 1 do
        matrix[i] = {}
        matrix[i][0] = i
    end
    for j = 0, string2_len, 1 do
        matrix[0][j] = j
    end
 
    for i = 1, string1_len, 1 do
        for j = 1, string2_len, 1 do
            if (string1:byte(i) == string2:byte(j)) then
                cost = 0
            else
                cost = 1
            end
         
            matrix[i][j] = math.min(matrix[i-1][j] + 1, matrix[i][j-1] + 1, matrix[i-1][j-1] + cost)
        end
    end
 
    return matrix[string1_len][string2_len]
end


Описание: замена слов по алгоритму Левенштейна (нуждается в функции выше)
Lua:
function string.levreplace(input, var)
    local shortest = -1

    for _, word in ipairs(var) do
        local lev = string.levenshtein(input, word);
     
        if lev == 0 then
            shortest = 0
        end
     
        if lev <= shortest or shortest < 0 then
            shortest = lev
        end
    end
 
    return word
end
Пример использования:
Lua:
local input = 'carrrot'
local words =
{
    'apple', 'pineapple', 'banana', 'orange',
    'radish', 'carrot', 'pea', 'bean', 'potato'
}

print(string.levreplace(input, words)) -- "carrot"
 

ImPasha

Software Developer & System Administrator
Друг
1,789
2,141
Описание: Функции позволяют приводить к верхнему и нижнему регистру кириллические символы, аналог функции от qrlk. Сложно назвать большое количество преимуществ данной функции перед её аналогом, но вот некоторые из них: простота редактирования, возможность добавить символы; скорость обработки.
Lua:
local russian_chars = {
  ['а']='А',['б']='Б',['в']='В',['г']='Г',['д']='Д', ['е']='Е',['ё']='Ё',['ж']='Ж',['з']='З',['и']='И',['э']='Э',
  ['й']='Й',['к']='К',['л']='Л', ['м']='М',['н']='Н', ['о']='О',['п']='П',['р']='Р',['с']='С',['т']='Т',['ю']='Ю',
  ['у']='У', ['ф']='Ф',['х']='Х',['ц']='Ц',['ч']='Ч', ['ш']='Ш',['щ']='Щ',['ъ']='Ъ',['ы']='Ы', ['ь']='Ь',['я']='Я'
}
local str = {lower = nil, upper = nil}
str.lower = function(string)
  if string == nil or type(string) ~= 'string' then return false end
  local char = {} local inverted = {}
  for index = 1, #string do table.insert(char, string:sub(index, index)) end
  for key, value in pairs(russian_chars) do inverted[value] = key end
  for index, value in ipairs(char) do
    if not inverted[value] then char[index] = string.lower(value)
    else char[index] = inverted[value] end
  end return table.concat(char)
end
str.upper = function(string)
  if string == nil or type(string) ~= 'string' then return false end
  local char = {}
  for index = 1, #string do table.insert(char, string:sub(index, index)) end
  for index, value in ipairs(char) do
    if not russian_chars[value] then char[index] = string.upper(value)
    else char[index] = russian_chars[value] end
  end return table.concat(char)
end
Пример использования:
Однострочный текст:
print(str.lower("ВсЕм ПрИвЕт!"))
print(str.upper("ВсЕм ПрИвЕт!"))
Многострочный текст:
print(str.lower([[
  ВсЕм ПрИвЕт!
  Как ваши дела?
]]))
print(str.upper([[
  ВсЕм ПрИвЕт!
  Как ваши дела?
]]))
Тестирование обоих систем, скриншот
 
  • Нравится
Реакции: maestto, RTD и AnWu

cover

Известный
Проверенный
245
268
Описание: Пропинговка SA:MP сервера
Lua:
local socket = require("socket")
local bit32 = require("bit")

function ping(ip, port)
    local data
    local commonPattern = generateCommonPattern(ip, port)
    local udp = socket.udp()
    udp:settimeout(3)
    udp:setsockname("*", 0)
    --
    udp:sendto(commonPattern .. "i", ip, port)
    data = udp:receive() -- optional
    print(data) -- optional
    --
    udp:sendto(commonPattern .. "p" .. "aaaa", ip, port)
    data = udp:receive() -- optional
    print(data) -- optional
    --
    udp:sendto(commonPattern .. "c", ip, port)
    data = udp:receive() -- optional
    print(data) -- optional
    --
    udp:sendto(commonPattern .. "r", ip, port)
    data = udp:receive() -- optional
    print(data) -- optional
    --
    udp:close()
end

function generateCommonPattern(ip, port)
    local separatedIp = explode(".", ip)
    local firstPortByte = bit32.band(port, 0xFF)
    local secondPortByte = bit32.band(bit32.rshift(port, 8), 0xFF)
    return "SAMP" ..
        string.char(separatedIp[1]) ..
            string.char(separatedIp[2]) ..
                string.char(separatedIp[3]) ..
                    string.char(separatedIp[4]) ..
                        string.char(firstPortByte) .. string.char(secondPortByte)
end

function explode(div, str)
    if (div == "") then
        return false
    end
    local pos, arr = 0, {}
    for st, sp in function()
        return string.find(str, div, pos, true)
    end do
        table.insert(arr, string.sub(str, pos, st - 1))
        pos = sp + 1
    end
    table.insert(arr, string.sub(str, pos))
    return arr
end
Пример использования:
Lua:
local ip, port = sampGetCurrentServerAddress()
ping(ip, port)
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
аналог функции от qrlk
40189


да и вот более простой вариант, да и ещё в 2 раза быстрее
Lua:
local lower, sub, char, upper = string.lower, string.sub, string.char, string.upper
local concat = table.concat

-- initialization table
local lu_rus, ul_rus = {}, {}
for i = 192, 223 do
    local A, a = char(i), char(i + 32)
    ul_rus[A] = a
    lu_rus[a] = A
end
local E, e = char(168), char(184)
ul_rus[E] = e
lu_rus[e] = E

function string.nlower(s)
    s = lower(s)
    local len, res = #s, {}
    for i = 1, len do
        local ch = sub(s, i, i)
        res[i] = ul_rus[ch] or ch
    end
    return concat(res)
end

function string.nupper(s)
    s = upper(s)
    local len, res = #s, {}
    for i = 1, len do
        local ch = sub(s, i, i)
        res[i] = lu_rus[ch] or ch
    end
    return concat(res)
end

40192
40193
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,650
2,535
Описание: Функция из сообщения:
Узнаем что за проц стоит у юзера

Lua:
local ffi = require("ffi")
local qwords = ffi.typeof("uint64_t[?]")
local dwords = ffi.typeof("uint32_t *")
local cpuid_EAX_EDX = ffi.cast("__cdecl uint64_t (*)(uint32_t)", "\x53\x0F\xA2\x5B\xC3")
local cpuid_EBX_ECX = ffi.cast("__cdecl uint64_t (*)(uint32_t)", "\x53\x0F\xA2\x91\x92\x93\x5B\xC3")

local function cpuid(n)
   local arr = ffi.cast(dwords, qwords(2, cpuid_EAX_EDX(n), cpuid_EBX_ECX(n)))
   return ffi.string(arr, 4), ffi.string(arr + 2, 4), ffi.string(arr + 3, 4), ffi.string(arr + 1, 4)
end

local s1 = ""
for n = 0x80000002, 0x80000004 do
   local eax, ebx, ecx, edx = cpuid(n)
   s1 = s1..eax..ebx..ecx..edx
end
s1 = s1:gsub("^%s+", ""):gsub("%z+$", "")

local eax, ebx, ecx, edx = cpuid(0)
local s2 = ebx..edx..ecx
s2 = s2:gsub("^%s+", ""):gsub("%z+$", "")

---Результат
print(s1.." "..s2)  -- Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz GenuineIntel
Могла крашить у некоторых человек, функция, которая от меня, в теории должна не крашить за счёт получения информации напрямую из реестра и гораздо короче:
Lua:
function getProcessorName()
    local handle = io.popen('reg.exe QUERY HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0 /v ProcessorNameString')
    local result = handle:read("*a")
    local processor_name = result:match('REG_SZ%s+(.+)'):gsub('%s+$', '')
    handle:close()
    return processor_name
end
Пример использования:
Lua:
print(getProcessorName())
-- Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz





Описание: Получение серийного ключа самого жёсткого диска (не логического)
Lua:
function getHarddiskSerial()
    local handle = io.popen('wmic diskdrive get serialnumber')
    local result = handle:read("*a")
    local serial = result:match('SerialNumber%s+(%d+)')
    handle:close()
    return serial
end
Пример использования:
Lua:
print(getHarddiskSerial())
-- 31297901273561723 (цифры рандомно ввёл, у вас же данные у каждого пользователя должны быть статические (не будут меняться, но у каждого должны быть индивидуальные цифры), и да, он такой же длинный.
 
Последнее редактирование:

ШPEK

Известный
1,474
525
Описание: перевод числа шестнадцатеричной/десятичной системы в двоичную
Lua:
function toBinary(dec, bits)
    local bin = ""
    for i = bits - 1, 0, -1 do
        bin = bin..bit.band(bit.rshift(dec, i), 1)
    end
    return bin 
end
Пример использования:
Lua:
local events = require("samp.events")

function events.onSendPlayerSync(data)
    sampAddChatMessage(toBinary(data.keysData, 2*8).." "..data.keysData, -1)
end