Взаимодействие imgui диалога и самповского

Knox_sb

Участник
Автор темы
31
2
Версия MoonLoader
Другое
Приветствую, у меня парочка вопросов
1. Как сделать imgui диалог, который может взаимодействовать с сампом (например, вписываешь в imgui окошко ответ на репорт и ответ отправляется по кнопке)
2. Возможно ли как то прочитать содержимое диалогового окна и примерно по такому же методу как text:find и если нашелся определенный текст в диалоге, выполнить определенное действие (например, чекнул мед. карту и если там написано "абсолютно здоров", то скрипт скипает диалог и пишет "поздравляю, вы прошли собеседование"). Надеюсь не сильно загрузил
 

kyrtion

Известный
871
304
1. Как сделать imgui диалог, который может взаимодействовать с сампом (например, вписываешь в imgui окошко ответ на репорт и ответ отправляется по кнопке)
Сначала тебе нужно узнать источник диалога, который появляется репорт у тебя на глазах. Нужно указать в sampev.onShowDialog и вывести всех аргументов в консоли, а затем просмотреть в moonloader.log и вписываешь ид диалога (если динамический ид, не укажи, а сверстай совпадение в заголовках диалога и текст). если совпадают и все проверки прошли, то подбираешь переменные в text:match(...) (желательно записать буфферы в imgui и тд, но не постоянно конвертировать в u8, а раз и всё), заставляешь выводить фрейм в игре и там будет ник автора, и текст репорта, т.д. - всё просто!
если ты шаришь и хочешь еще расширить, вроде профи: в таком случае можно использовать луа для запуска консоли, вот: тут и тут, и там пополняешь для вывода в консоли и тебе будет проще скопировать первоисточников чата/диалога и тд

2. Возможно ли как то прочитать содержимое диалогового окна и примерно по такому же методу как text:find и если нашелся определенный текст в диалоге, выполнить определенное действие (например, чекнул мед. карту и если там написано "абсолютно здоров", то скрипт скипает диалог и пишет "поздравляю, вы прошли собеседование"). Надеюсь не сильно загрузил
если все проверки прошли и тогда дальше ставишь цикл по строкам. дальше составляешь регулярное выражение в :find()
можно и по строкам диалога пробивать по line:find(...)

Lua:
local text = 'text\ndi-\nalog!'

for line in text:gmatch('[^\n]+') do
    print(line, line:find('di%-'))
end

-- output: так пример текст диалога как в сампе, \n - перенос строка
-- text nil
-- di- 1 3 -- этот нашли, вернется как true, остальное false т.к. nil
-- alog! nil
 
  • Нравится
Реакции: VanoKLR и Knox_sb

Knox_sb

Участник
Автор темы
31
2
Сначала тебе нужно узнать источник диалога, который появляется репорт у тебя на глазах. Нужно указать в sampev.onShowDialog и вывести всех аргументов в консоли, а затем просмотреть в moonloader.log и вписываешь ид диалога (если динамический ид, не укажи, а сверстай совпадение в заголовках диалога и текст). если совпадают и все проверки прошли, то подбираешь переменные в text:match(...) (желательно записать буфферы в imgui и тд, но не постоянно конвертировать в u8, а раз и всё), заставляешь выводить фрейм в игре и там будет ник автора, и текст репорта, т.д. - всё просто!
если ты шаришь и хочешь еще расширить, вроде профи: в таком случае можно использовать луа для запуска консоли, вот: тут и тут, и там пополняешь для вывода в консоли и тебе будет проще скопировать первоисточников чата/диалога и тд


если все проверки прошли и тогда дальше ставишь цикл по строкам. дальше составляешь регулярное выражение в :find()
можно и по строкам диалога пробивать по line:find(...)

Lua:
local text = 'text\ndi-\nalog!'

for line in text:gmatch('[^\n]+') do
    print(line, line:find('di%-'))
end

-- output: так пример текст диалога как в сампе, \n - перенос строка
-- text nil
-- di- 1 3 -- этот нашли, вернется как true, остальное false т.к. nil
-- alog! nil
Можно в 1 попроще или на примере, а то я немного чайник именно в названиях

+ пишу на мобилке есть только монетлоадер лог
 
Последнее редактирование:

kyrtion

Известный
871
304
Можно в 1 попроще, а то я немного чайник именно в названиях
допустим, как я обычно указываю если скрипт должно работать с конкретным диалогом:

так выглядит диалог, если я получил диалог на руках:
Код:
dialogId: 52
style: 0
title: 'Репорт'
button1: 'Ответить'
button2: 'Назад'
text:
```
{ffe126}Автор:\t\t{f9f9f9}Player_Name[123]

{ffe126}Сообщение:\t{f9f9f9}61 дм
... (там вроде что-то продолжение, лучше скинуть источник диалога сюда или в лс)
```
1. обычно смотрю в dialogId, если там будет динамические ид (те которые меняются, или постоянные ид и ничего не меняются), то я его не указываю для проверки
2. смотрим заголовка диалога, если там будет пустая строка то не укажем
3. в тексте присутствуют hex-цвет, пустая строка и возможно оставят табуляция (\t). их заберем обязательно для чистоты

Lua:
local dataReport = {
    template = {
        author = 'Автор: %s[%d]',
        message = 'Сообщение: %s',
    }
    state = false,
    author = {
        nickname = '',
        id = -1,
        online = false
    },
    message = ''
}

-- onShowDialog:
--                          |> убираем hex-цвет,       |> а это делаем еще пожестоже регулряное выражение с ^$
if dialogId == 52 and title:gsub('{%x%x%x%x%x%x}', ''):find('^Репорт$') then
    local dText = text
        :gsub('{%x%x%x%x%x%x}', '') -- строка станет без hex-цвет
        :gsub('\t', ' ') -- заменяет табы на пробелы
        :gsub('\n+', '\n') -- убирает пустые строка если будет несколько переносов (enter)
   
    for line in dText:gmatch('[^\n]+') do
        line = line:gsub('%s+', ' ') -- заменяет пробелы на 1 пробел
            :gsub('^%s+$', '') -- заменяет пробелы весь строка на пустой, т.к. стоит ^$ как пожестоже
        if line:find('^Автор: %S-%[%d+%]$') then
            dataReport.author.nickname, dataReport.author.id = line:match('^Автор: (%S-)%[(%d+)%]$')
            -- если там в переменнах вернет числа, но при :match все возвращают в строковых значений или nil, поэтому:
            dataReport.author.id = tonumber(dataReport.author.id)
        elseif line:find('^Сообщение: .*$') then
            -- рано или поздно игроки забагают как пустое сообщение, то укажем .* и в начале ^
            -- можно ставить $ в конце, если сообщение репорта автоматически ставится точка или шаблонное слово
            dataReport.message = line:match('^Сообщение: (.*)')
        end
    end
    dataReport.state = true
   
    --[[
        И по идее должно хранить в таблице после вышеперечисленных алгоритмов:
        dataReport.state:            true
        dataReport.author.nickname:    Player_Name
        dataReport.author.id:        123
        dataReport.message:            61 дм
       
        Для вывода в фрейм желательно записать в imgui значением, например, для mimgui
        чтобы вывело раз и навсегда без постоянной перекодировки в u8 в фрейм.
        если будет изменение в диалоге, то их нужно снова записать и выводить
       
        теперь записываем переменные для вывода фрейм:
        но желательно сначала создать локальные переменные для форматирование
        готовые рег. выражение для string.format:
        local author = string.format(dataReport.template.author, dataReport.author.nickname, dataReport.author.id)
        local message = string.format(dataReport.template.message, dataReport.message)

        записываем в строковых значениях mimgui и ид:
        dataReportImgui.state[0] = dataReport.state
        imgui.StrCopy(dataReportImgui.author, u8(author))
        imgui.StrCopy(dataReportImgui.message, u8(message))
    ]]
end

-- frame:
imgui.Text(dataReportImgui.author)
imgui.Text(dataReportImgui.message)

Бля дальше уже лень описывать
 
Последнее редактирование:
  • Нравится
Реакции: Knox_sb

Knox_sb

Участник
Автор темы
31
2
допустим, как я обычно указываю если скрипт должно работать с конкретным диалогом:

так выглядит диалог, если я получил диалог на руках:
Код:
dialogId: 52
style: 0
title: 'Репорт'
button1: 'Ответить'
button2: 'Назад'
text:
```
{ffe126}Автор:\t\t{f9f9f9}Player_Name[123]

{ffe126}Сообщение:\t{f9f9f9}61 дм
... (там вроде что-то продолжение, лучше скинуть источник диалога сюда или в лс)
```
1. обычно смотрю в dialogId, если там будет динамические ид (те которые меняются, или постоянные ид и ничего не меняются), то я его не указываю для проверки
2. смотрим заголовка диалога, если там будет пустая строка то не укажем
3. в тексте присутствуют hex-цвет, пустая строка и возможно оставят табуляция (\t). их заберем обязательно для чистоты

Lua:
local dataReport = {
    template = {
        author = 'Автор: %s[%d]',
        message = 'Сообщение: %s',
    }
    state = false,
    author = {
        nickname = '',
        id = -1,
        online = false
    },
    message = ''
}

-- onShowDialog:
--                          |> убираем hex-цвет,       |> а это делаем еще пожестоже регулряное выражение с ^$
if dialogId == 52 and title:gsub('{%x%x%x%x%x%x}', ''):find('^Репорт$') then
    local dText = text
        :gsub('{%x%x%x%x%x%x}', '') -- строка станет без hex-цвет
        :gsub('\t', ' ') -- заменяет табы на пробелы
        :gsub('%s+', ' ') -- заменяет пробелы на 1 пробел
        :gsub('^%s+$', '') -- заменяет пробелы весь строка на пустой, т.к. стоит ^$ как пожестоже
        :gsub('\n+', '\n') -- убирает пустые строка если будет несколько переносов (enter)
   
    for line in dText:gmatch('[^\n]+') do
        if line:find('^Автор: %S-%[%d+%]$') then
            dataReport.author.nickname, dataReport.author.id = line:match('^Автор: (%S-)%[(%d+)%]$')
            -- если там в переменнах вернет числа, но при :match все возвращают в строковых значений или nil, поэтому:
            dataReport.author.id = tonumber(dataReport.author.id)
        elseif line:find('^Сообщение: .*$') then
            -- рано или поздно игроки забагают как пустое сообщение, то укажем .* и в начале ^
            -- можно ставить $ в конце, если сообщение репорта автоматически ставится точка или шаблонное слово
            dataReport.message = line:match('^Сообщение: (.*)')
        end
    end
    dataReport.state = true
   
    --[[
        И по идее должно хранить в таблице после вышеперечисленных алгоритмов:
        dataReport.state:            true
        dataReport.author.nickname:    Player_Name
        dataReport.author.id:        123
        dataReport.message:            61 дм
       
        Для вывода в фрейм желательно записать в imgui значением, например, для mimgui
        чтобы вывело раз и навсегда без постоянной перекодировки в u8 в фрейм.
        если будет изменение в диалоге, то их нужно снова записать и выводить
       
        теперь записываем переменные для вывода фрейм:
        но желательно сначала создать локальные переменные для форматирование
        готовые рег. выражение для string.format:
        local author = string.format(dataReport.template.author, dataReport.author.nickname, dataReport.author.id)
        local message = string.format(dataReport.template.message, dataReport.message)

        записываем в строковых значениях mimgui и ид:
        dataReportImgui.state[0] = dataReport.state
        imgui.StrCopy(dataReportImgui.author, u8(author))
        imgui.StrCopy(dataReportImgui.message, u8(message))
    ]]
end

-- frame:
imgui.Text(dataReportImgui.author)
imgui.Text(dataReportImgui.message)

Бля дальше уже лень описывать
Прикольная ебанина, спасибо
 

kyrtion

Известный
871
304
1. Для создания IMGUI-диалога, который может взаимодействовать с SAMP, можно использовать различные методы. Один из способов заключается в использовании функций для отображения текста и получения данных от пользователя. Вот пример реализации такого диалога:
1726531467391.png

руки прочь от чатжпт