- 1,494
- 609
Скрипт CEF Monitoring собирает полученные/отправленные пакеты, затем расшифрует и показывает в окно.
Скрипт может распознавать пакеты для CEF в Advance RP. И они так выглядят:
* - необязательно указать для отправки
Важно!
Кодировка пакета является CP1251 (Windows 1251), но не UTF-8. Поэтому работаете с пакетами в скрипт без перекодировки.
Код:
Пример для получение список тасков в CEF:
Вывод (смотри в код onReceivePacket сверху):
Пример как эмулировать после отредактирования в диалог после получения CEF-пакет:
К сожалению, способ на cef eval не нашел. Пытался, но не вышло. Только отправлять и эмулировать пакетов без евала.
Благодарности:
- @Rice. за готовый скрипт
- @Back1ng за то нашел способ чтение/отправки пакеты в CEF
Скрипт может распознавать пакеты для CEF в Advance RP. И они так выглядят:
Код:
[SEND] CEF -> 13; cef:tasksRequest; menu | ...
[GET] CEF -> 12; cef:tasks; {"tasks":[{"group":0,"slot":0,"name":"Перенести на складе","target":15,"item":" грузов","progress":0.0,"status":0},{"group":0,"slot":1,"name":"Увеличить силу на","target":2,"item":" ед.","progress":0.0,"status":0},{"group":0,"slot":2,"name":"Набрать в соревнованиях по стрельбе","target":22,"item":" очков","progress":0.0,"status":0},{"group":0,"slot":3,"name":"Подмести в Cluckin Bell","target":15,"item":" кв. м полов","progress":0.0,"status":0},{"group":0,"slot":4,"name":"Сыграть в кости с","target":2,"item":" разными игроками","progress":0.0,"status":0},{"group":0,"slot":5,"name":"Добыть","target":299,"item":" кг руды","progress":0.0,"status":0},{"group":1,"slot":0,"name":"Заправить автомехаником","target":33,"item":" автомобилей","progress":0.0,"status":0},{"group":1,"slot":1,"name":"Сыграть в рулетку","target":33,"item":" раз(а)","progress":0.0,"status":0},{"group":1,"slot":2,"name":"Выпить безалкогольных напитков","target":121,"item":" шт.","progress":0.0,"status":0},{"group":1,"slot":3,"name":"Заработать на заводе продуктов","target":91817,"item":"$","progress":0.0,"status":0}]},"battlePass":{"level":2,"exp":10000,"need":11800,"days":35,"pass":0,"maxLevel":50}} | ...
[SEND] CEF -> 13; cef:tasksRequest; menu | ...| Значение | Объясняю |
|---|---|
| * GET или SEND | GET - вы получили от сервера SEND - вы отправили пакет на сервере, чтобы он прочитал ваши пакеты |
| * CEF -> | Обозначает что пакет получен/отправлен для обработки в CEF |
| 12 или 13 | 12 (0x0C) - как GET (получен) 13 (0x0D) - как SEND (отправлен) |
| cef:tasksRequest | Название событие |
| menu | Аргументы событие (payload) |
| ... | Байты (не входит для обработки CEF) |
Важно!
Кодировка пакета является CP1251 (Windows 1251), но не UTF-8. Поэтому работаете с пакетами в скрипт без перекодировки.
Код:
Lua:
local ffi = require("ffi")
local CEF_PACKET_ID = 0xFA -- 250
local CEF_MAX_PACKET = 0x2000 -- 8192
local CEF_EVENT_GET = 0x0C -- 12
local CEF_EVENT_SEND = 0x0D -- 13
local function readPacketBytes(bs)
if bs == nil or bs == 0 then return "" end
local size = raknetBitStreamGetNumberOfBytesUsed(bs)
if not size or size <= 0 or size > CEF_MAX_PACKET then return "" end
local savedOffset = raknetBitStreamGetReadOffset(bs)
local buffer = ffi.new("uint8_t[?]", size)
raknetBitStreamResetReadPointer(bs)
local dest = tonumber(ffi.cast("intptr_t", buffer))
raknetBitStreamReadBuffer(bs, dest, size) ---@diagnostic disable-line: param-type-mismatch
raknetBitStreamSetReadOffset(bs, savedOffset)
raknetBitStreamResetReadPointer(bs)
return ffi.string(buffer, size)
end
local function parseCefEvent(bs)
local raw = readPacketBytes(bs)
if #raw < 6 then return nil end
local index = 2
local typ = raw:byte(index) -- in/out event
index = index + 1
local name_len = raw:byte(index)
if not name_len or name_len <= 0 or name_len > 63 then return nil end
index = index + 1
local name_len_end = index + name_len - 1
if name_len_end + 2 > #raw then return nil end
local event_name = raw:sub(index, name_len_end)
index = name_len_end + 1
local payload_len = raw:byte(index) + raw:byte(index + 1) * 256
index = index + 2
if payload_len < 0 or index + payload_len - 1 > #raw then return nil end
return typ, event_name, raw:sub(index, index + payload_len - 1)
end
local function sendCefEvent(event_name, payload)
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, CEF_PACKET_ID)
raknetBitStreamWriteInt8(bs, CEF_EVENT_SEND)
raknetBitStreamWriteInt8(bs, #event_name)
raknetBitStreamWriteString(bs, event_name)
raknetBitStreamWriteInt16(bs, #payload)
raknetBitStreamWriteString(bs, payload)
raknetSendBitStreamEx(bs, 1, 9, 0)
raknetDeleteBitStream(bs)
end
local function emulCefEvent(is_event_get, event_name, payload)
is_event_get = is_event_get and CEF_EVENT_GET or CEF_EVENT_SEND
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, CEF_EVENT_GET)
raknetBitStreamWriteInt8(bs, #event_name)
raknetBitStreamWriteString(bs, event_name)
raknetBitStreamWriteInt16(bs, #payload)
raknetBitStreamWriteString(bs, payload)
raknetEmulPacketReceiveBitStream(CEF_PACKET_ID, bs)
raknetDeleteBitStream(bs)
end
addEventHandler("onReceivePacket", function(id, bs)
if id ~= CEF_PACKET_ID then return end
local typ, event_name, payload = parseCefEvent(bs)
if not typ or typ ~= CEF_EVENT_GET then return end
print(" -> GET", typ, event_name, payload)
end)
addEventHandler("onSendPacket", function(id, bs)
if id ~= CEF_PACKET_ID then return end
local typ, event_name, payload = parseCefEvent(bs)
if not typ or typ ~= CEF_EVENT_SEND then return end
print(" <- SEND", typ, event_name, payload)
end)
function main()
if not isSampLoaded() or not isSampfuncsLoaded() then return end
while not isSampAvailable() do wait(100) end
sampRegisterChatCommand("test_send_event", function(arg)
local event, payload = arg:match("^(%S+)%s*(.*)$")
if not event then
sampAddChatMessage("Usage: /test_send_event <event> [payload]", -1)
return
end
sendCefEvent(event, payload)
end)
while true do
wait(250)
end
end
Пример для получение список тасков в CEF:
Lua:
sendCefEvent("cef:tasksRequest", "menu")
-- или /test_send_event cef:tasksRequest menu
Код:
typ = 12
event_name = cef:tasks
payload = {"tasks":[{"group":0,"slot":0,"name":"Перенести на складе","target":15,"item":" грузов","progress":0.0,"status":0},...
Пример как эмулировать после отредактирования в диалог после получения CEF-пакет:
Lua:
addEventHandler("onReceivePacket", function(id, bs)
if id ~= CEF_PACKET_ID then return end
local typ, event_name, payload = parseCefEvent(bs)
if not typ or typ ~= CEF_EVENT_GET or not event_name or not payload then return end
if event_name ~= "cef:dialog" or not payload:find([["DIALOG_HEADER":%s*"{%x+}Тут могло быть заголовка диалога"]]) then return end
local decoded_payload = decodeJson(payload) -- распакуем строка-значение в таблице Lua
decoded_payload.DIALOG_TEXT = decoded_payload.DIALOG_TEXT:gsub("Возвраст", "В штате") -- заменяем Возраст на В штате
-- или полностью -- нужно менять табуляция на элементы <tbl> и тд
decoded_payload.DIALOG_TEXT = ("С уважением,\nтвой разраб\t{4287F5}lua"):gsub("\t", "<tbl>"):gsub("\n", "<br>")
-- запакуем обратно из таблицы в строка и эмулируем
local encoded_payload = encodeJson(decoded_payload)
emulCefEvent(true, "cef:dialog", encoded_payload)
return false -- скрываем старый диалог
end)
К сожалению, способ на cef eval не нашел. Пытался, но не вышло. Только отправлять и эмулировать пакетов без евала.
Благодарности:
- @Rice. за готовый скрипт
- @Back1ng за то нашел способ чтение/отправки пакеты в CEF
Вложения
Последнее редактирование: