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
Последнее редактирование: