- 2,741
- 31,897
- Закреплено
- #12
Некоторые знают, что была автоматическая версия скрипта (реворк v2.4) — с авто-скриншотом каждые Y строк и автоматической очисткой чата. В этой версии автоматики сознательно нет, и вот почему.
Автоматика, которая реально полезна (чтобы буфер чата не переполнялся между скриншотами), требует полной очистки истории чата после каждого снимка. Штатных команд SAMP для этого нет — единственный способ — лезть напрямую в структуру
CChat в памяти процесса и занулять поля.В реворке это делалось так:
memoryLib.fill(chat + 0x132, 0x0, 25200, true) -- занулить 25200 байтИменно эта строка ломала чат: инпут улетал в верхний левый угол, и спасти мог только перезаход. Причина простая — офсет
0x132 не является началом массива записей чата, как думал автор реворка. Там лежат служебные поля: текущий ввод, скроллбар, флаги состояния. Зануляешь их — ломаешь всё.Даже если убрать опасный
memoryLib.fill и оставить только сброс счётчика сообщений:memoryLib.setuint32(chat + 0x12E, 0, true) -- m_nMsgCount = 0…проблема не уходит полностью. Счётчик сброшен, а физические записи в буфере остались, и внутреннее состояние
CChat рассинхронизировано. SAMP хранит ещё и номер текущей страницы, масштаб текста, флаги инпута — всё это опирается на согласованное состояние, которое мы нарушаем вторжением в память.Три причины, почему прямой доступ к памяти CChat — плохая идея:
- Офсеты зависят от версии SAMP.
0x12E,0x132,0x13A— это для 0.3.7 R1. На другом билде они сдвинуты, и запись мимо = повреждение случайных полей. Скрипт не может это надёжно проверить. - Структура
CChatне задокументирована. Мы не знаем точно, что лежит по каждому офсету. Любой незнакомый офсет — лотерея: сегодня работает, завтра падает. - Даже «безопасный» сброс счётчика рассинхронизирует состояние. Счётчик говорит «0», а буфер полон.
PageUpпоказывает фантомные строки, инпут ведёт себя непредсказуемо.
К тому же счётчик строк сам по себе неточный. Он хукает только серверные сообщения, а клиентские (системные уведомления, ответы команд) пропускает. Поэтому авто-режим в любом случае работает криво — иногда делает лишний скриншот, иногда недодерживает.
Вывод: автоматический режим через прямую работу с памятью — это хождение по минному полю ради фичи, которая в принципе не может работать надёжно. Ручной режим по одной кнопке работает всегда, потому что использует только штатные API SAMP:
/fontsize,/pagesize— черезsampProcessChatInput;/blind— серверная команда;F8— черезsetVirtualKeyDown.
Эти функции безопасны по определению: их предоставляет сам SAMP/SAMPFUNCS, и они сами разбираются со своим внутренним состоянием. Ничего сломать невозможно.
Если кто-то хочет честную автоматику — её нужно делать на стороне сервера или через перехват рендера чата, а не через запись в чужую память. Это уже совсем другой проект.
---
- MoonLoader (рекомендуется 0.26.2+);
- SAMPFUNCS;
- (опционально) Chat++ — нужен, чтобы
/pagesizeработал больше 20 строк. Без него штатно ограничение 20.
Проверен на: SAMP 0.3.7 R1.
---
- Скопировать
sss.luaв папкуmoonloader. - Конфиг создастся сам при первом запуске:
moonloader\config\sss.ini. - Зайти в игру, ввести
/sssдля настройки.
---
Команда:
/sss — открыть меню настроек.В меню доступны:
- Клавиша активации — задаёте свою комбинацию (можно несколько клавиш через
+, напримерALT+P); - Размер шрифта при СС — от -3 до 5;
- Число строк при СС — от 10 до 64 (значения больше 20 требуют Chat++);
- Авто-стандарт — авто-возврат настроек из
sa-mp.cfgпосле скриншота; - Уведомления — вкл/выкл сообщения в чат от скрипта.
Снимок: нажать настроенную клавишу в игре — скрипт сам сделает всю работу.
---
🛠 Что было исправлено в v1.1
Оригинальный скрипт содержал несколько багов, из-за которых он падал или просто не работал. В этой версии пофикшено:
- Опечатка ampAddChatMessage — вместо
sampAddChatMessage. Крашила скрипт при вводе кривого размера шрифта в диалоге. - Хоткей не срабатывал — массив
buttIDхранил строки ("119") вместо чисел (119).isKeyJustPressed("119")получал строку вместо числа и молча возвращалfalse. То есть горячая клавиша просто не работала, даже если была настроена. VK_F8не был определён —setVirtualKeyDown(VK_F8, true)падал сattempt to index a nil value. Скриншот вообще не делался.- Конфиг сохранялся не туда —
inicfg.save(ini, 'sss')писал в файлsssв рабочем каталоге, а не вmoonloader\config\sss.ini. Дальшеinicfg.loadне находил конфиг, возвращалnil, и скрипт падал наmainIni.chat.fontsize. - Сброс клавиши при отмене — если в диалоге настройки клавиши нажать ESC, не нажав клавишу, старое значение
butt/buttIDтерялось навсегда. Приходилось перенастраивать заново. Теперь старое значение восстанавливается. - Срабатывание во время печати в чат — если печатал сообщение и случайно нажимал хоткей,
/fontsizeи/pagesizeуходили в чат как текст. Добавлена проверкаsampIsChatInputActive().
Также интерфейс полностью переведён на русский, убраны глобальные переменные, почищен устаревший синтаксис (
table.getn → #).- Chat++ (нужен для
/pagesize > 20): https://www.blast.hk/threads/20939/
Оставляю оригинальный скрипт, каким его задумывал автор. При наличии SS+ традиционные методы уходят на второй план.