Представляю вам RakLua.
RakLua — это новая библиотека, которая служит заменой событиям и функциям SAMPFUNCS для взаимодействия с RakNet'ом и BitStream — классом, позволяющим SAMPy отправлять/получать данные от сервера. Библиотека использует
sol3
для биндинга C++ (самой библиотеки) и самого Lua. Библиотека включает почти все возможности взаимодействия с RakNet'ом и его событиями, а ключевым моментом является одновременная поддержка SAMP 0.3.7-R1, SAMP 0.3.7-R2, SAMP 0.3.7-R3-1, SAMP 0.3.7-R4-2 и SAMP 0.3.7-R5-1, а так же отсутствие зависимости от SAMPFUNCS и CLEO (потому что SAMPFUNCS не используется).Содержание:
- Список имеющихся функций и событий
- Примеры эмуляции исходящих RPC/пакетов
- Отлавливание и обработка входящих/исходящих RPC и пакетов
GitHub: Northn/RakLua
Версия RakLua: 2.14; состояние: Stable
Установка: файлы
RakLuaDll.dll, RakLua.lua
из архива RakLua2.14.zip
, приложенного к теме, перетащить в папку *Корневая папка с игрой*/moonloader/lib
Список имеющихся функций и событий
Важная заметка: вам может быть неудобно переписывать исходный код в формат RakLua, если это так, то прочтите данный пост.
Описание | Применение в RakLua | Применение в SAMPFUNCS |
---|---|---|
Создание BitStream; удаление BitStream |
Lua:
|
Lua:
|
Получение оффсета для чтения/записи данных |
Lua:
|
Lua:
|
Установка оффсета для чтения/записи данных |
Lua:
|
Lua:
|
Сброс указателя для чтения/записи данных |
Lua:
|
Lua:
|
Игнор битов/байтов для чтения данных |
Lua:
|
Lua:
|
Получение количества использованных битов/байтов и количества непрочитанных битов/байтов |
Lua:
|
Lua:
|
Чтение данных |
Lua:
|
Lua:
|
Запись значений |
Lua:
|
Lua:
|
Отправка RPC/пакетов; Эмуляция входящих RPC/пакетов |
Lua:
|
Lua:
|
Установка обработчиков на входящие/исходящие RPC и пакеты |
Lua:
|
Lua:
|
Событие | Индекс |
---|---|
Входящие RPC | RakLuaEvents.INCOMING_RPC |
Исходящие RPC | RakLuaEvents.OUTGOING_RPC |
Входящие пакеты | RakLuaEvents.INCOMING_PACKET |
Исходящие пакеты | RakLuaEvents.OUTGOING_PACKET |
Дополнительная функция:
RakLua.getSampVersion()
, возвращает индекс исходя из перечисления:Описание | Индекс |
---|---|
SAMP не загружен (одиночная игра / SAMP не установлен) | RakLuaSampVersions.SAMP_NOT_LOADED |
Неизвестная версия SAMP (неподдерживаемая) | RakLuaSampVersions.SAMP_UNKNOWN |
Версия SAMP 0.3.7-R1 | RakLuaSampVersions.SAMP_037_R1 |
Версия SAMP 0.3.7-R3-1 | RakLuaSampVersions.SAMP_037_R3_1 |
Примеры эмуляции исходящих RPC/пакетов
Для начала, хочу подметить, что работа с BitStream производится через новый класс, предоставляемый этой библиотекой — RakLuaBitStream, однако вы можете получить оригинальный BitStream через
local bitStream = bs:getBitStream()
, но он, скорее всего, для вас является бесполезным.Давайте начнём с простого: эмуляция отправки, например, команды.
Lua:
function send_rpc_command(text)
local bs = RakLuaBitStream.new()
bs:writeInt32(text:len())
bs:writeString(text)
if bs:sendRPC(50) --[[RPC_ServerCommand в 0.3.7-R3]] then
print("RPC was sent!")
else
print("We couldn't send RPC.")
end
end
Довольно просто, не так ли? Вы также можете убрать проверку на успешность отправки RPC, поскольку если вы всё правильно записали, то оно, вероятнее всего, отправится. Также обратите внимание, что мы не удаляем BitStream, нам этого не нужно делать, этим сам SAMP позаботится.
Можем отправить какое-либо сообщение просто в чат:
Lua:
function send_text(text)
local bs = RakLuaBitStream.new()
bs:writeUInt8(text:len())
bs:writeString(text)
if bs:sendRPC(101) --[[RPC_Chat в 0.3.7-R3]] then
print("RPC was sent!")
else
print("We couldn't send RPC.")
end
end
Или написать целый
sampSendChat(text)
:
Lua:
function send_rpc_command(text)
local bs = RakLuaBitStream.new()
bs:writeInt32(text:len())
bs:writeString(text)
return bs:sendRPC(50) --[[RPC_ServerCommand в 0.3.7-R3]]
end
function send_text(text)
local bs = RakLuaBitStream.new()
bs:writeUInt8(text:len())
bs:writeString(text)
return bs:sendRPC(101) --[[RPC_Chat в 0.3.7-R3]]
end
function sampSendChat(text)
text = tostring(text)
return text:sub(1, 1) == "/" and send_rpc_command(text) or send_text(text)
end
Мы также можем отправлять пакеты, достаточно лишь заполнить его и отправить:
Lua:
local bs = RakLuaBitStream.new()
bs:writeUInt8(id) -- ID пакета
-- И заполняем необходимыми данными
bs:sendPacket()
Отлавливание и обработка входящих/исходящих RPC и пакетов
Давайте хукнем, например, всеми известные onServerMessage, onSetPlayerHealth и onSetPlayerPos из входящих RPC:
Lua:
local RakLua = require 'RakLua'
function main()
RakLua.registerHandler(RakLuaEvents.INCOMING_RPC,
function(id, bs)
if id == 93 then -- RPC_ClientMessage
local color = bs:readInt32() -- Читаем цвет
local textLen = bs:readInt32() -- Читаем длину текста
local text = bs:readString(textLen) -- Читаем сам текст
local res = onServerMessage(color, text) -- Вызываем свою функцию
if type(res) == "boolean" then -- Если тип возвращаемого значения bool
return res -- Возвращаем значение, сам обработчик уже обработает/не обработает
-- исходя из возвращаемого значения
elseif type(res) == "table" then
bs:resetWritePointer() -- Сбросим указатель записи, чтобы перезаписать всё
bs:writeInt32(res[1]) -- Запишем цвет
bs:writeInt32(res[2]:len()) -- Запишем длину текста
bs:writeString(res[2]) -- Запишем сам текст
end
elseif id == 14 then -- RPC_SetPlayerHealth
local health = bs:readFloat() -- Получим количество HP, которое сервер
-- Хочет нам установить
if health < 5 then
return false
end
elseif id == 12 then -- RPC_SetPlayerPos
local x, y, z = bs:readFloat(), bs:readFloat(), bs:readFloat()
print(string.format("Server tried to set your position at %.2f; %.2f; %.2f", x, y, z))
return false -- Проигнорируем телепортацию
end
end
)
end
function onServerMessage(color, text)
if color == -1 then
return false
elseif text == "hello" then
return true
end
return {color, "hello"}
end
Мы написали обработчик, который при получении RPC
ClientMessage
будет вызывать функцию onServerMessage
, при получении RPC SetPlayerHealth
, если сервер попытается установить HP ниже пяти, будет игнорировать, и RPC SetPlayerPos
, который будет всегда игнорировать попытку сервера телепортировать нас и будет писать в moonloader.log
соответствующую информацию.Давайте напишем обработчик на исходящие RPC:
Lua:
RakLua.registerHandler(RakLuaEvents.OUTGOING_RPC,
function(id, bs, priority, reliability, orderingChannel, shiftTimestamp)
if id == 101 then -- RPC_Chat
local textLen = bs:readUInt8()
local text = bs:readString(textLen)
local res = onSendChat(text)
if type(res) == "boolean" then
return res
elseif type(res) == "table" then
bs:resetWritePointer()
bs:writeUInt8(res[1]:len())
bs:writeString(res[1])
end
elseif id == 50 then -- RPC_ServerCommand
local cmdLen = bs:readInt32()
local cmd = bs:readString(cmdLen)
local res = onSendCommand(cmd)
if type(res) == "boolean" then
return res
elseif type(res) == "table" then
bs:resetWritePointer()
bs:writeInt32(res[1]:len())
bs:writeString(res[1])
end
end
end
)
function onSendChat(text)
if text == "hello" then
text = "bye"
elseif text == "privet" then
return false
end
return {"[Префикс] "..text}
end
function onSendCommand(cmd)
if cmd == "/help" then
cmd = "/mm"
elseif cmd == "/admins" then
return false
end
return {cmd}
end
Обработчик, при получении RPC
Chat; ServerCommand
, будет вызывать соответствующие функции и исходя из их возвращаемых аргументов действовать.Обработка исходящих пакетов:
Lua:
RakLua.registerHandler(RakLuaEvents.OUTGOING_PACKET,
function(id, bs, priority, reliability, orderingChannel)
if id == 207 then -- ID_PLAYER_SYNC
bs:ignoreBytes(35) -- or bs:skipBytes(35); пропускаем 35 байт
local hp, armor = bs:readUInt8(), bs:readUInt8()
print(string.format("I sent %d HP; %d armor.", hp, armor))
end
end
)
Если отправляем Packet
PLAYER_SYNC
, то пропускаем первые 35 байт, читаем количество здоровья, брони и выводим в moonloader.log
.Вот и всё, мы научились работать с RakLua, возможно даже что и с BitStream, раз ранее не работали.
Также хочу отметить, что поддержка с SAMP.Lua в наличии, но только начиная с версии
2.0
. Для совместимости с SAMP.Lua необходимо вызвать функцию RakLua.defineSampLuaCompatibility()
до подгрузки SAMP.Lua.Вложения
-
RakLua.zip156.6 KB · Просмотры: 260
-
RakLua1.1.zip157.2 KB · Просмотры: 35
-
RakLua1.2.zip156.8 KB · Просмотры: 28
-
RakLua1.3.zip172.7 KB · Просмотры: 129
-
RakLua2.0.zip176.6 KB · Просмотры: 48
-
RakLua2.01.zip176.4 KB · Просмотры: 88
-
RakLua2.1.zip89 KB · Просмотры: 581
-
RakLua2.11.zip103.6 KB · Просмотры: 49
-
RakLua2.12.zip104.3 KB · Просмотры: 381
-
RakLua2.13.zip104.8 KB · Просмотры: 1,719
-
RakLua2.14.zip105.7 KB · Просмотры: 109
Последнее редактирование: