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

ImPasha

Software Developer & System Administrator
Друг
1,788
2,142
Описание: меняет атрибут скрытости для указанного файла (остальные атрибуты сбрасываются)
Lua:
ffi.cdef[[
  typedef unsigned long DWORD;
  typedef int BOOL;
  typedef const char *LPCSTR;

  BOOL SetFileAttributesA(
    LPCSTR lpFileName,
    DWORD  dwFileAttributes
  );
]]

function set_hidden(file_name, is_hidden, full_hidden)
  ffi.C.SetFileAttributesA(file_name, full_hidden and 0x7 or (is_hidden and 0x2 or 0x0))
end
Пример использования:
Lua:
set_hidden('any_file.txt', true, true) -- файл скрыт и не отображается даже тем, кто включил отображение скрытых файлов
set_hidden('any_file.txt', true) -- файл скрыт
set_hidden('any_file.txt', false) -- файл не скрыт
да-да, делайте свои супер-крутые лоадеры, а потом продавайте их за 100 рублей
 

Bredd Lane

Известный
423
349
Описание: Описывает текущую игровую погоду.
Lua:
function getStrGameWeather()
    local current_weather = require('memory').getint8(0xC81320)
    local weather_nums = {
        ['Ясная'] = {0, 1, 2, 3, 5, 6, 10, 11, 13, 14, 17, 18, 23, 24, 25, 26, 27, 28, 29, 34},
        ['Облачная'] = {4, 7, 12, 15, 33, 35, 36, 37, 40, 41, 42},
        ['Дождливая'] = {8, 9, 16},
        ['Темная'] = {20, 21, 22, 30, 31, 32, 38, 39, 43, 44, 45},
        ['Штормовая'] = {19}
    }
    for k, v in pairs(weather_nums) do
        for m, n in pairs(v) do
            if n == current_weather then
                return k
            end
        end
    end
    return 'Неизвестно ('..current_weather..'-ая)'
end
Пример использования:
Lua:
sampAddChatMessage('Погода в вашем регионе: '..getStrGameWeather(), -1)
 

ImPasha

Software Developer & System Administrator
Друг
1,788
2,142
Здесь такое дело: по какой-то причине я думал, что tonumber, в случае передачи в него строки с мусором в виде лишних символов, достанет все числа из этой строки и вернёт адекватный вариант. Оказалось, что я перепутал язык программирования и Lua такие фокусы делать не умеет делать. Не знаю как остальным, но лично мне была бы полезна такая функция, и несмотря на то, что сделать её сможет каждый, кто хотя бы пару дней пишет на Lua, решил её выложить сюда.

Описание: извлекает из строки все числовые значения, соединяет их вместе (не складывает!) и выводит конечный результат.

Lua:
local tonumber_orig = tonumber
function tonumber(str, base, def)
  if def then return tonumber_orig(str, base) end
  local buffer = ""
  for out in str:gmatch('%d+') do
    buffer = buffer .. out
  end
  return tonumber_orig(buffer, base) or 0
end
Пример использования:
Lua:
print(tonumber('ghgfh534gfhfgh435hfgh')) -- результат: 534435
print(tonumber('ghgfh534gfhfgh435hfgh', nil, true)) -- результат: nil

-- если передавать третьим аргументом true,
-- будет использоваться оригинальная функция tonumber

На этом всё, можете кидаться камнями и помидорами!
Либо можно использовать этот вариант:

Lua:
return tonumber((str:gsub('%D', '')), base)
 

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Здесь такое дело: по какой-то причине я думал, что tonumber, в случае передачи в него строки с мусором в виде лишних символов, достанет все числа из этой строки и вернёт адекватный вариант. Оказалось, что я перепутал язык программирования и Lua такие фокусы делать не умеет делать. Не знаю как остальным, но лично мне была бы полезна такая функция, и несмотря на то, что сделать её сможет каждый, кто хотя бы пару дней пишет на Lua, решил её выложить сюда.

Описание: извлекает из строки все числовые значения, соединяет их вместе (не складывает!) и выводит конечный результат.

Lua:
local tonumber_orig = tonumber
function tonumber(str, def)
  if def then return tonumber_orig(str) end
  local buffer = ""
  for out in str:gmatch('%d+') do
    buffer = buffer .. out
  end
  return tonumber_orig(buffer) or 0
end
Пример использования:
Lua:
print(tonumber('ghgfh534gfhfgh435hfgh')) -- результат: 534435
print(tonumber('ghgfh534gfhfgh435hfgh', true)) -- результат: nil

-- если передавать вторым аргументом true,
--будет использоватся оригинальная функция tonumber

На этом всё, можете кидаться камнями и помидорами!
a где base?
Lua:
local buffer = ""
for out in str:gmatch('%d+') do
  buffer = buffer .. out
end
return tonumber_orig(buffer, base) or 0
Lua:
return tonumber_orig((str:gsub('%D', '')), base)
 
Последнее редактирование модератором:
  • Нравится
Реакции: kizn и ImPasha

_razor

t.me/sssecretway | ТГК: t.me/razor_code
Всефорумный модератор
1,952
3,229
Описание: Изменяет прозрачность и цвета чата SA-MP
Lua:
function sampEditChatAlpha(alpha)
    local samp = getModuleHandle("samp.dll")
    if samp ~= nil then
        memory.write(samp + 0x6392F, alpha, 4, true)
        memory.write(samp + 0x63B3B, alpha, 4, true)
        memory.write(samp + 0x63B68, alpha, 4, true)
        memory.write(samp + 0x63B94, alpha, 4, true)

        memory.write(samp + 0x6392F, alpha, 4, true)
        memory.write(samp + 0x63973, alpha, 4, true)
        memory.write(samp + 0x639AC, alpha, 4, true)
        memory.write(samp + 0x639E8, alpha, 4, true)
        memory.write(samp + 0x63A24, alpha, 4, true)
        memory.write(samp + 0x63A5D, alpha, 4, true)
        memory.write(samp + 0x63A99, alpha, 4, true)
        memory.write(samp + 0x63ADC, alpha, 4, true)
    end
end
Пример использования:
Lua:
sampEditChatAlpha(0x69000000)
sampEditChatAlpha(0x690000FF)

1604771234600.png
1604771282419.png

1604771307385.png
 

Cosmo

Известный
Друг
656
2,745
Описание:
Получает хэндл ближайшего транспорта к центру экрана
Car car = getNearCarToCenter(int radius):
function getNearCarToCenter(radius)
    local arr = {}
    local sx, sy = getScreenResolution()
    for _, car in ipairs(getAllVehicles()) do
        if isCarOnScreen(car) and getDriverOfCar(car) ~= playerPed then
            local carX, carY, carZ = getCarCoordinates(car)
            local cX, cY = convert3DCoordsToScreen(carX, carY, carZ)
            local distBetween2d = getDistanceBetweenCoords2d(sx / 2, sy / 2, cX, cY)
            if distBetween2d <= tonumber(radius and radius or sx) then
                table.insert(arr, {distBetween2d, car})
            end
        end
    end
    if #arr > 0 then
        table.sort(arr, function(a, b) return (a[1] < b[1]) end)
        return arr[1][2]
    end
    return nil
end

Описание:
Получает хэндл ближайшего игрока к центру экрана
Ped ped = getNearCharToCenter(int radius):
function getNearCharToCenter(radius)
    local arr = {}
    local sx, sy = getScreenResolution()
    for _, player in ipairs(getAllChars()) do
        if select(1, sampGetPlayerIdByCharHandle(player)) and isCharOnScreen(player) and player ~= playerPed then
            local plX, plY, plZ = getCharCoordinates(player)
            local cX, cY = convert3DCoordsToScreen(plX, plY, plZ)
            local distBetween2d = getDistanceBetweenCoords2d(sx / 2, sy / 2, cX, cY)
            if distBetween2d <= tonumber(radius and radius or sx) then
                table.insert(arr, {distBetween2d, player})
            end
        end
    end
    if #arr > 0 then
        table.sort(arr, function(a, b) return (a[1] < b[1]) end)
        return arr[1][2]
    end
    return nil
end

