скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

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;

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






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook