Отслеживание чата

Alex07

Известный
Автор темы
29
13
Версия MoonLoader
.026-beta
Доброго времени.
Наковырял скриптик из подручных средств, который должен отслеживать сообщения в чате о разрыве коннекта (сбой инета, серверный рестарт в 5 утра на аризоне и т.д.) и кидать в чат команду на коннект (стоит фастконнект 5.1 от АИРа)
Только он чет не хочет толком работать. Например там есть исключения на реакцию крика, шепота и вип чата, чтобы отсеять сообщения от реальных людей.
Однако ж он только на сообщения игроков и реагирует (тестил сам и с твинка), а на серверные - нет. + сегодня перед рестартом когда в чате появилось мсг о рестарте (оно есть в скрипте для реакции) игру крашнуло. Пока коннектился к серверу словил еще пару сообщений (Wrong server password), на которые скрипт тоже не выдал никакой реакции.
Кто может направить на путь истинный?
P.S. лютый кривокод
Rec5:
local sampev = require 'samp.events'

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end

    sampAddChatMessage("{7B68EE} {ffffff} [Rec5] {33EA0D}загружен", -1)

    Rec5Status = true
end

function sampev.onServerMessage(color, text)
    if text:find('Технический рестарт через 01 минут. Сессия завершена принудительно') or text:find('Server closed the connection') or text:find('Wrong server password') or text:find('You are banned from this server') or text:find('Сервер не отвечает')
    and not text:find('говорит') and not text:find('говорит шепотом') and not text:find('кричит') and not text:find('VIP') and not text:find('PREMIUM') and not text:find('|') then
            sampSendChat('/rec 90')
    end
end
 

Вложения

  • rec_5am.lua
    785 байт · Просмотры: 9
Решение
Нужен сампфукс
Lua:
function onReceivePacket(id, data)
    if id == 32 or id == 33 or id == 36 or id == 37 then
        -- код
    end
end


Так нужен только самп луа
Lua:
local sampev = require 'samp.events'

function sampev.onConnectionClosed()
    -- код
end
function sampev.onConnectionLost()
    -- код
end
function sampev.onConnectionBanned()
    -- код
end
function sampev.onConnectionPasswordInvalid()
    -- код
end

SAsha133777

Потрачен
127
111
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Это же с синхрой взаимодействие. И сообщения только серверные ловит.
А то что Server closed the connection и т.д., сообщения от скриптов - это всё клиентские.

Можно в бесконечном цикле проверять последнюю строчку в чате.
На этом форуме есть простой реконнект с такой работой.

Но это говнокод.
Просто есть пакеты синхронизации которые тебе отправляет сервер когда закрывает соеднинение, банит IP, пишет что не верный пароль и т.д. Вот эти пакеты ловить надо.

Потом может код скину.
 
Последнее редактирование:

qdIbp

Автор темы
Проверенный
1,438
1,180
Server closed the connection
Wrong server password
You are banned from this server
Сервер не отвечает

Это не серверные сообщения, так что onServerMessage бесполезен

Lua:
local ffi = require 'ffi'
local hook = {hooks = {}}
addEventHandler('onScriptTerminate', function(scr)
    if scr == script.this then
        for i, hook in ipairs(hook.hooks) do
            if hook.status then
                hook.stop()
            end
        end
    end
end)

ffi.cdef [[
    int VirtualProtect(void* lpAddress, unsigned long dwSize, unsigned long flNewProtect, unsigned long* lpflOldProtect);
]]

function hook.new(cast, callback, hook_addr, size)
    local size = size or 5
    local new_hook = {}
    local detour_addr = tonumber(ffi.cast('intptr_t', ffi.cast('void*', ffi.cast(cast, callback))))
    local void_addr = ffi.cast('void*', hook_addr)
    local old_prot = ffi.new('unsigned long[1]')
    local org_bytes = ffi.new('uint8_t[?]', size)
    ffi.copy(org_bytes, void_addr, size)
    local hook_bytes = ffi.new('uint8_t[?]', size, 0x90)
    hook_bytes[0] = 0xE9
    ffi.cast('uint32_t*', hook_bytes + 1)[0] = detour_addr - hook_addr - 5
    new_hook.call = ffi.cast(cast, hook_addr)
    new_hook.status = false
    local function set_status(bool)
        new_hook.status = bool
        ffi.C.VirtualProtect(void_addr, size, 0x40, old_prot)
        ffi.copy(void_addr, bool and hook_bytes or org_bytes, size)
        ffi.C.VirtualProtect(void_addr, size, old_prot[0], old_prot)
    end
    new_hook.stop = function() set_status(false) end
    new_hook.start = function() set_status(true) end
    new_hook.start()
    table.insert(hook.hooks, new_hook)
    return setmetatable(new_hook, {
        __call = function(self, ...)
            self.stop()
            local res = self.call(...)
            self.start()
            return res
        end
    })
end

function main()
    while not isSampAvailable() do
        wait(0)
    end  
    sampChatHook = hook.new('void(__thiscall *)(void *this, uint32_t type, const char* text, const char* prefix, uint32_t color, uint32_t pcolor)', ChatHook, getModuleHandle('samp.dll') + 0x64010)
    wait(-1)
end

function ChatHook(HOOKED_CHAT_THIS, HOOKED_CHAT_TYPE, HOOKED_CHAT_TEXT, HOOKED_CHAT_PREFIX, HOOKED_CHAT_COLOR, HOOKED_CHAT_PCOLOR)
    local text = ffi.string(HOOKED_CHAT_TEXT)
    if text:find('Server closed the connection') then
        print('LOX)
    end
    sampChatHook(HOOKED_CHAT_THIS, HOOKED_CHAT_TYPE, HOOKED_CHAT_TEXT, HOOKED_CHAT_PREFIX, HOOKED_CHAT_COLOR, HOOKED_CHAT_PCOLOR)
end
find на 60 строчки
 

SAsha133777

Потрачен
127
111
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Нужен сампфукс
Lua:
function onReceivePacket(id, data)
    if id == 32 or id == 33 or id == 36 or id == 37 then
        -- код
    end
end


Так нужен только самп луа
Lua:
local sampev = require 'samp.events'

function sampev.onConnectionClosed()
    -- код
end
function sampev.onConnectionLost()
    -- код
end
function sampev.onConnectionBanned()
    -- код
end
function sampev.onConnectionPasswordInvalid()
    -- код
end
 
Последнее редактирование:

Alex07

Известный
Автор темы
29
13
Так нужен только самп луа
Lua:
local sampev = require 'samp.events'

function sampev.onConnectionClosed()
    -- код
end
function sampev.onConnectionLost()
    -- код
end
function sampev.onConnectionBanned()
    -- код
end
function sampev.onConnectionPasswordInvalid()
    -- код
end
Взял, потестил, вручную офал инет. При неправильном пароле серв закрывает соединение и уходит команда на реконнект, при обычном обрыве сети без скрипта чат зафлуживается "Выбранный слот занят", со скриптом игра просто закрывается без ошибок. Думаю тут уже надо будет думать в сторону какого-нибудь фикса или фастконнекта