SAMP.Lua

Изначально эта библиотека задумывалась как простой апи исключительно для обработки сетевых пакетов, но в процессе было решешо, что лучше бы сделать её полноценной библиотекой для работы с сампом, в будущем это позволит избавить от необходимости использования SAMPFUNCS. Пока реализован только модуль, значительно упрощающий работу с пакетами, так что говорить сейчас будем о нём.

SAMP.Events
Этот модуль добавляет событийную обработку входящих и исходящих RakNet пакетов. Имеет удобный API, полностью кастомизируем, предоставляет те же возможности, что и обычные хуки: чтение, перезапись, игнорирование.


Использование
Простой пример обработки исходящего сообщения в чат:
Lua:
local sampev = require 'lib.samp.events'

function sampev.onSendChat(msg)
  print('You said: ' .. msg)
end
Да, настолько просто. Нужно лишь загрузить библиотеку и добавить функцию с соответствующими аргументами, вот и всё.
Перезапись данных в пакете настолько же проста, нужно лишь вернуть из функции все значения в том же порядке, занеся их в таблицу.
Lua:
function sampev.onSendChat(msg)
  return {'I said: ' .. msg}
end
Будет дописывать текст "I said:" в начало каждого отправляемого сообщения.
Если вернуть из функции false, то пакет будет проигнорирован клиентом. Этот код запретит серверу изменять позицию игрока:
Lua:
function sampev.onSetPlayerPos(position)
  print(string.format('Server tried to change your position to %0.2f %0.2f %0.2f', position.x, position.y, position.z))
  return false
end
Структуры всех пакетов находятся в файле events.lua.

Перезапись исходящих пакетов синхронизации слегка отличается от всех остальных - они не требуют возврата аргументов, а вместо этого данные перезаписываются как в обычной таблице lua. Это сделано для повышения производительности.
Пример перезаписи позиции в исходящих данных синхронизации игрока:
Lua:
function sampev.onSendPlayerSync(data)
  print('Original position:', data.position.x, data.position.y, data.position.z)
  data.position.x = 1337
  data.position.y = 1488
  data.position.z = 228
end
Это применимо только в событиях onSendPlayerSync, onSendVehicleSync, onSendPassengerSync, onSendAimSync, onSendUnoccupiedSync, onSendTrailerSync, onSendBulletSync, onSendSpectatorSync.
Структуры всех пакетов синхронизации находятся в файле synchronization.lua.


Примеры скриптов
AntiCarJack - перехват и игнорирование входящего RPC и пакета синхронизации
Bubble Sniffer - перехват и обработка входящего RPC
DerpCam - перезапись данных исходящего пакета синхронизации
Chat Bliss - перезапись, игнорирование и обработка исходящего RPC


Кастомизация
API структурирован так, что позволяет вносить в него любые изменения, не прибегая к изменению исходных файлов модулей.
Добавление своего обработчика для серверного пакета проигрывания звука:
Lua:
local sampev = 'lib.samp.events'
local raknet = 'lib.samp.raknet'
sampev.INTERFACE.INCOMING_RPCS[raknet.RPC.PLAYSOUND] = {'onPlaySound', {soundId = 'int32'}, {x = 'float'}, {y = 'float'}, {z = 'float'}}
И теперь в тот же файл можно добавить функцию для обработки события:
Lua:
function sampev.onPlaySound(sound, x, y, z)
-- добавляем сообщение в лог
print(string.format('Sound %d at coords %0.2f, %0.2f, %0.2f', sound, x, y, z))
-- и отключаем звук, запрещая дальнейшую обработку пакета
return false
end
Следует сразу разобрать код регистрации события, чтобы стало понятнее.
Lua:
sampev.INTERFACE. -- поле INTERFACE - это все экспортируемые элементы модуля
INCOMING_RPCS -- обращение к списку входящих RPC
[raknet.RPC.PLAYSOUND] -- обращение к элементу таблицы INCOMING_RPCS по индексу, в данном случае INCOMING_RPCS - это таблица, содержащая список структур всех входящих RPC, а raknet.RPC.PLAYSOUND - идентификатор требуемого RPC
= -- присваиваем ему новое значение - таблицу с информацией о событии и структурой пакета
{'onPlaySound', -- название события, функция события будет использовать это имя
-- структура пакета. каждый параметр должен быть заключен в отдельную таблицу, иметь название и тип в формате {названиеПараметра = 'тип'}
{soundId = 'int32'}, {coords = 'vector3d'}}
Очевидно, что INCOMING_RPCS - это не единственная таблица, их четыре:
INCOMING_RPCS - входящие RPC
OUTCOMING_RPCS - исходящие RPC
INCOMING_PACKETS - входящие пакеты
OUTCOMING_PACKETS - исходящие пакеты

Новый тип тоже можно добавить без изменения исходников библиотеки:
Lua:
events.INTERFACE.BitStreamIO.fvector3 = { -- название типа после последней точки
   read = function(bs) -- функция чтения. первый аргумент - битстрим
     local vec = {}
     vec.x = raknetBitStreamReadFloat(bs)
     vec.y = raknetBitStreamReadFloat(bs)
     vec.z = raknetBitStreamReadFloat(bs)
     return vec
   end,
   write = function(bs, value) -- функция записи
     raknetBitStreamWriteFloat(bs, value.x)
     raknetBitStreamWriteFloat(bs, value.y)
     raknetBitStreamWriteFloat(bs, value.z)
   end
}
В случае, если пакет имеет какую-то сложную структуру, не описываемую даже с помощью пользовательских типов, то вместо структуры можно передать функцию, которая будет обрабатывать данные. Например как это сделано для RPC InitGame:
Lua:
INCOMING_RPCS[RPC.INITGAME] = {'onInitGame', onInitGameReader, onInitGameWriter} -- второй и третий аргумент - это функции чтения и записи
Для большего количества примеров смотрите исходный код.