Использование:
Lua:
local player = getNearCharToCenter(150) -- 150 это радиус на экране (в пикселях) а не в 3d пространстве относительно вас
if player then
    local playerId = select(2, sampGetPlayerIdByCharHandle(player))
    print('Ближайшй к центру игрок с ID: '..playerId)
else -- nil
    print('Ближайший к центру игрок в указаном радиусе не найден')
end

local car = getNearCarToCenter(150)
if car then
    local carId = select(2, sampGetVehicleIdByCarHandle(car))
    print('Ближайшее к центру атво с ID: '..carId)
else -- nil
    print('Ближайшее к центру авто в указаном радиусе не найдено')
end

Пример реализации:
 

etereon

MQ-Team
Проверенный
329
854
Описание: получает модель пикапа по его ID (в 0.27 уже есть такая функиця).
Lua:
PICKUP_POOL = sampGetPickupPoolPtr() -- после инициализации сампа

function get_pickup_pool(id)
    return ffi.cast("int *", (id * 20 + 61444) + PICKUP_POOL)[0]
end
 
Последнее редактирование:

_razor

t.me/sssecretway | ТГК: t.me/razor_code
Всефорумный модератор
1,952
3,229
Описание: Изменяет местоположение диалога который находиться в данный момент на экране.
Lua:
function setCurrentDialogPosition(x, y)
    local CDialog = memory.getuint32(getModuleHandle("samp.dll") + 0x21A0B8)
    local CDXUTDialog = memory.getuint32(CDialog + 0x1C)

    memory.write(CDialog + 0x04, x, 4, true)
    memory.write(CDialog + 0x08, y, 4, true)

    memory.write(CDXUTDialog + 0x116, x, 4, true)
    memory.write(CDXUTDialog + 0x11A, y, 4, true)
end
Пример использования:
Lua:
local posX, posY = getCursorPos()
setCurrentDialogPosition(posX, posY)
-- будет передвигать диалог за курсором
1605553472565.png
 

kizn

q(≧▽≦q)
Всефорумный модератор
2,409
2,101
Описание: узнаёт ID игрока по нику.
Lua:
function sampGetPlayerIdByNickname(nick)
    local _, myid = sampGetPlayerIdByCharHandle(playerPed)
    if tostring(nick) == sampGetPlayerNickname(myid) then return myid end
    for i = 0, 1000 do if sampIsPlayerConnected(i) and sampGetPlayerNickname(i) == tostring(nick) then return i end end
end
Пример использования:
Lua:
sampRegisterChatCommand('idn', function(text)
    local id = sampGetPlayerIdByNickname(text)
    if id then print(text..'['..id..']') end
end)
Делает лишние переборы, если на сервере не 1000 игроков. Вот вариант по максимальному количеству игроков на сервере:

Описание: узнает ID игрока по нику (измененная версия функции @imring)

Lua:
function sampGetPlayerIdByNickname(nick)
    local result, id = sampGetPlayerIdByCharHandle(PLAYER_PED)
    if nick == sampGetPlayerNickname(id) then return id end
    for i = 0, sampGetMaxPlayerId(false) do
        if sampIsPlayerConnected(i) and sampGetPlayerNickname(i) == nick then return i end
    end
end

Пример использования:

Lua:
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand('getId', function(arg) -- /getId nick
        if sampGetPlayerIdByNickname(arg) then
            print(sampGetPlayerIdByNickname(arg))
        end
    end)
    wait(-1)
end

function sampGetPlayerIdByNickname(nick)
    local result, id = sampGetPlayerIdByCharHandle(PLAYER_PED)
    if nick == sampGetPlayerNickname(id) then return id end
    for i = 0, sampGetMaxPlayerId(false) do
        if sampIsPlayerConnected(i) and sampGetPlayerNickname(i) == nick then return i end
    end
end
 
  • Нравится
Реакции: gaZmanoV

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Делает лишние переборы, если на сервере не 1000 игроков. Вот вариант по максимальному количеству игроков на сервере:

Описание: узнает ID игрока по нику (измененная версия функции @imring)

Lua:
function sampGetPlayerIdByNickname(nick)
    local result, id = sampGetPlayerIdByCharHandle(PLAYER_PED)
    if nick == sampGetPlayerNickname(id) then return id end
    for i = 0, sampGetMaxPlayerId(false) do
        if sampIsPlayerConnected(i) and sampGetPlayerNickname(i) == nick then return i end
    end
end

Пример использования:

Lua:
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand('getId', function(arg) -- /getId nick
        if sampGetPlayerIdByNickname(arg) then
            print(sampGetPlayerIdByNickname(arg))
        end
    end)
    wait(-1)
end

function sampGetPlayerIdByNickname(nick)
    local result, id = sampGetPlayerIdByCharHandle(PLAYER_PED)
    if nick == sampGetPlayerNickname(id) then return id end
    for i = 0, sampGetMaxPlayerId(false) do
        if sampIsPlayerConnected(i) and sampGetPlayerNickname(i) == nick then return i end
    end
end
Да, но он абсолютно равносилен. Если ты хочешь юзать получаемый ид с sampGetMaxPlayerId для цикла, то это тебя надо убивать. 2 цикла вместо одного использовать глупо.
 
  • Ха-ха
  • Нравится
  • Вау
Реакции: Sargon, kizn и kin4stat

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
  • Грустно
Реакции: kin4stat

kizn

q(≧▽≦q)
Всефорумный модератор
2,409
2,101
Описание:
Удаляет все строки с нужным текстом из текстового файла (работает с кириллицей и без)

Lua:
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

function deleteLine(filePath, text)
local tableOfLines = {}

for line in io.lines(filePath) do
    if not u8:decode(line):find(text) then
        table.insert(tableOfLines, line)
    end
end

local file = io.open(filePath, 'w')
file:write('')
file:close()

local file = io.open(filePath, 'a')
for i = 1, #tableOfLines do
    file:write(tableOfLines[i]..'\n')
end
file:close()
end

Пример использования:
Lua:
local path = getWorkingDirectory() .. '/test.txt'
deleteLine(path, 'прощай')


fK04Bsp.png
3pTVkCK.png
 

ufdhbi

Известный
Проверенный
1,460
866
Описание:
Удаляет все строки с нужным текстом из текстового файла (работает с кириллицей и без)

Lua:
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

function deleteLine(filePath, text)
local tableOfLines = {}

for line in io.lines(filePath) do
    if not u8:decode(line):find(text) then
        table.insert(tableOfLines, line)
    end
end

local file = io.open(filePath, 'w')
file:write('')
file:close()

local file = io.open(filePath, 'a')
for i = 1, #tableOfLines do
    file:write(tableOfLines[i]..'\n')
end
file:close()
end

Пример использования:
Lua:
local path = getWorkingDirectory() .. '/test.txt'
deleteLine(path, 'прощай')


fK04Bsp.png
3pTVkCK.png
Lua:
function deleteLine(filePath, text)
    local tableOfLines = {}   
    for line in io.lines(filePath) do
        if not u8:decode(line):find(text) then
            table.insert(tableOfLines, line)
        end
    end
    local file = io.open(filePath, 'w+')
    file:write(table.concat(tableOfLines), "\n")
    file:close()
end
 

_razor

t.me/sssecretway | ТГК: t.me/razor_code
Всефорумный модератор
1,952
3,229
Описание: Изменяет цвета диалогам (вызвать функцию можно один раз, цвета сохранятся)
Thanks @Stickey
Lua:
function setDialogColor(l_up, r_up, l_low, r_bottom)
    local CDialog = memory.getuint32(getModuleHandle("samp.dll") + 0x21A0B8)
    local CDXUTDialog = memory.getuint32(CDialog + 0x1C)
    memory.setuint32(CDXUTDialog + 0x12A, l_up, true) -- Left corner
    memory.setuint32(CDXUTDialog + 0x12E, r_up, true) -- Right upper corner
    memory.setuint32(CDXUTDialog + 0x132, l_low, true) -- Lower left corner
    memory.setuint32(CDXUTDialog + 0x136, r_bottom, true) -- Right bottom corner
end
Пример использования:
Lua:
setDialogColor(0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFFFF00) -- AARRGGBB format
1607372480968.png