Исходник Гайд [LUA] Делаем рванку за 5 минут [2 часть]

Thanks @krim, шо когда-то объяснил мне это.

Салам. В этой статье я покажу вам, как можно сделать рванку с ног с помощью отправки фейковой синхронизации.



В прошлом гайде я показал, как можно хукнуть исходящий пакет PACKET_VEHICLE_SYNC. В этом же гайде я покажу как можно легко отправить пакет PACKET_PLAYER_SYNC с помощью специальной функции и сделать из этого рванку с ног на людей в радиусе.

Как и в первой части гайда, нам необходимо создать переключатель и команду активации и деактивации:
Lua:
local rvanka = false -- по умолчанию рванка будет оффнута

sampRegisterChatCommand("hz", function() rvanka = not rvanka printStringNow(rvanka and "OnFoot rvanka - ~g~ON" or "OnFoot rvanka - ~r~OFF", 1500) end)
 -- т.к. функция команды содержит только 2 действия, сделаем все в 1 строке

Создаем бесконечный цикл в main() который будет выполняться, пока скрипт действует.
Lua:
while true do wait(150) -- создаем цикл, который всегда будет true и ставим задержку 150 мс (можно ставить задержку больше, но так и кд между отправкой пакетов будет больше), чтобы игра не вылетела
    -- тут будут наши жостки махинации
end


В созданном цикле делаем проверку на наш переключатель и находится ли наш персонаж в машине.
Lua:
while true do wait(150)
    if rvanka then -- если наш переключатель == true
        if isCharInAnyCar(PLAYER_PED) then -- если наш персонаж сидит в машине
            rvanka = false -- оффаем рванку
            sampAddChatMessage("Выйди с машины, дэбил", -1) -- сообщаем об этом в чат
        else -- если мы не в машине
            -- тут шалить будем
        end
    end
end

Теперь нам надо получить игрока в определенном радиусе с помощью специальной функции.
Lua:
while true do wait(150)
    if rvanka then
        if isCharInAnyCar(PLAYER_PED) then
            rvanka = false
            sampAddChatMessage("Выйди с машины, дэбил", -1)
        else
            for _, id in pairs(search(20)) do -- перебираем всех игроков в радиусе 20 метров и получаем их ID с помощью функции search(radius), которая принимает 1 аргумент - радиус
                -- тут штэ-то будет
            end
        end
    end
end

-- вне мейна вставляем функцию поиска игрока (взято из темы с полезными сниппетами и функциями, поэтому вам необязательно понимать как она устроена)

