Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

[ARZ/SAMP] Что-же такое Pawn.RakNet?

Авг
2
0
Пользователь
Pawn.RakNet в ARZ/SAMP: краткое руководство

Что такое Pawn.RakNet?

Pawn.RakNet — это библиотека, позволяющая перехватывать, анализировать и модифицировать сетевой трафик между клиентом и сервером в SA-MP (в частности Arizona RP). Она даёт доступ к низкоуровневым пакетам и RPC (Remote Procedure Calls), что используется для создания кастомных функций, античитов или анализа данных.

Типы перехватываемых пакетов
Основные типы пакетов, с которыми приходится работать:
  • PR_INCOMING_PACKET / PR_INCOMING_RPC — трафик от сервера к клиенту.
  • PR_OUTGOING_PACKET / PR_OUTGOING_RPC — трафик от клиента к серверу.
Базовые типы данных в пакетах
Данные в пакетах представлены последовательностью байт. Основные типы для чтения:
  • PR_INT8 / PR_UINT8: 1 байт. INT8 (-128..127), UINT8 (0..255).
  • PR_INT16 / PR_UINT16: 2 байта. INT16 (-32768..32767), UINT16 (0..65535).
  • PR_INT32 / PR_UINT32: 4 байта. INT32 (±2.1 млрд), UINT32 (0..4.3 млрд).
  • PR_FLOAT: 4 байта (числа с плавающей точкой, например, координаты).
  • PR_BOOL: 1 байт (0 = false, любое другое значение, часто 128 = true).
  • PR_STRING: строка символов. Важно: перед строкой обычно указывается её длина (например, UINT16), а сама строка может завершаться нулевым байтом.
Как разбирать пакеты с помощью Lua (на примере Arizona RP)
Используется библиотека RakLua. Алгоритм:
  1. Регистрируем обработчик для нужного типа трафика.
  2. Проверяем ID пакета.
  3. Последовательно читаем данные, зная их тип и порядок.
Пример 1: Перехват интерфейса (ExecuteEvent)
RakLua.registerHandler(RakLuaEvents.INCOMING_PACKET, function(id, bs)
if id == 220 then
bs:skipBytes(1)
local customId = bs:readUInt8()

if customId == 17 then -- PR_SendInterface / ExecuteEvent
local browserId = bs:readUInt32()
local strlen = bs:readUInt16()
local event_encoded = bs:readUInt8()
local str

if event_encoded ~= 0 then
str = bs:readEncoded(strlen + 1)
else
str = bs:readString(strlen)
end


sampAddChatMessage(string.format('RakLuaEvents.INCOMING_PACKET(%i)[PR_SendInterface] -> browserId %i && text_len %i && text %s', customId, browserId, strlen, str), -1)
print(string.format('PR_SendInterface(playerid, {%i}, "%s")', browserId, str))
end
end
end)
Пример 2: Метод подбора (дым машины)
Допустим, вы обнаружили пакет с customId = 139. Методом перебора типов данных можно определить его структуру:
elseif customId == 139 then
local vehicleid = bs:readUInt16()
local intensity = bs:readFloat() -- по стандарту в любых модах аризоны нет полностью разобранного пакета.
local r = bs:readUInt8()
local g = bs:readUInt8()
local b = bs:readUInt8()


sampAddChatMessage(string.format('RakLuaEvents.INCOMING_PACKET(%i)[onArizonaSetVehicleColorSmoke] -> vehicleid %i && color %f && r %i && g %i && b %i', customId, vehicleid, value, r, g, b), -1)
print(string.format('onArizonaSetVehicleColorSmoke(playerid, %i, %f, %i, %i, %i)', vehicleid, value, r, g, b))
Готовый скрипт для начала работы
require "lib.moonloader"
local RakLua = require 'RakLua'
function main()
RakLua.registerHandler(RakLuaEvents.INCOMING_PACKET, function(id, bs)
if id == 220 then
bs:skipBytes(1)
local customId = bs:readUInt8()
if customId == 17 then
local browserId = bs:readUInt32()
local strlen = bs:readUInt16()
local event_encoded = bs:readUInt8()
local str

if event_encoded ~= 0 then
str = bs:readEncoded(strlen + 1)
else
str = bs:readString(strlen)
end
if not str then
str = "(decode failed)"
end
sampAddChatMessage(string.format('RakLuaEvents.INCOMING_PACKET(%i)[PR_SendInterface] -> browserId %i && text_len %i && text %s', customId, browserId, strlen, str), -1)
print(string.format('PR_SendInterface(playerid, {%i}, "%s")', browserId, str))
elseif customId == 139 then
local vehicleid = bs:readUInt16()
local intensity = bs:readFloat()
local r = bs:readUInt8()
local g = bs:readUInt8()
local b = bs:readUInt8()
sampAddChatMessage(string.format('RakLuaEvents.INCOMING_PACKET(%i)[onArizonaSetVehicleColorSmoke] -> vehicleid %i && color %f && r %i && g %i && b %i', customId, vehicleid, value, r, g, b), -1)
print(string.format('onArizonaSetVehicleColorSmoke(playerid, %i, %f, %i, %i, %i)', vehicleid, value, r, g, b))
end
end
end)
RakLua.registerHandler(RakLuaEvents.INCOMING_RPC, function(id, bs)
if id == 93 then
local color, len = bs:readUInt32(), bs:readUInt32()
local message = bs:readString(len)
print(string.format('SendClientMessage(playerid, 0x%x, "%s")', color, message))
elseif id == 61 then
local dId = bs:readUInt16()
local dType, dTitle_len = bs:readUInt8(), bs:readUInt8()
local dTitle = bs:readString(dTitle_len)
local dButton_1_len = bs:readUInt8()
local dButton_1 = bs:readString(dButton_1_len)
local dButton_2_len = bs:readUInt8()
local dButton_2 = bs:readString(dButton_2_len)
local dText = bs:readEncoded(4096)
print(string.format('ShowPlayerDialog(playerid, %i, %i, "%s", "%s", "%s", "%s")', dId, dType, dTitle, dText, dButton_1, dButton_2))
elseif id == 171 then
bs:skipBytes(2)
local skinId = bs:readUint32()
local x, y, z, a = bs:readFloat(), bs:readFloat(), bs:readFloat(), bs:readFloat()
print(string.format('skin = %d & pos [ %f, %f, %f, %f ]', skinid, x, y, z, a))
sampAddChatMessage(string.format('skin = %d & pos [ %f, %f, %f, %f ]', skinid, x, y, z, a), -1)
end
end)
end

Всем желаю удачи. Посторался над постом и потратил много времени.
 
Сверху