понедельник, 23 мая 2011 г.

Пишем ICQ Бота-шпаргалку


Скоро у меня экзамены - заканчиваю 9 класс. Решил сделать ICQ-бота, который выступит в роли шпаргалки. Вдруг попадется билет, который я не знаю. Все билеты учить, разумеется, лень, а хорошую оценку ой как хочется. Итак, как же будет работать наша программа?
Принцип таков: Мы отправляем номер билета боту, он в соответствии с предварительно составленной «базой» отправляет нам ответ. Как полагается, начнем с интерфейса. Для начала нам потребуется компонент ICQClient. Наверняка у тебя его нет, поэтому скачиваем по этой ссылке.
Как его установить?
1) Открываем TICQClient.dpk;
2)Переходим в меню Tools -> Environment Options -> Library;
3)Жмем кнопку "..." напротив Library path;
4)Добавляем путь к папке, где лежит компонент;
5)Возвращаемся к окну с открытым .dpk, жмем Compile и Install по очереди;
На вкладке Samples палитры компонентов должен появится наш компонент.


Кидаем на форму компоненты:
  • 1 Memo с именем ICQLog;
  • 2 Edit с именами UINEdit и PasswordEdit;
  • 2 Button с «кепшинами» - «Онлайн» и «Оффлайн», и именами OnlineBtn и OfflineBtn соответственно;
  • 1 Label, переименованный в ICQStatus;
  • 1 Timer;
  • 1 ICQClient, переименованный в ICQ;
При нажатии кнопки «Онлайн» будем подключаться к серверу. Для этого в обработчике кнопки пишем следующее:

procedure TForm1.ICQOnlineClick(Sender: TObject);
begin
// Проверяем корректность введеных значений
  if (UINEdit.Text = '') or (PasswordEdit.Text = '') then
// если поля пусты, то предупреждаем об этом пользователя
   MessageDlg('Поля UIN и Пароль не должны быть пустыми!',mtError,[mbYes],0)
  else
// Пытаемся подключиться
   begin
     ICQ.UIN := StrToInt(UINEdit.Text);
     ICQ.Password := PasswordEdit.Text;
      ICQ.Login();
      ICQLog.Lines.Add('Соединение сервером ICQ... ');
  end;
end;

Тут проверяем корректность введеных значений, если поля введены корректно то подключаемся и пишим в лог (ICQLog)  «Соединение сервером ICQ... »

Обработчик нажатия на кнопку «Оффлайн» довольно прост и понятен:

procedure TForm1.ICQOflineClick(Sender: TObject);
begin
 ICQ.Disconnect;
end;

Далее мы проверяем подключились ли мы. Для этого у ICQ создаем обработчик события OnLogin.

procedure TForm1.ICQLogin(Sender: TObject);
begin
  if ICQ.LoggedIn then
    begin
      ICQStatus.Caption := 'Онлайн'; // Меняем «статус» подключения
      OnlineBtn.Enabled := False; // Отключаем кнопку Онлайн
      OfflineBtn.Enabled := True; // Включаем кнопку Оффлайн
      Timer1.Enabled := True; // ...и таймер
    end
  else
    begin // Тут все, практически, наоборот
      ICQStatus.Caption := 'Оффлайн';
      OnlineBtn.Enabled := True;
      OfflineBtn.Enabled := False;
      Timer1.Enabled := False;
    end;
end;


Если (ICQ.LoggedIn) равно True мы «Онлайн», False мы «Офлайн».

Для таймера у нас заготовлен такой код:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  ICQ.SendKeepAlive; // Даем знать серверу, чтомы все еще Онлайн
  if ICQ.LoggedIn then // Дальше ты уже знаешь что происходит :-)
    begin
      ICQStatus.Caption := 'Онлайн';
      OnlineBtn.Enabled := False;
      OfflineBtn.Enabled := True;
      Timer1.Enabled := True;
    end
  else
     OfflineBtn.Enabled := False;
      Timer1.Enabled := False;
    end;
End;

SendKeepAlive нужно отсылать на сервер каждые 2 минуты чтобы давать знать что мы еще весим в «Онлайн»
В событие OnError все того же компонента ICQ суём вот такое:

procedure TForm1.ICQError(Sender: TObject; ErrorType: TErrorType;
  ErrorMsg: String);
begin
  ICQLog.Lines.Add('Ошибка при подключении. '); // Логируем событие
  Timer1.Enabled := False; // Отключаем таймер
End;

Вот и дошли до самого главного - событие OnMessageRecv. Оно позволяет получать входящие сообщения. В папке, например, «Информатика» будут хранится *.txt-файлы, которые проименованы по номерам билетов.
Здесь мы обрабатываем входящее сообщение. Отправлять боту мы будем только номер билета. А бот, если существует файл с таким именем (номером вопроса), открывает нужный файл, считывает ответ на вопрос билета и отсылает обратно.
procedure TForm1.ICQMessageRecv(Sender: TObject; Msg, UIN: String);
var
  f: TextFile; // Текстовый файл, который будем открывать
  bilet: String; // Содержимое файла
begin
  ICQLog.Lines.Add(UIN + ': ' + Msg); // Логируем входящее сообщение
  if FileExists('Информатика\' + Msg + '.txt') then
    begin // Если существует запрошенный файл...
      AssignFile(f,'Информатика\' + Msg + '.txt'); 
      Reset(f); // ...то открываем его для чтения
      While not Eof(f) do // И до конца файла
        ReadLn(f, bilet); // Считываем каждую строку
      ICQ.SendMessage(StrToInt(UIN), bilet); // Посылаем готовое сообщение
      ICQLog.Lines.Add(UINEdit.Text + ': ' + bilet); // и снова логируем
      CloseFile(f); // Освобождаем файл, т.к. больше он нам не понадобится
    end
  else // А если запрошенного билета (файла) нет
    begin
// Посылаем соответствующее сообщение клиенту
      ICQ.SendMessage(StrToInt(UIN),'Такого билета не существует!');
// И логируем
      ICQLog.Lines.Add(UIN +  ' : Такого билета не существует!');
    end;
end;

Вначале кода мы добавляем в лог уин того кто нам прислал сообщение, и содержимое. Далее мы проверяем на существования файла в папке «Информатике», если файл существует мы связываем переменную «f» с файлом, и открываем файл для чтения.И до конца строкмы добавляем в переменную «bilet» текст и предаем содержимое.Нам не нужно рыться в каком либо коде и изменять переменные где содержится информация о билета, нам придется всего лишь зайди в папку и добавить *.txt файл с номером билета. Программа откроет нужный файл при небходимости и отправит его содержимое.Вот и подходит к концу данная статья, мы рассмотрели компонент ICQClient и научилсь им пользоваться, сделали простенький бот который будет небольшой шпаргалкой на экзамене.

Комментариев нет:

Отправить комментарий

Сделай автору приятно - оставь комментарий!