function search(radius)
    local inSphere = {} -- создается пустая таблица
    if not radius then return {} end
    local Mx, My, Mz = getCharCoordinates(PLAYER_PED) -- получаем наши коорды
    for k,v in pairs(getAllChars()) do -- перебираем всех игроков
        local x, y, z = getCharCoordinates(v) -- получаем их координаты

        if getDistanceBetweenCoords3d(Mx, My, Mz, x, y, z) <= tonumber(radius) and v ~= 1 then -- если дистанция от нас до игрока меньше указанной в аргументе
            local result, id = sampGetPlayerIdByCharHandle(v) -- получаем id игроков

            if result and not isCharDead(v) and not sampIsPlayerNpc(id) then -- если получили ID и игрок не мертвый и он не является НПС
                inSphere[#inSphere + 1] = id -- добавляем в таблицу ID игроков.
            end
        end
    end

    return inSphere -- возвращаем таблицу с ID ближайших игроков
end

С помощью полученного ID, мы получаем координаты игрока.
Lua:
while true do wait(150)
    if rvanka then
        if isCharInAnyCar(PLAYER_PED) then
            rvanka = false
            sampAddChatMessage("Выйди с машины, дэбил", -1)
        else
            for _, id in pairs(search(20)) do
                local x,y,z = getCharCoordinates(select(2,sampGetCharHandleBySampPlayerId(id))) -- получаем координаты с помощью хэндла, который мы узнали по ID
                printStringNow("Pizdim: Name - ~r~" .. sampGetPlayerNickname(id) .. "~w~, ID - ~r~" .. id, 200)
                sendPacketSync(x,y,z)
            end
        end
    end
end

Переходим к самой отправке пакета. Для этого нам нужна функция FYP'a, которая отправляет нужную нам синхру.
Lua:
function sendPacketSync(posX,posY,posZ) -- создаем функцию, в которой мы будем указывать что мы хотим отправить
    local data = samp_create_sync_data("player") -- с помощью функции Фипа объявляем объект data структуры stOnFootData
    data.position = {posX,posY,posZ - 0.7} -- обращаемся к data и указываем массив с координатами, на которых мы будем находиться для сервера
    data.quaternion[2] = math.random(0.00, 1.00) -- ставим рандомный кватернион вращения по Y для нашего персонажа
    data.moveSpeed = {0,0,1} -- устанавливаем мувспид по Z - 1, чтобы наш пед взлетал вверх из под игрока
    data.send() -- отправляем пакет на сервер
end

function samp_create_sync_data(sync_type, copy_from_player) -- функция Фипа
    local ffi = require 'ffi'
    local sampfuncs = require 'sampfuncs'
    local raknet = require 'samp.raknet'
    require 'samp.synchronization'
    copy_from_player = copy_from_player or true
    local sync_traits = {
        player = {'PlayerSyncData', raknet.PACKET.PLAYER_SYNC, sampStorePlayerOnfootData},
        vehicle = {'VehicleSyncData', raknet.PACKET.VEHICLE_SYNC, sampStorePlayerIncarData},
        passenger = {'PassengerSyncData', raknet.PACKET.PASSENGER_SYNC, sampStorePlayerPassengerData},
        aim = {'AimSyncData', raknet.PACKET.AIM_SYNC, sampStorePlayerAimData},
        trailer = {'TrailerSyncData', raknet.PACKET.TRAILER_SYNC, sampStorePlayerTrailerData},
        unoccupied = {'UnoccupiedSyncData', raknet.PACKET.UNOCCUPIED_SYNC, nil},
        bullet = {'BulletSyncData', raknet.PACKET.BULLET_SYNC, nil},
        spectator = {'SpectatorSyncData', raknet.PACKET.SPECTATOR_SYNC, nil}
    }
    local sync_info = sync_traits[sync_type]
    local data_type = 'struct ' .. sync_info[1]
    local data = ffi.new(data_type, {})
    local raw_data_ptr = tonumber(ffi.cast('uintptr_t', ffi.new(data_type .. '*', data)))
    if copy_from_player then
        local copy_func = sync_info[3]
        if copy_func then
            local _, player_id
            if copy_from_player == true then
                _, player_id = sampGetPlayerIdByCharHandle(PLAYER_PED)
            else
                player_id = tonumber(copy_from_player)
            end
            copy_func(player_id, raw_data_ptr)
        end
    end
    local func_send = function()
        local bs = raknetNewBitStream()
        raknetBitStreamWriteInt8(bs, sync_info[2])
        raknetBitStreamWriteBuffer(bs, raw_data_ptr, ffi.sizeof(data))
        raknetSendBitStreamEx(bs, sampfuncs.HIGH_PRIORITY, sampfuncs.UNRELIABLE_SEQUENCED, 1)
        raknetDeleteBitStream(bs)
    end
    local mt = {
        __index = function(t, index)
            return data[index]
        end,
        __newindex = function(t, index, value)
            data[index] = value
        end
    }
    return setmetatable({send = func_send}, mt)
end

Функция sendPacketSync будет вызываться в бесконечном цикле с такими значениями аргументов:
Lua:
while true do wait(150)
    if rvanka then
        if isCharInAnyCar(PLAYER_PED) then
            rvanka = false
            sampAddChatMessage("Выйди с машины, дэбил", -1)
        else
            for _, id in pairs(search(20)) do
                local x,y,z = getCharCoordinates(select(2,sampGetCharHandleBySampPlayerId(id)))
                printStringNow("Pizdim: Name - ~r~" .. sampGetPlayerNickname(id) .. "~w~, ID - ~r~" .. id, 200)
                sendPacketSync(x,y,z) -- вызываем функцию с аргументами x,y,z, который обозначают координаты жертвы
            end
        end
    end
end

Также мы добавим ноп на изменение нашей позиции сервером
Lua:
local ev = require ("lib.samp.events") -- загружаем библиотеку, для перехвата пакетов и РПС

function ev.onSetPlayerPos() -- создаем хук, который будет отлавливать попытки изменить нашу позицию сервером
    if rvanka then return false end -- если рванка включена, запрещаем серверу менять нашу позицию
end

В итоге у нас должно получиться что-то типа такого:
Lua:
----------------directives----------------

script_author('Ega')
script_name('OnFoot rvanka')

----------------lib----------------

require ("lib.moonloader")
local ev = require ("lib.samp.events")

----------------variables----------------

local rvanka = false

----------------main----------------

function main()
    if not isSampAvailable() then return false end

    sampRegisterChatCommand("hz", function() rvanka = not rvanka printStringNow(rvanka and "OnFoot rvanka - ~g~ON" or "OnFoot rvanka - ~r~OFF", 1500) end)

----------------while true----------------

    while true do wait(150)
        if rvanka then
            if isCharInAnyCar(PLAYER_PED) then
                rvanka = false
                sampAddChatMessage("Выйди с машины, дэбил", -1)
            else
                for _, id in pairs(search(20)) do
                    local x,y,z = getCharCoordinates(select(2,sampGetCharHandleBySampPlayerId(id)))
                    printStringNow("Pizdim: Name - ~r~" .. sampGetPlayerNickname(id) .. "~w~, ID - ~r~" .. id, 200)
                    sendPacketSync(x,y,z)
                end
            end
        end
    end
end

----------------function----------------

function sendPacketSync(posX,posY,posZ)
    local data = samp_create_sync_data("player")
    data.position = {posX,posY,posZ - 0.7}
    data.quaternion[2] = math.random(0.00, 1.00)
    data.moveSpeed = {0,0,1}
    data.send()
end

function ev.onSetPlayerPos(pos)
    if rvanka then return false end
end

function search(radius)
    local inSphere = {}
    if not radius then return {} end
    local Mx, My, Mz = getCharCoordinates(PLAYER_PED)
    for k,v in pairs(getAllChars()) do
        local x, y, z = getCharCoordinates(v)

        if getDistanceBetweenCoords3d(Mx, My, Mz, x, y, z) <= tonumber(radius) and v ~= 1 then
            local result, id = sampGetPlayerIdByCharHandle(v)

            if result and not isCharDead(v) and not sampIsPlayerNpc(id) then
                inSphere[#inSphere + 1] = id
            end
        end
    end

    return inSphere
end

function samp_create_sync_data(sync_type, copy_from_player)
    local ffi = require 'ffi'
    local sampfuncs = require 'sampfuncs'
    local raknet = require 'samp.raknet'
    require 'samp.synchronization'
    copy_from_player = copy_from_player or true
    local sync_traits = {
        player = {'PlayerSyncData', raknet.PACKET.PLAYER_SYNC, sampStorePlayerOnfootData},
        vehicle = {'VehicleSyncData', raknet.PACKET.VEHICLE_SYNC, sampStorePlayerIncarData},
        passenger = {'PassengerSyncData', raknet.PACKET.PASSENGER_SYNC, sampStorePlayerPassengerData},
        aim = {'AimSyncData', raknet.PACKET.AIM_SYNC, sampStorePlayerAimData},
        trailer = {'TrailerSyncData', raknet.PACKET.TRAILER_SYNC, sampStorePlayerTrailerData},
        unoccupied = {'UnoccupiedSyncData', raknet.PACKET.UNOCCUPIED_SYNC, nil},
        bullet = {'BulletSyncData', raknet.PACKET.BULLET_SYNC, nil},
        spectator = {'SpectatorSyncData', raknet.PACKET.SPECTATOR_SYNC, nil}
    }
    local sync_info = sync_traits[sync_type]
    local data_type = 'struct ' .. sync_info[1]
    local data = ffi.new(data_type, {})
    local raw_data_ptr = tonumber(ffi.cast('uintptr_t', ffi.new(data_type .. '*', data)))
    if copy_from_player then
        local copy_func = sync_info[3]
        if copy_func then
            local _, player_id
            if copy_from_player == true then
                _, player_id = sampGetPlayerIdByCharHandle(PLAYER_PED)
            else
                player_id = tonumber(copy_from_player)
            end
            copy_func(player_id, raw_data_ptr)
        end
    end
    local func_send = function()
        local bs = raknetNewBitStream()
        raknetBitStreamWriteInt8(bs, sync_info[2])
        raknetBitStreamWriteBuffer(bs, raw_data_ptr, ffi.sizeof(data))
        raknetSendBitStreamEx(bs, sampfuncs.HIGH_PRIORITY, sampfuncs.UNRELIABLE_SEQUENCED, 1)
        raknetDeleteBitStream(bs)
    end
    local mt = {
        __index = function(t, index)
            return data[index]
        end,
        __newindex = function(t, index, value)
            data[index] = value
        end
    }
    return setmetatable({send = func_send}, mt)
end
 
Последнее редактирование:

Musaigen

abobusnik
Проверенный
1,607
1,365
  • Нравится
Реакции: кириешки

ГОХА | GoxaShow

В АРМИИ С 12.12,ЗАКАЗЫ НЕ ДЕЛАЮ,ТУПЫЕ ВОПРОСЫ-НАХУ
Проверенный
1,890
1,907
сука, где ноп на синхру, задержку синхры я вообще молчу, чел который зайдёт с 100+ фпс отьедет от сампа, А если зайти на сервер с ач, то за секунду и кикнется сам
 

whyega52

Гений, миллионер, плейбой, долбаеб
Автор темы
Модератор
2,783
2,608
сука, где ноп на синхру
Бля, не пиздите, ща добавлю

сука, где ноп на синхру, задержку синхры я вообще молчу, чел который зайдёт с 100+ фпс отьедет от сампа, А если зайти на сервер с ач, то за секунду и кикнется сам
Добавил ноп и изменил задержку
 
Последнее редактирование:

whyega52

Гений, миллионер, плейбой, долбаеб
Автор темы
Модератор
2,783
2,608
сука, где ноп на синхру, задержку синхры я вообще молчу, чел который зайдёт с 100+ фпс отьедет от сампа, А если зайти на сервер с ач, то за секунду и кикнется сам
Ты про ноп изменения позиции сервом или про ноп исходящий синхры?
 

whyega52

Гений, миллионер, плейбой, долбаеб
Автор темы
Модератор
2,783
2,608

ГОХА | GoxaShow

В АРМИИ С 12.12,ЗАКАЗЫ НЕ ДЕЛАЮ,ТУПЫЕ ВОПРОСЫ-НАХУ
Проверенный
1,890
1,907
Знаю, писал с телефона и отпечатался.

А зачем? По-сути же ты в кд между пакетами с этим нопом просто будешь афк
так и нужно, смотри, может произойти момент типо за 5 мс для сервера ты будешь в одном месте и в другом сразу же, он тебя кикнет за быстрый тп и будет прав
 
  • Нравится
Реакции: whyega52

whyega52

Гений, миллионер, плейбой, долбаеб
Автор темы
Модератор
2,783
2,608
сделай гайд пж как на курде к челу ебашить, если он от тебя далеко(до 200м), ото сервер явно отпиздит за такие перемещения.
На синхре шоль или просто устанавливая себе корды?

@Corenale, а в чем баг-то? Напиши его хоть, чтобы исправить можно было
 
Последнее редактирование:
  • Bug
Реакции: Corenale