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;
|