Роботы, плагины и скрипты к чату MyChat. Разработка альтернативных клиентов и различных утилит. Технические вопросы по программированию, замечания и предложения по развитию API
Аватара пользователя
smartmarket
Добрый день!
Стояла версия чата 7.3

Есть следующий скрипт, который работал в данной версии
Скрипт выполняет функцию бота, на запрос присылает сообщение из файла

Код: Выделить всё
const
   Baza = 'c:\Ururu.txt';
function OnPrivateMessage(iCID, iUIN, iUINTo, iMsgType: integer; sMsg: string): boolean;
var
sCmd, sData: string;
iCount, i: integer;
begin
sCmd:='';

// получить текст команды
   sCmd := UpperCase(mConvertMsgToPlainText(sMsg, iMsgType));
  // если получатель сообщения - встроенный робот Elisa с UIN = 0
    if iUINTo = 2 then begin
   
      // смотрим, сколько в текстовом файле строк
    iCount := GetTextFileLinesCount(Baza);
   
        // идём по всему файлу в надежде встретить нужную нам строку
        for i := 1 to iCount do begin
          LoadLineFromFile(Baza, i, sData);
         
            // если нашли
            if pos(sCmd+'|', sData) = 1 then begin
              delete(sData, 1, length(sCmd)+1);
             
               mSendPrivateMessage(2, iUIN, sData, 1, true);
     
      end;
      end;
     end;
  result := true;
 
end;

begin

end.


После обновления перестал корректно работать, я так понял что он не считывает строки из файла которые идут по счету за 30 строкой.

Как теперь работает функция GetTextFileLinesCount? Как возможно это исправить?
Аватара пользователя
Алексей Пикуров
Здравствуйте. Перешлите мне на [email protected] ваш текстовый файл, я посмотрю.
Аватара пользователя
Алексей Пикуров
Код очень неоптимальный и будет тормозить, если текстовый файл будет расти.

Нужно написать вот так:

Код: Выделить всё
const
  BAZA = 'c:\Ururu.txt';
  BOT_UIN = 2;
 
function OnPrivateMessage(iCID, iUIN, iUINTo, iMsgType: integer; sMsg: string): boolean;
var
  sCmd, sData, s: string;
  x: integer;
begin
  result := true;
 
    if iUINTo = BOT_UIN then begin
      sCmd  := UpperCase(mConvertMsgToPlainText(sMsg, iMsgType));
      sData := LoadTextFromFile(BAZA, 0);
      x     := pos(sCmd + '|', sData);
   
        if x <> 0 then begin
          s := copy(sData, x, PosEx(CRLF, sData, x + 1) - x);
          Fetch(s, '|');
          mSendPrivateMessage(BOT_UIN, iUIN, s, 1, true);
          result := false;
        end;
    end;   
end;

begin

end.
Аватара пользователя
smartmarket
Благодарю! Стал читать весь файл, но обнаружил проблему, при отправке только цифр, не полного "кодового слова", а часть его, ответ все равно приходит, как добиться что бы ответ приходил при полном совпадении?
Аватара пользователя
Алексей Пикуров
Пожалуйста. Кодовое слово у вас всегда фиксированной ширины в 9 символов? Поставьте проверку в коде, проблемы не вижу.

Код: Выделить всё
    if iUINTo = BOT_UIN then begin
      sCmd  := UpperCase(mConvertMsgToPlainText(sMsg, iMsgType));
     
        if length(sCmd) = 9 then begin
          sData := LoadTextFromFile(BAZA, 0);
          x     := pos(sCmd + '|', sData);
   
            if x <> 0 then begin
              s := copy(sData, x, PosEx(CRLF, sData, x + 1) - x);
              Fetch(s, '|');
              mSendPrivateMessage(BOT_UIN, iUIN, s, 1, true);
              result := false;
            end;
        end;   
    end;   
Аватара пользователя
Алексей Пикуров
Насчёт функции GetTextFileLinesCount вы правы, она работала неверно из-за того, что неправильно определялась кодировка исходного файла.

Если файл чисто ASCII — то проблем не было, если кодировка win1251, как у вас, или UTF8 — то были проблемы.

В новой версии поправили, теперь в функции есть параметр для указания кодировки файла, войдет в релиз после версии 7.7.
Аватара пользователя
smartmarket
Благодарю! Будем ждать релиза!
Каким образом поступить если кодовое слово не фиксированной длины?
Аватара пользователя
Алексей Пикуров
Ну, по-другому код написать, подумайте сами, как построить условие.
Аватара пользователя
smartmarket
Добрый день! Заметил одну вещь при использовании данного скрипта :
Код: Выделить всё
const
  BAZA = 'c:\Ururu.txt';
  BOT_UIN = 2;
 
function OnPrivateMessage(iCID, iUIN, iUINTo, iMsgType: integer; sMsg: string): boolean;
var
  sCmd, sData, s: string;
  x: integer;
begin
  result := true;
 
    if iUINTo = BOT_UIN then begin
      sCmd  := UpperCase(mConvertMsgToPlainText(sMsg, iMsgType));
      sData := LoadTextFromFile(BAZA, 0);
      x     := pos(sCmd + '|', sData);
   
        if x <> 0 then begin
          s := copy(sData, x, PosEx(CRLF, sData, x + 1) - x);
          Fetch(s, '|');
          mSendPrivateMessage(BOT_UIN, iUIN, s, 1, true);
          result := false;
        end;
    end;   
end;

begin

end.


при попытке отправить снимок экрана из клиента чата или нажатием кнопки prnt scrn, скприпт присылает 1 строку из файла
Аватара пользователя
Алексей Пикуров
Чтобы ответить, надо иметь ваш текстовый файл.

У вас есть функция для отладки скриптов mLogScriptToDisk — запись промежуточных результатов в файл. Воспользуйтесь ею, чтобы понять, что идёт не так.
Аватара пользователя
Алексей Пикуров
Замените строку

Код: Выделить всё
if iUINTo = BOT_UIN then begin

на

Код: Выделить всё
if (iUINTo = BOT_UIN) and (iMsgType in [0,1]) then begin

Нужно обрабатывать только текстовые сообщения, остальные игнорировать. Типы сообщений MyChat.

Пользуйтесь отладкой, я нашёл проблему в условии за две минуты, просто вставил вызов AddLineToFile(sCmd, 'c:\temp\log.txt', 0); сразу после "sCmd := UpperCase(mConvertMsgToPlainText(sMsg, iMsgType));".