CaJlaT

Овощ
Модератор
2,806
2,603
Оттуда потом можно ссылку достать потом, без дополнений. Рофлянул на этк тему.
Тема нормальная, но можно было бы сделать на jmp хуке, чтобы ещё и ссылки скриптов открывать было удобнее
 
  • Нравится
Реакции: Vintik

GrishaMazzlov

https://t.me/RealCashFlow101
Проверенный
1,781
938
Тема нормальная, но можно было бы сделать на jmp хуке, чтобы ещё и ссылки скриптов открывать было удобнее
Да я не обсираю тему, я просто в юмористической форме сказал про то, что это можно сделать и без дополнений. Каждый скрипт на БХ - хорош, даже есть это биндер одной команды на одну кнопку, ибо человек изучая язык программирования решил выставить результат практики на всеобщее обозрение, чтобы получить критику и советы.
 

CaJlaT

Овощ
Модератор
2,806
2,603
Можно пожалуйста поподробнее, что такое jmp хук, и чем он хорош?
Можно хукать не только серверные сообщения, а сообщения скриптов или клиента (sa:mp started и т.д)
Конкретно хук чата:
 

CaJlaT

Овощ
Модератор
2,806
2,603
Просто перенести данные строки в свой скрипт и jmp хук будет работать? Я просто кроме эмуляции клавиш в ffi не юзал никогда, поэтому не шарю за эту библиотеку :)
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 ChatHook(HOOKED_CHAT_THIS, HOOKED_CHAT_TYPE, HOOKED_CHAT_TEXT, HOOKED_CHAT_PREFIX, HOOKED_CHAT_COLOR, HOOKED_CHAT_PCOLOR)
    if HOOKED_CHAT_TEXT then lua_thread.create(checkChat, HOOKED_CHAT_TEXT) end
    sampChatHook(HOOKED_CHAT_THIS, HOOKED_CHAT_TYPE, HOOKED_CHAT_TEXT, HOOKED_CHAT_PREFIX, HOOKED_CHAT_COLOR, HOOKED_CHAT_PCOLOR)
end

function checkChat(text)
    local text = ffi.string(text)
    --твой код...
end

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    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
 

СоМиК

Известный
Автор темы
457
310
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 ChatHook(HOOKED_CHAT_THIS, HOOKED_CHAT_TYPE, HOOKED_CHAT_TEXT, HOOKED_CHAT_PREFIX, HOOKED_CHAT_COLOR, HOOKED_CHAT_PCOLOR)
    if HOOKED_CHAT_TEXT then lua_thread.create(checkChat, HOOKED_CHAT_TEXT) end
    sampChatHook(HOOKED_CHAT_THIS, HOOKED_CHAT_TYPE, HOOKED_CHAT_TEXT, HOOKED_CHAT_PREFIX, HOOKED_CHAT_COLOR, HOOKED_CHAT_PCOLOR)
end

function checkChat(text)
    local text = ffi.string(text)
    --твой код...
end

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    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
Спасибо, будет время - внесу изменения в скрипт
 

Sanchez.

Известный
704
187
А почему у скрипта тег [ARZ] если этот скрипт можно использовать где угодно?
 

СоМиК

Известный
Автор темы
457
310
А почему у скрипта тег [ARZ] если этот скрипт можно использовать где угодно?
Прост) Я играю на арз и пишу скрипты под арз, само как то написалось)
UPD да и в принципе какая разница, большинство других проектов либо мертво с 0 онлайна, либо остались последние живчики и из-за этого 100 - 200 онлайна из тысячи на весь проект
 
  • Ха-ха
Реакции: Sanchez.

Vintik

Мечтатель
Проверенный
1,456
908
Прост) Я играю на арз и пишу скрипты под арз, само как то написалось)
UPD да и в принципе какая разница, большинство других проектов либо мертво с 0 онлайна, либо остались последние живчики и из-за этого 100 - 200 онлайна из тысячи на весь проект
А самп рп!? 🥺🥺
 

VgrxTxch

Известный
1,163
322
а если ссылка будет без https:// или http://?
например просто google.ru
 

СоМиК

Известный
Автор темы
457
310
а если ссылка будет без https:// или http://?
например просто google.ru
Скрипту надо как то определять, что в чате ссылка, а не просто какое то сообщение, поэтому к сожалению никак, только если отслеживать домен, но сделать это очень трудно и заняло бы очень много времени, так как доменов в мире очень много, и каждый надо вносить в массив и делать проверку на сравнение домена в массиве и в сообщении
а если ссылка будет без https:// или http://?
например просто google.ru
(UPD) А хотя знаешь, я заинтересован в этой идее, и думаю, что буду постепенно добавлять всё больше и больше доменов в массив. Ожидай обновления.
Скрипт был обновлен до версии 1.1, подробнее - в самом первом сообщении в этой теме.
 
Последнее редактирование:

kin4stat

mq-team
Всефорумный модератор
2,730
4,710
Идея хорошая. Если бы еще по клику можно было бы открывать, было бы вообще атас. Если не забуду - помогу потом сделать это