БОЛЬШОЙ FAQ ПО DELPHI



ICQ2000 сделай сам 9


Автор: Alexander Vaga
WEB-сайт: http://icq2000cc.hobi.ru

В pеалмод я больше не писюн... не писюк... не писец...

Прием сообщений

Все сообщения приходят в SNAC(4,07).

У него такой же формат, как и у SNAC(4,06). Поэтому стоит сразу комментировать код:

unit Main.pas;


 procedure TForm1.SNAC_4_7(p:PPack);
 var
     i,cnt,T,MessageFormat,SubMode,SubMode2,Empty : word;
     {myUIN,}
     hisUIN : longint;
     SubType : array[0..3] of byte;
     MessageSubType : longint absolute SubType;
     tmp,tmp2,tmp3 : PPack;
     sTemp : string;
     dTemp : TByteArray;
     typemes,
     {subtypemes,}
     unk,modifier,lenmes : word;
 
     // для SNAC(4,0B)-подтверждения принятых advanced сообщений
     d1,d2 : longint;
     ACK : TByteArray;
     ind : word;
 
     NewMsg : PMsgItem;
     FG : array[0..3] of byte;
     BG : array[0..3] of byte;
 begin
      // сохраняем Cookie-1 и Cookie-2
      d1:=PacketRead32(p);
      d2:=PacketRead32(p);
      // читаем формат сообщения
      MessageFormat := swap(PacketRead16(p));
      // от кого ?
      sTemp := PacketReadB_String(p);
 
      // Cookie-1,Cookie-2 и некоторую другую часть пакета сохраним.
      // Эти данные необходимо включить в ACK на это сообщение
      ind:=0;
      PLONG(@(ACK[ind]))^:=d1; inc(ind,4);
      PLONG(@(ACK[ind]))^:=d2; inc(ind,4);
      PWORD(@(ACK[ind]))^:=swap(MessageFormat);inc(ind,2);
      PBYTE(@(ACK[ind]))^:=length(sTemp);inc(ind,1);
      MOVE(sTemp[1],ACK[ind],length(sTemp));inc(ind,length(sTemp));
      PWORD(@(ACK[ind]))^:=swap($0003);inc(ind,2);
 
      // преобразуем его UIN из строки в longint
      try hisUIN := strtoint(sTemp); except hisUIN:=0; end;
      M(Memo,'< From: '+sTemp);
      PacketRead16(p);
      // узнаем сколько всего TLV во входящем пакете
      cnt := swap(PacketRead16(p));
      // читаем все эти TLV
      for i:=1 to cnt do
        // самый интересный - TLV(6)
        if TLVReadStr(p,sTemp)=6 then begin
          { в TLV(6) - его статус }
        end;
 
      // анализируем каждый из форматов
      case MessageFormat of
      $0001: begin
             M(Memo,'< Message-format:1 (SIMPLE)');
             // чтение TLV(2) в sTemp
             TLVReadStr(p,sTemp);
             // скопируем sTemp во временный PPack,
             // для удобства обработки
             tmp := PacketNew;
             PacketAppend(tmp,@(sTemp[1]),length(sTemp));
             PacketGoto(tmp,0);
             // обработаем его
             PacketRead16(tmp);
             PacketRead16(tmp);
             PacketRead8(tmp);
             PacketRead16(tmp);
             // добрались до длины сообщения
             lenmes := swap(PacketRead16(tmp))-4;
             PacketRead32(tmp);
             // читаем сообщение в sTemp
             PacketRead(tmp,@sTemp[1],lenmes);
             SetLength(sTemp,lenmes);
             // анализ содержания сообщения
             DoSimpleMsg(hisUIN,sTemp);
             // удалим временный PPack
             PacketDelete(tmp);
             end;
 
      $0002: begin
             M(Memo,'< Message-format:2 (ADVANCED)');
             // чтение TLV(5) в sTemp
             TLVReadStr(p,sTemp);
             // скопируем sTemp во временный PPack,
             // для удобства обработки
             tmp := PacketNew;
             PacketAppend(tmp,@(sTemp[1]),length(sTemp));
             PacketGoto(tmp,0);
             // обработаем его
             SubMode := swap(PacketRead16(tmp));
             PacketRead32(tmp);
             PacketRead32(tmp);
             PacketRead(tmp,@dTemp,16);
 
             case SubMode of
             $0000: begin
                    M(Memo,'SubMode: $0000 NORMAL');
                    TLVReadWord(tmp,SubMode2);
                    // TLV(F) - пустой
                    TLVReadWord(tmp,Empty);
                    // прием и анализ TLV(2711)
                    T := TLVReadStr(tmp,sTemp);
                    if T=$2711 then begin
                      // сохраняем кусок данных для ACKа
                      MOVE(sTemp[1],ACK[ind],47);inc(ind,47);
                      PLONG(@(ACK[ind]))^:=0; inc(ind,4);
 
                      // используем временный PPack
                      tmp2 := PacketNew;
                      PacketAppend(tmp2,@(sTemp[1]),length(sTemp));
                      PacketGoto(tmp2,0);
 
                      PacketRead(tmp2,@dTemp,26);
                      PacketRead8(tmp2);
                      PacketRead16(tmp2);
                      PacketRead16(tmp2);
                      PacketRead16(tmp2);
                      PacketRead(tmp2,@dTemp,12);
                      // читаем ТИП сообщения
                      typemes := PacketRead8(tmp2);
                      {subtypemes := }PacketRead8(tmp2);
                      unk:=swap(PacketRead16(tmp2));
                      modifier:=swap(PacketRead16(tmp2));
                      M(Memo,'Unk: $'+inttohex(unk,4));
                      M(Memo,'Modifier: $'+inttohex(modifier,4));
                      // длина сообщения
                      lenmes := PacketRead16(tmp2);
                      // анализ сообщения
                      NewMsg:=DoMsg(true,typemes,
                         lenmes,PCharArray(@(tmp2^.data[tmp2^.cursor])),
                         hisUIN,Now2DateTime);
                      // небольшая перемотка
                      PacketGoto(tmp2,(tmp2^.cursor)+lenmes);
                      // читаем Foreground и Background Colors
                      PacketRead(tmp2,@FG,4);
                      PacketRead(tmp2,@BG,4);
                      if NewMsg<>nil then begin
                        NewMsg^.FG:='$00'+inttohex(FG[2],2)+
                                          inttohex(FG[1],2)+
                                          inttohex(FG[0],2);
                        NewMsg^.BG:='$00'+inttohex(BG[2],2)+
                                          inttohex(BG[1],2)+
                                          inttohex(BG[0],2);
                      end;
                      // удаление временного PPack
                      PacketDelete(tmp2);
 
                      // дозаполнение ACK
                      PWORD(@(ACK[ind]))^:= 1; inc(ind,2);
                      PBYTE(@(ACK[ind]))^:= 0; inc(ind,1);
                      PLONG(@(ACK[ind]))^:= 0; inc(ind,4);
                      PLONG(@(ACK[ind]))^:=-1; inc(ind,4);
 
                      // посылка ACKа
                      tmp3 := CreatePacket($2,SEQ);
                      SNACAppend(tmp3,$4,$0B);
                      PacketAppend(tmp3,@ACK[0],ind);
                      PacketSend(tmp3);
                    end;
                    // Submode:$0000
                    end;
             $0001: M(Memo,'SubMode:$0001 ??? message canceled ???');
             $0002: M(Memo,'SubMode:$0002 FILE-ACK');
             // case SubMode
             end;
             PacketDelete(tmp);
             end;
 
      $0004: begin
             M(Memo,'< Message-format:4 '+
                    '(url or contacts or auth-req or userAddedYou)');
             TLVReadStr(p,sTemp);
             tmp := PacketNew;
             PacketAppend(tmp,@(sTemp[1]),length(sTemp));
             PacketGoto(tmp,0);
 
             hisUIN := PacketRead32(tmp);
             typemes := PacketRead8(tmp);
             {subtypemes := }
             PacketRead8(tmp);
 
             lenmes := PacketRead16(tmp);
             DoMsg(true,typemes,
               lenmes,PCharArray(@(tmp^.data[tmp^.cursor])),
               hisUIN,Now2DateTime);
 
             PacketDelete(tmp);
             end;
        else M(Memo,'< ??? SNAC 4,7; Message-format: '+s(MessageFormat));
      // case MessageFormat
      end;
 end;
 

продолжение следует ...




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Видеокурс ВЗЛОМ