Что касается всей библиотеки в целом, то она ещё находится на зачаточной стадии и обсуждать кроме планов нечего. По сути она должна заменить собой основную часть SAMPFUNCS - моддинг сампа.

Скачать последнюю версию и следить за изменениями всегда можно на GitHub.
Установка: скачать samp.zip из последнего релиза и целиком скопировать папку 'samp' (не содержимое папки!) из архива в каталог 'moonloader/lib/'.

Любая помощь в разработке приветствуется, особенно с добавлением новых структур. Предложите Pull request на гитхабе или напишите в этой теме.

Ну и конечно же крохотное нано-спасибо hnnssy за помощь.
 
Последнее редактирование:

WebDim

Участник
59
3
Хотелось поднять снова вопрос об
onCreateObject(id, data)
Как только не пробовал получить materialText

Код:
function hook.onCreateObject(obj_id, obj_data)
    if bl_obj then
        local tmp_str = ""
        for k,v in pairs(obj_data.materialText) do
            tmp_str = tmp_str..v
        end
        if tmp_str ~= "" then
            sampAddChatMessage("• {FFC800}[Подсказка] {ffffff} id obj: "..obj_id.." text obj: "..tmp_str, 0xffffff)
        end
    end
end

Вразумите наконец, голову уже дня три ломаю.

Понимаю что можно взять (даже реализовал это) с onSetObjectMaterialText
но мне нужны координаты данного объекта и как это связать ума не приложу.
 
Последнее редактирование:

Akionka

akionka.lua
Проверенный
742
502
Хотелось поднять снова вопрос об
onCreateObject(id, data)
Как только не пробовал получить materialText

Код:
function hook.onCreateObject(obj_id, obj_data)
    if bl_obj then
        local tmp_str = ""
        for k,v in pairs(obj_data.materialText) do
            tmp_str = tmp_str..v
        end
        if tmp_str ~= "" then
            sampAddChatMessage("• {FFC800}[Подсказка] {ffffff} id obj: "..obj_id.." text obj: "..tmp_str, 0xffffff)
        end
    end
end

Вразумите наконец, голову уже дня три ломаю.

Понимаю что можно взять (даже реализовал это) с onSetObjectMaterialText
но мне нужны координаты данного объекта и как это связать ума не приложу.
пример реализации https://github.com/Akionka/trinity-set-cooler/blob/master/trinity-set-cooler.lua#L26
 
  • Нравится
Реакции: WebDim

Hatiko

Известный
Проверенный
1,502
620
а че скачать больше незя?
Специально для тебя потратил 20 секунд. Читать вообще отказываетесь.
1601034871724.png

1601034892156.png
 
  • Нравится
Реакции: AnWu

user337567

Участник
91
10
Почему некоторые функции не работают адекватно? В чат отправляется 2 раза
Screenshot_272.png

поясните в чем прикол и как это исправить
 

lionex

Потрачен
33
1
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Не работает, вот тупо не работает. Переустанавливал мунлоадер, сачал папку samp с github'a.
Lua:
local sampev = require 'lib.samp.events'
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then end
    while not isSampAvailable() do wait(100) end

    while true do
        wait(0)
    end
end

function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
    sampAddChatMessage(dialogId, -1)
    sampAddChatMessage(style, -1)
    sampAddChatMessage(title, -1)
    sampAddChatMessage(button1, -1)
    sampAddChatMessage(button2, -1)
    sampAddChatMessage(text, -1)
end
В чём проблема?
 

ArzAh

Потрачен
72
10
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Будет какая то "поддержка" - DIALOG_STYLE_TABLIST_HEADERS?
Через
Lua:
onShowDialog
костыльно как то выводит информацию с диалога.
или она уже есть? Но что то он плохо работает с данным стилем диалога.
 

Fott

Простреленный
3,461
2,374
Будет какая то "поддержка" - DIALOG_STYLE_TABLIST_HEADERS?
Через
Lua:
onShowDialog
костыльно как то выводит информацию с диалога.
или она уже есть? Но что то он плохо работает с данным стилем диалога.
Почему костыльно?
 

_ex$tanOr_

Участник
125
19
Lua:
function sampev.onSendChat(message)
    if active_tv.v  and not sampIsDialogActive() then

            sampSendChat('/tv '..message)

    end
end

Не флудите пишет после отправки корректного сообщения. Как пофиксить?
 

paulohardy

вы еще постите говно? тогда я иду к вам
Всефорумный модератор
1,907
1,283
Lua:
function sampev.onSendChat(message)
    if active_tv.v  and not sampIsDialogActive() then

            sampSendChat('/tv '..message)

    end
end

Не флудите пишет после отправки корректного сообщения. Как пофиксить?
Lua:
function sampev.onSendChat(message)
    if active_tv.v  and not sampIsDialogActive() then
        sampSendChat('/tv '..message)
        return false
    end
end
 
  • Нравится
Реакции: _ex$tanOr_

B365

Известный
30
15
Как использовать "onServerStatisticsResponse"? В игре это событие никогда не происходит и в файле библиотеки часть события закомментирована. В структуре должна быть информация о потере пакетов.
INCOMING_RPCS[RPC.SRVNETSTATS] = {'onServerStatisticsResponse'} --, {data = 'RakNetStatisticsStruct'}}
 

dzekb

Новичок
17
6
як установить пж подакажить я граю на аризона лаунчер
 
  • Нравится
Реакции: memir