Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
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;

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

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay