Witam. Piszę wtyczkę do komunikatora znajomego do obsługi GG i padłem tuż na wstępie. Chodzi o logowanie.

Informację czerpię z http://toxygen.net/libgadu/protocol/#ch1.3
I problem:
Jaki bym nie wysłał pakiet czy też logował się przez SHA, algorytm GG otrzymuję pakiet GG_LOGIN_FAILED 0x0009 - czyli błąd logowania. Dane są poprawne.

Procedura logowania:

var
  wd:wsadata;
  ad:sockaddr_in;
  Dane: ServInfo;
  Numer: Integer;
  Haslo: String;
begin
  Numer:= NUMER;
  Haslo:= 'HASLO';
  nr:= Numer;
  WSAStartup($101,wd);
  log('Inicjalizacja '+wd.szDescription);
  s:=socket(af_inet,sock_stream,ipproto_tcp);
  ad.sin_family:=af_inet;
  Dane:= PobierzIP(Numer);
  ad.sin_port:= nToHs(Dane.port);
  ad.sin_addr.s_addr:=Dane.ip;

  log('Podłączanie '+inet_ntoa(ad.sin_addr)+':'+inttostr(Dane.port));
  if connect(s, ad, 16) = 0 then
  begin
    log('Połączono!'#13#10'Logowanie '+inttostr(nr));
    recv(s, header, SizeOf(Header), 0);
    if (Header.typ = 1) then
      log('Pakiet: GG_WELCOME (1)')
    else
      log('Pakiet: Unknow ('+IntToStr(Header.typ)+')');

    recv(s, gg_welcome, SizeOf(gg_welcome), 0);
    log('Ziarno: ' + IntToStr(gg_welcome.seed));

    gg_login80.uin:= Numer;
    gg_login80.language:= 'pl';
    gg_login80.hash_type:= '1';
    gg_login80.hash := PChar(IntToStr(login_hash(haslo, gg_welcome.seed))+#0);
    //gg_login80.hash:= PChar(HashSHA1(haslo)+#0);

    gg_login80.status:= 2;
    gg_login80.flags:= 0;
    gg_login80.features:= $00000007;
    gg_login80.local_ip:= 0;
    gg_login80.local_port:= 0;
    gg_login80.external_ip:= 0;
    gg_login80.external_port:= 0;
    gg_login80.image_size:= 255;
    gg_login80.unknown2:= #64; //0x64
    gg_login80.version_len:= $21; // 32;
    gg_login80.version:= 'Gadu-Gadu Client build 8.0.0.7669';
    gg_login80.description_size:= 4;
    gg_login80.description:= 'abcd';

    Header.typ:= 49;
    Header.size:= SizeOf(gg_login80);
    send(s, Header, sizeof(Header), 0);
    send(s, gg_login80, sizeof(gg_login80), 0);

    recv(s, header, SizeOf(Header), 0);
    log(IntToStr(Header.typ));
    log(IntToStr(Header.Size));

    if (Header.typ = 9) then
      log('Login Failed (9)')
    else
    if (Header.typ = 53) then
      log('Logik OK (53)')
    else
      log('Unknow');

A tak wygląda pakiet, który sobie przetłumaczyłem:

gg_login80: packed record
  uin: integer;		{ numer Gadu-Gadu }
  language: array[0..2]of char;	 { język: "pl" }
  hash_type: char;	   { rodzaj funkcji skrótu hasła }
  hash: PChar;//array[0..64] of char;  { skrót hasła dopełniony \0 }
  status: integer;	 { początkowy status połączenia }
  flags: integer;	  { flagi (przeznaczenie nieznane) }
  features: integer;   { opcje protokołu (0x00000007)}
  local_ip: integer;   { lokalny adres połączeń bezpośrednich (nieużywany) }
  local_port: Word;	 { lokalny port połączeń bezpośrednich (nieużywany) }
  external_ip: integer;	  { zewnętrzny adres (nieużywany) }
  external_port: Word;  { zewnętrzny port (nieużywany) }
  image_size: Byte;	  { maksymalny rozmiar grafiki w KB }
  unknown2: Char; { 0x64 }
  version_len: integer;	  { długość ciągu z wersją (0x21) }
  version: array[0..32] of Char;	   { "Gadu-Gadu Client build 8.0.0.7669" (bez \0) }
  description_size: integer; { rozmiar opisu }
  description: array[0..255] of Char;   { opis (nie musi wystąpić, bez \0) }
end;