Protokół GG. Problem z zalogowaniem się.

0

Witam,

na razie mam taki kod

#include <iostream>
#include <winsock2.h>
#include <windows.h>

using namespace std;

struct gg_header {
	int type;		/* typ pakietu */
    int length;		/* dlugosc reszty */
}header;

#define GG_WELCOME 0x0001

struct gg_welcome {
	int seed;		/* klucz szyfrowania hasla */
}welcome;

#define GG_LOGIN60 0x0015

struct gg_login60 {
	int uin;				/* numer */
	int hash;				/* hash hasla */
	int status;				/* status na wjazd */
	int version;			/* wersja klienta */
	char unknown1;			/* 0x00 */
	int local_ip;			/* moje ip */
	short local_port;		/* port na ktorym slucham */
	int external_ip;		/* zew. ip */
	short external_port;	/* zew. port */
	char image_size;		/* maks. rozm. grafiki z kb */
	char unknown2;			/* 0xbe */
	char description[];		/* opis / nie musi byc */
	int time;				/* czas / nie musi byc */
}login;

#define GG_NEW_STATUS 0x0002

struct gg_new_status {
	int status;				/* na jaki zmienic */
	char description[];		/* opis / nie musi byc */
	int time;				/* czas / nie musi byc */
}nstatus;

int gg_login_hash(char *password, unsigned int seed)
{
	unsigned int x, y, z;

	y = seed;

	for (x = 0; *password; password++) {
		x = (x & 0xffffff00) | *password;
		y ^= x;
		y += x;
		x <<= 8;
		y ^= x;
		x <<= 8;
		y -= x;
		x <<= 8;
		y ^= x;

		z = y & 0x1f;
		y = (y << z) | (y >> (32 - z));
	}

	return y;
}

void clear(struct gg_header *header)
{

	header->type = 0;
	header->length = 0;

}

int main(int argc, char **argv[])
{
    
    WSADATA wsd;
    SOCKET sock;
    struct sockaddr_in server;
	
	int numer = 12345;
	char *password = "jakies haslo";
	
    
    if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)
	{
	
		cout<<"Nie mozna utworzyc WinSocka\r\n";
		cout.flush();
		return 1;
	
	}
	
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sock == INVALID_SOCKET)
	{
	
		cout<<"Nie mozna utworzyc gniazda ( "<<WSAGetLastError()<<" )\r\n";
		cout.flush();
		return 2;
	
	}
	
	server.sin_family = AF_INET;
	server.sin_port = htons((u_short)8074);
	server.sin_addr.s_addr = inet_addr("91.214.237.11");
	
	cout<<"ip: "<<inet_addr("91.214.237.11")<<"\r\n";
	cout<<"port: "<<htons((u_short)8074)<<"\r\n";
	cout.flush();
	
	if(connect(sock, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
	{
	
		cout<<"Nie mozna sie polaczyc ( "<<WSAGetLastError()<<" )\r\n";
		cout.flush();
		return 3;
	
	}
	
	clear(&header);
	
	/******* pobieranie seeda *******/
	
	if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
	{
	
		if(recv(sock, (char *)&welcome, header.length, 0) > 0)
		{
		
			cout<<"seed: "<<welcome.seed<<"\r\n";
			cout.flush();
		
		} else {
		
			cout<<"seed failed\r\n";
			cout.flush();
		
		}
	
	}
	
	login.uin = numer;
	login.hash = gg_login_hash(password, welcome.seed);
	login.status = 0x0002;
	login.version = 0x20;
	login.unknown1 = 0x00;
	login.local_ip = 0x00;
	login.local_port = 1550;
	login.external_ip = 0x00;
	login.external_port = 1550;
	login.unknown2 = 0xbe;
	login.image_size = 256;
	//login.description[]
	//login.time
	
	/****** logowanie *****/
	
	#define GG_LOGIN_OK 0x0003
	#define GG_LOGIN_FAILED 0x0009
	
	
	clear(&header);
	
	header.type = GG_LOGIN60;
	header.length = sizeof(login);
	
	if(send(sock, (char *)&header, sizeof(header), 0) > 0)
	{
		
		if(send(sock, (char *)&login, sizeof(login), 0) > 0)
		{
		
			clear(&header);
			
			//if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
			//{
			
                recv(sock, (char *)&header, sizeof(header), 0);
				if(header.type == GG_LOGIN_OK)
				{
				
					cout<<"login ok\r\n";
					cout.flush();
				
				} else if (header.type == GG_LOGIN_FAILED)
				{
				
					cout<<"login failed\r\n";
					cout.flush();
				
				} else {
				
					cout<<"wtf?!\r\n";
				
				}
				
                cout<<header.length<<"\r\n";
				cout.flush();
				printf("0x%x\r\n", header.type);
			
			//}
		
		}
	
	}
	
	closesocket(sock);
	WSACleanup();
	
	getchar();
	
	return 0;
	
}

Mam problem z zalogowaniem się. Dostaję ciągle status 0 zamiast 3 (prawidłowe zalogowanie się) czy nawet 9 (nieprawidłowe zalogowanie). Czy ktoś wie gdzie jest problem ?

0

Masz błędy w definicji struktur, ich pola powinny być upakowane bajt po bajcie.
To znaczy że pole INT po CHAR powinno być pod adresem pola CHAR plus jeden. Domyślne 'pakowanie' jest 8, czyli typy ośmiobajtowe i większe zawsze będą pod adresem podzielnym przez 8, a mniejsze (int, short) pod adresem podzielnym przez ich wielkość (4,2).

GCC:

struct s1{}PACKED;

MSVC:

#pragma pack(push)
#pragma pack(1)
struct s1{};
struct s2{};
#pragma pack(pop)

sizeof(struct {char,int}) będzie domyślnie 8, a z pakowaniem 1 spadnie do pięciu bajtów.

0

Poprawiłem, cały kod wygląda teraz tak

#include <iostream>
#include <winsock2.h>
#include <windows.h>

using namespace std;

struct gg_header {
	int type;		/* typ pakietu */
    int length;		/* dlugosc reszty */
}PACKED;

#define GG_WELCOME 0x0001

struct gg_welcome {
	int seed;		/* klucz szyfrowania hasla */
}PACKED;

#define GG_LOGIN60 0x0015

struct gg_login60 {
	int uin;				/* numer */
	int hash;				/* hash hasla */
	int status;				/* status na wjazd */
	int version;			/* wersja klienta */
	char unknown1;			/* 0x00 */
	int local_ip;			/* moje ip */
	short local_port;		/* port na ktorym slucham */
	int external_ip;		/* zew. ip */
	short external_port;	/* zew. port */
	char image_size;		/* maks. rozm. grafiki z kb */
	char unknown2;			/* 0xbe */
	char description[];		/* opis / nie musi byc */
	int time;				/* czas / nie musi byc */
}PACKED;

#define GG_NEW_STATUS 0x0002

struct gg_new_status {
	int status;				/* na jaki zmienic */
	char description[];		/* opis / nie musi byc */
	int time;				/* czas / nie musi byc */
}PACKED;

int gg_login_hash(char *password, unsigned int seed)
{
	unsigned int x, y, z;

	y = seed;

	for (x = 0; *password; password++) {
		x = (x & 0xffffff00) | *password;
		y ^= x;
		y += x;
		x <<= 8;
		y ^= x;
		x <<= 8;
		y -= x;
		x <<= 8;
		y ^= x;

		z = y & 0x1f;
		y = (y << z) | (y >> (32 - z));
	}

	return y;
}

/*void clear(struct gg_header *header)
{

	header->type = 0;
	header->length = 0;

}*/

int main(int argc, char **argv[])
{
    
    WSADATA wsd;
    SOCKET sock;
    struct sockaddr_in server;
    struct gg_welcome welcome;
    struct gg_login60 login;
    struct gg_new_status nstatus;
    struct gg_header header;
	
	int numer = twoj_nr;
	char *password = "haslo";
	
    
    if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)
	{
	
		cout<<"Nie mozna utworzyc WinSocka\r\n";
		cout.flush();
		return 1;
	
	}
	
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sock == INVALID_SOCKET)
	{
	
		cout<<"Nie mozna utworzyc gniazda ( "<<WSAGetLastError()<<" )\r\n";
		cout.flush();
		return 2;
	
	}
	
	server.sin_family = AF_INET;
	server.sin_port = htons((u_short)8074);
	server.sin_addr.s_addr = inet_addr("91.214.237.11");
	
	cout<<"ip: "<<inet_addr("91.214.237.11")<<"\r\n";
	cout<<"port: "<<htons((u_short)8074)<<"\r\n";
	cout.flush();
	
	if(connect(sock, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
	{
	
		cout<<"Nie mozna sie polaczyc ( "<<WSAGetLastError()<<" )\r\n";
		cout.flush();
		return 3;
	
	}
	
	header.type = 0;
	header.length = 0;
	
	/******* pobieranie seeda *******/
	
	if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
	{
	
		if(recv(sock, (char *)&welcome, header.length, 0) > 0)
		{
		
			cout<<"seed: "<<welcome.seed<<"\r\n";
			cout<<"header type: "<<header.type<<"\r\n";
			cout.flush();
		
		} else {
		
			cout<<"seed failed\r\n";
			cout.flush();
			return 4;
		
		}
	
	}
	
	login.uin = numer;
	login.hash = gg_login_hash(password, welcome.seed);
	login.status = 0x0002;
	login.version = 0x20;
	login.unknown1 = 0x00;
	login.local_ip = 0x00;
	login.local_port = 1550;
	login.external_ip = 0x00;
	login.external_port = 1550;
	login.unknown2 = 0xbe;
	login.image_size = 256;
	//login.description[]
	//login.time
	
	/****** logowanie *****/
	
	#define GG_LOGIN_OK 0x0003
	#define GG_LOGIN_FAILED 0x0009
	
	
	header.type = 0;
	header.length = 0;
	
	header.type = GG_LOGIN60;
	header.length = sizeof(login);
	
	if(send(sock, (char *)&header, sizeof(header), 0) > 0)
	{
		
		if(send(sock, (char *)&login, sizeof(login), 0) > 0)
		{
		
			header.type = 0;
			header.length = 0;
			
			//if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
			//{
			
                recv(sock, (char *)&header, sizeof(header), 0);
				if(header.type == GG_LOGIN_OK)
				{
				
					cout<<"login ok\r\n";
					cout.flush();
				
				} else if (header.type == GG_LOGIN_FAILED)
				{
				
					cout<<"login failed\r\n";
					cout.flush();
				
				} else {
				
					cout<<"wtf?!\r\n";
				
				}
				
                cout<<header.length<<"\r\n";
				cout.flush();
				printf("0x%x\r\n", header.type);
			
			//}
		
		}
	
	}
	
	closesocket(sock);
	WSACleanup();
	
	getchar();
	
	return 0;
	
}

I dalej nie otrzymuję ani 3 ani 9, tylko zero.

0

login.image_size = 256; // 9 bitów zmieści się w 8?

Zastanów się nad dwoma ostatnimi polami w gg_login60. Pierwsze z nich (description) jest opcjonalne, tzn może być, ale nie musi. Jeżeli jest, to musi kończyć się zerem.
Drugie (time) też jest opcjonalne, ale może być tylko wtedy, gdy pierwsze istnieje, a ponieważ time nie ma stałej pozycji w strukturze, nie może istnieć w definicji struktury.

0

Miałem taki sam wątek założyć :D
Też mam z tym problem, tyle że używam protokołu w wersji 8.

//main.cpp:
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <string>
#include "declars.h"
#include "SHA1.h"
using namespace std;

int main()
{

	gg_welcome welcome;
	gg_login80 login;


	SOCKET      sock;
	sockaddr_in addr;
	WSAData     data;

	WSAStartup(MAKEWORD(2,2), &data);
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	addr.sin_addr.S_un.S_addr = inet_addr("91.214.237.17");
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8074);

	if(connect(sock, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
	{
		cerr << "could not connect\n";
		cin.get();
		return -1;
	}

	cout << "connected\n";

	recv(sock, (char*)&welcome, sizeof(welcome), 0);
	cout << "seed: " << welcome.seed << endl;

	string result;
	CSHA1 sha1;
	sha1.Update((const unsigned char*)&pass, strlen(pass));
	sha1.Update((const unsigned char*)&welcome.seed, sizeof(welcome.seed));
	sha1.Final();
	sha1.ReportHashStl(result, CSHA1::REPORT_HEX_SHORT);
	strcpy(login.hash, result.c_str());
	for(int i = 40; i < 64; i++)
	{
		login.hash[i] = '\0';
	}

	
	login.uin = 13039737;
	strcpy(login.language, "pl");
	login.hash_type = 0x02;
	login.status = 	0x0002;
	login.flags = 0;
	login.features = 0x00000007;
	login.local_ip = 0;
	login.local_port = 0;
	login.external_ip = 0;
	login.external_port = 0;
	login.image_size = 255;
	login.unknown1 = 0x64;
	login.version_len = 0x23;
	strcpy(login.version, "Gadu-Gadu Client build 10.0.0.10450");
	login.type = 0x0031;
	login.size = sizeof(login) - 8;

	send(sock, (char*)&login, sizeof(login), 0);
	int buf = 0;
	recv(sock, (char*)&buf, 4, 0);
	cout << buf;

	cin.get();
	return 0;
};

//declars.h:
#pragma pack(push)
#pragma pack(1)

struct gg_welcome {
	int type, size;
	int seed;	
};

struct gg_login80 {
		int type, size;
        int uin;              /* numer Gadu-Gadu */
        char language[2];     /* język: "pl" */
        char hash_type;       /* rodzaj funkcji skrótu hasła */
        char hash[64];        /* skrót hasła dopełniony \0 */
        int status;           /* początkowy status połączenia */
        int flags;            /* początkowe flagi połączenia */
        int features;         /* opcje protokołu (0x00000367)*/
        int local_ip;         /* lokalny adres połączeń bezpośrednich (nieużywany) */
        short local_port;     /* lokalny port połączeń bezpośrednich (nieużywany) */
        int external_ip;      /* zewnętrzny adres (nieużywany) */
        short external_port;  /* zewnętrzny port (nieużywany) */
        char image_size;      /* maksymalny rozmiar grafiki w KB */
        char unknown1;        /* 0x64 */
        int version_len;      /* długość ciągu z wersją (0x23) */
        char version[];       /* "Gadu-Gadu Client build 10.0.0.10450" (bez \0) */
};


#pragma pack(pop)

Też cały czas dostaję 0.

0
sapero napisał(a)

login.image_size = 256; // 9 bitów zmieści się w 8?

Zastanów się nad dwoma ostatnimi polami w gg_login60. Pierwsze z nich (description) jest opcjonalne, tzn może być, ale nie musi. Jeżeli jest, to musi kończyć się zerem.
Drugie (time) też jest opcjonalne, ale może być tylko wtedy, gdy pierwsze istnieje, a ponieważ time nie ma stałej pozycji w strukturze, nie może istnieć w definicji struktury.

To z image_size już poprawione, ale nie rozumiem o co Ci chodzi z tymi 2 polami. Z tego co ja zrozumiałem to time musi być jeżeli jest description, ale skoro go nie ma to i time też nie ma :D Czyli co, mam wywalić time z definicji ?

0

Musisz wywalić time ze struktury bo i tak nie użyjesz go bezpośrednio. Jedyny sposób na użycie go to

char *pszOpis = "będę o";
size_t opisLen = strlen(pszOpis)+1;
gg_login60 *login = (gg_login60*)new char[sizeof(gg_login60)/*31*/ + opisLen + sizeof(int)/*4*/];
login->... = ...;
memcpy(login->description, pszOpis, opisLen);

int *pTime = (int*)(&login->description[opisLen]);
*pTime = ...;

Musisz też się upewnić że "char description[]" ma rozmiar ZERO, o ile chcesz używać sizeof(gg_login60) jako wzorca (=31). W przeciwnym wypadku musisz sobie pododawać rozmiary zmiennych i wstawić sumę do jakiegoś #define, albo użyj makra FIELD_OFFSET(gg_login60, description).

char description[0] jest akceptowane przynajniej w gcc, i jasno widać że nie zajmuje pamięci.

Poza tym dobrze by było gdyby wszystkie struktury wysyłane miały na początku header, by jednym send() załatwić sprawę.

struct gg_login60
{
   gg_header hdr;
   //tutaj pola gg_login60, ale bez time
}

W tym przypadku pobierając sizeof(gg_login60) musisz odjąc sizeof(gg_header).

HCK

login.size = sizeof(login) - 8;

Taki rozmiar wycina login.version z pakietu, astrcpy(login.version, "Gadu-Gadu Client build 10.0.0.10450");

nadpisuje Ci jakieś zmienne, bo gg_login80.version[] jest zbyt małe by pomieścić ten string. Zaalokuj strukturę przez NEW, malloc,alloca, albo na stałe ustaw X w char version[X] (w gg_login80) na rozmiar tego stringa +1.

Ewentualnie użyj jakiegoś bufora char[sizeof(gg_login80)+max_text_size] i castuj go na gg_login80*. Pola version i size zainicjuj wtedy tak:
```cpp
strcpy(login->version, "Gadu-Gadu Client build 10.0.0.10450");
login->size = sizeof(gg_login80) - 8/*header*/ + strlen(login->version) /* + 1 jeśli trzeba*/;
0

Zrobiłem jak napisałeś, ale bez dodawania headera, na razie wygląda to tak

struct gg_login60 {
	int uin;				/* numer */
	int hash;				/* hash hasla */
	int status;				/* status na wjazd */
	int version;			/* wersja klienta */
	char unknown1;			/* 0x00 */
	int local_ip;			/* moje ip */
	short local_port;		/* port na ktorym slucham */
	int external_ip;		/* zew. ip */
	short external_port;	/* zew. port */
	char image_size;		/* maks. rozm. grafiki z kb */
	char unknown2;			/* 0xbe */
	char description[0];	/* opis / nie musi byc */
	//int time;				/* czas / nie musi byc */
}PACKED;
	login.uin = numer;
	login.hash = gg_login_hash(password, welcome.seed);
	login.status = 0x0002;
	login.version = 0x20;
	login.unknown1 = 0x00;
	login.local_ip = 0x00;
	login.local_port = 1550;
	login.external_ip = 0x00;
	login.external_port = 1550;
	login.unknown2 = 0xbe;
	login.image_size = 128;
	//login.description[]
	//login.time

i nadal dostaję 0 ;/

0
		type	49	int
		size	137	int
		uin	13039737	int
		language	0x003dfe4c "pl"	char [3]
		hash_type	2 ''	char
		hash	0x003dfe50 "tutaj hasz"	char [64]
		status	2	int
		flags	0	int
		features	7	int
		local_ip	0	int
		local_port	0	short
		external_ip	0	int
		external_port	0	short
		image_size	-1 'ÿ'	char
		unknown1	100 'd'	char
		version_len	35	int
		version	0x003dfeae "Gadu-Gadu Client build 10.0.0.10450"	char [35]

Taką tę strukturę mam kiedy ją wysyłam, dalej 0 dostaję.

0

login.features = 0x00000007;

hck, wg. opisu protokolu 8 tam powinno być wartość 0x00000367 a nie taka jak ty wpisałeś :)

int features; /* opcje protokołu (0x00000367)*/

edit

sory, niedoczytałem :p

edit2

taką prośbę mam, jakby ktoś posiadał działający kodzik (łączy z serwerem, powiedzmy zmienia status i rozłącza) bo ja już serio nie iwem o co chodzi z tym moim kodem, to prosiłbym o wrzucenie chociaż kawałka :P

0

http://www.sendspace.com/file/zpt3dz
To klient 6.0, pisałem go przed wojną w devcpp, a dzisiaj przeniosłem pod CB.
Ma dwa proste boty odpowiadające i częściowo obsługuje listę userów pobraną z serwera.

0

Sory za post pod postem.

Próbuję to samo zrobić na podstawie dokumentacji do protokolu 8 http://toxygen.net/libgadu/protocol/ i na linuksie ale dalej, tak jak wcześniej i tak jak hck w odpowiedzi mam 0 zamiast ładnej strukturki.

#include <iostream>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <openssl/sha.h>

using namespace std;

#define GG_PACKED __attribute__ ((packed))
#define GG_WELCOME 0x0001
#define GG_LOGIN80 0x0031
#define GG_LOGIN80_OK 0x0035
#define GG_LOGIN80_FAILED 0x0043

struct gg_header {

	int type;	/* typ */
	int length;	/* dl. reszty */
	
}GG_PACKED;

struct gg_welcome {

	int seed;	/* ziarno */

}GG_PACKED;

struct gg_login80 {

	int uin;
	char language[2];	/* "pl" */
	char hash_type;		/* 0x02 */
	char hash[64];
	int status;		/* 0x0002 */
	int flags;
	int features;		/*0x00000007 */
	int local_ip;		/*0*/
	short local_port;	/*0*/
	int external_ip;	/*0*/
	short external_port;	/*0*/
	char image_size;
	char unknown1;		/* 0x64 */
	int version_len;	/* 0x23 */
	char version[37];	/* Gadu-Gadu Client build 10.0.0.10450 */
	int description_size;
	char description[32];
	
}GG_PACKED;

struct gg_login80_ok {

	int unknown1;

}GG_PACKED;

struct gg_login80_failed {

	int unknown1;
	
}GG_PACKED;

char *gg_sha_hash(const char *password, unsigned int seed)
{
	SHA_CTX ctx;
	static char result[20];
	  
	SHA_Init(&ctx);  
	SHA_Update(&ctx, password, strlen(password));
	SHA_Update(&ctx, &seed, sizeof(seed));
	SHA_Final((unsigned char *)result, &ctx);

	return result;
}

void clear(struct gg_header *pHead)
{

	pHead->type = 0;
	pHead->length = 0;

}

int main(int argc, char *argv[])
{
	int sock = 0;
	int numer = numer;
	const char *pass = "haslo";
	struct sockaddr_in server;
	struct gg_header header;
	struct gg_welcome welcome;
	struct gg_login80 login;
	struct gg_login80_ok lok;
	struct gg_login80_failed lfailed;
	
	server.sin_family = AF_INET;
	server.sin_port = htons((u_short)8074);
	server.sin_addr.s_addr = inet_addr("91.214.237.11");
	memset(&(server.sin_zero), '\0', 8);
	
	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
	{
	
		cout<<"socket()\r\n";
		cout.flush();
		fprintf(stderr, "%s\r\n", strerror(errno));
		return -1;
	
	}
	
	cout<<"ip: "<<server.sin_addr.s_addr<<"\r\n";
	cout<<"port: "<<server.sin_port<<"\r\n";
	cout.flush();
	
	if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
	{
	
		cout<<"connect()\r\n";
		cout.flush();
		fprintf(stderr, "%s\r\n", strerror(errno));
		return -1;
	
	}
	
	clear(&header);
	
	if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
	{
	
		if(recv(sock, (char *)&welcome, header.length, 0) > 0)
		{
		
			cout<<"header type: "<<header.type<<"\r\n";
			cout<<"seed: "<<welcome.seed<<"\r\n";
			cout.flush();
		
		} else {
		
		
			cout<<"recv seed 2\r\n";
			cout.flush();
		
		}
	
	}
	
	clear(&header);
	
	login.uin = numer;
	sprintf(login.language, "pl");
	login.hash_type = 0x02;
	sprintf(login.hash, gg_sha_hash(pass, welcome.seed));
	for(unsigned int i = sizeof(login.hash); i > strlen(login.hash); i--)
	{
	
		login.hash[i] = '\0';
	
	}
	login.status = 0x0002;
	login.flags = 0;
	login.features = 0x00000007;
	login.local_ip = 0;
	login.local_port = 0;
	login.external_ip = 0;
	login.external_port = 0;
	login.image_size = 128;
	login.unknown1 = 0x64;
	login.version_len = 0x23;
	sprintf(login.version, "Gadu-Gadu Client build 10.0.0.10450");
	login.description_size = 0;
	login.description[0] = '\0';
	
	header.type = GG_LOGIN80;
	header.length = sizeof(login);
	
	if(send(sock, (char *)&header, sizeof(header), 0) > 0)
	{
	
		if(send(sock, (char *)&login, sizeof(login), 0) > 0)
		{
		
			clear(&header);
			
			if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
			{
			
				cout<<"-- header type: "<<header.type<<"\r\n";
				cout.flush();
			
			}
			
			cout<<"header type: "<<header.type<<"\r\n";
			cout.flush();
		
		}
	
	}
	
	close(sock);
	
	return 0;

}

Chciałbym aby ten program otrzymywał poprawną odpowiedź z serwera, no ale nie wychodzi mi. Jeśli ktoś zna odp. to proszę niech pomoże.

0

Dobra mam przełom :D Znów sory za post pod postem.

#include <iostream>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <openssl/sha.h>

using namespace std;

#define GG_PACKED __attribute__ ((packed))
#define GG_WELCOME 0x0001
#define GG_LOGIN80 0x0031
#define GG_LOGIN80_OK 0x0035
#define GG_LOGIN80_FAILED 0x0043
#define GG_LIST_EMPTY 0x0012

struct gg_header {

	int type;	/* typ */
	int length;	/* dl. reszty */
	
}GG_PACKED;

struct gg_welcome {

	int seed;	/* ziarno */

}GG_PACKED;

struct gg_login80 {

	int uin;
	char language[2];	/* "pl" */
	char hash_type;		/* 0x02 */
	char hash[64];
	int status;		/* 0x0002 */
	int flags;
	int features;		/*0x00000007 */
	int local_ip;		/*0*/
	short local_port;	/*0*/
	int external_ip;	/*0*/
	short external_port;	/*0*/
	char image_size;
	char unknown1;		/* 0x64 */
	int version_len;	/* 0x23 */
	char version[36];	/* Gadu-Gadu Client build 10.0.0.10450 */
	int description_size;
	char description[32];
	
}GG_PACKED;

/*struct gg_login80_ok {

	int unknown1;

}GG_PACKED;

struct gg_login80_failed {

	int unknown1;
	
}GG_PACKED;*/

char *gg_sha_hash(const char *password, unsigned int seed)
{
	SHA_CTX ctx;
	static char result[20];
	  
	SHA_Init(&ctx);  
	SHA_Update(&ctx, password, strlen(password));
	SHA_Update(&ctx, &seed, sizeof(seed));
	SHA_Final((unsigned char *)result, &ctx);

	return result;
}

void clear(struct gg_header *pHead)
{

	pHead->type = 0;
	pHead->length = 0;

}

int main(int argc, char *argv[])
{
	int sock = 0;
	int numer = numerek;

	const char *pass = "haselko";
	struct sockaddr_in server;
	struct gg_header header;
	struct gg_welcome welcome;
	struct gg_login80 login;
	/*struct gg_login80_ok lok;
	struct gg_login80_failed lfailed;*/
	
	server.sin_family = AF_INET;
	server.sin_port = htons((u_short)8074);
	server.sin_addr.s_addr = inet_addr("91.214.237.11");
	memset(&(server.sin_zero), '\0', 8);
	
	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
	{
	
		cout<<"socket()\r\n";
		cout.flush();
		fprintf(stderr, "%s\r\n", strerror(errno));
		return -1;
	
	}
	
	cout<<"ip: "<<server.sin_addr.s_addr<<"\r\n";
	cout<<"port: "<<server.sin_port<<"\r\n";
	cout.flush();
	
	if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
	{
	
		cout<<"connect()\r\n";
		cout.flush();
		fprintf(stderr, "%s\r\n", strerror(errno));
		return -1;
	
	}
	
	clear(&header);
	
	if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
	{
	
		if(recv(sock, (char *)&welcome, header.length, 0) > 0)
		{
		
			cout<<"header type: "<<header.type<<"\r\n";
			cout<<"seed: "<<welcome.seed<<"\r\n";
			cout.flush();
		
		} else {
		
			cout<<"recv seed 2\r\n";
			cout.flush();
		
		}
	
	}
	
	clear(&header);
	
	login.uin = numer;
	sprintf(login.language, "pl");
	login.hash_type = 0x02;
	sprintf(login.hash, gg_sha_hash(pass, welcome.seed));
	for(unsigned int i = sizeof(login.hash); i > strlen(login.hash); i--)
	{
	
		login.hash[i] = '\0';
	
	}
	login.status = 0x0002;
	login.flags = 0;
	login.features = 0x00000367;
	login.local_ip = 0;
	login.local_port = 0;
	login.external_ip = 0;
	login.external_port = 0;
	login.image_size = 64;
	login.unknown1 = 0x64;
	login.version_len = 0x23;
	sprintf(login.version, "Gadu-Gadu Client build 10.0.0.10450");
	login.description_size = 0;
	login.description[0] = '\0';
	
	header.type = GG_LOGIN80;
	header.length = sizeof(login);
	
	if(send(sock, (char *)&header, sizeof(header), 0) > 0)
	{
	
		if(send(sock, (char *)&login, sizeof(login), 0) > 0)
		{
		
			clear(&header);
			
			if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
			{
			
				if(header.type == GG_LOGIN80_OK)
				{
				
					cout<<"login ok\r\n";
					cout.flush();
				
				} else if(header.type == GG_LOGIN80_FAILED) {
				
					cout<<"login failed\r\n";
					cout.flush();
				
				} else {
				
					cout<<"wtf\r\n";
					cout.flush();
				
				}
				
			}
			
			cout<<"header type: "<<header.type<<"\r\n";
			cout.flush();
		
		}
	
	}
	
	close(sock);
	
	return 0;

}

Jak cały czas zwracało 0, tak teraz zwraca 0x0043 czyli login failed :D ale zawsze coś :) ale nadal nie loguje no... :(

EDIT

i jeszcze pytanie, czy ten hash powinien wyglądać tak

header type: 1
seed: -403436217
�6jn=�j�n�$�ѥ�Y�
login failed
header type: 67

Mam na myśli tą linijke z tymi dziwnymi znaczkami, bo coś mi się nie wydaję, ale może się mylę.

0

Coś jest źle.
Zesniffowałem GG.
GG 10:

(TCP)192.168.0.134:3281->91.197.13.42:8074 ,188 Bytes

45 00 00 BC 67 86 40 00 80 06 00 00 C0 A8 00 86  ; E...g.@.........
5B C5 0D 2A 0C D1 1F 8A 83 78 55 06 28 DF 64 8C  ; [..*....xU.(.d.
50 18 2F FD 2A CC 00 00 31 00 00 00 8C 00 00 00  ; P/.*...1.......
79 F8 C6 00 70 6C 02 80 25 C0 95 CE A6 20 F0 D1  ; y...pl..%.... ..
BE 12 4D 84 F2 0F F5 55 3F 5F E6 00 00 00 00 00  ; ..M....U?_......
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ; ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ; ................
00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 37  ; ...............7
07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF  ; ................
64 23 00 00 00 47 61 64 75 2D 47 61 64 75 20 43  ; d#...Gadu-Gadu C
6C 69 65 6E 74 20 62 75 69 6C 64 20 31 30 2E 30  ; lient build 10.0

Mój klient:

(TCP)192.168.0.134:3449->91.214.237.17:8074 ,221 Bytes

45 00 00 DD 09 2F 40 00 80 06 00 00 C0 A8 00 86  ; E..../@.........
5B D6 ED 11 0D 79 1F 8A 6A A5 D8 E9 7A 1C 52 93  ; [....y.j...zR.
50 18 40 26 0A E6 00 00 31 00 00 00 AD 00 00 00  ; P@&....1.......
79 F8 C6 00 70 6C 02 45 43 35 34 33 45 30 44 30  ; y...pl.EC543E0D0
44 30 37 36 38 45 32 41 46 41 45 42 46 35 33 32  ; D0768E2AFAEBF532
32 35 32 41 41 36 43 39 32 42 37 36 39 36 39 00  ; 252AA6C92B76969.
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ; ................
00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 67  ; ...............g
03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40  ; ...............@
64 23 00 00 00 47 61 64 75 2D 47 61 64 75 20 43  ; d#...Gadu-Gadu C
6C 69 65 6E 74 20 62 75 69 6C 64 20 31 30 2E 30  ; lient build 10.0
2E 30 2E 31 30 34 35 30 00 00 00 00 00 00 CC CC  ; .0.10450........
CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC  ; ................

Tylko co? ;/
Czemu w GG10 nie widać haszu, a w moim widać?

0

No właśnie to będzie chyba coś z tymi hashami. A nie wiecie czy ta stara metoda jest jeszcze akceptowana ?

btw. moj wysyla tak z sha1 (openssl/sha.h)

0000  00 04 75 eb 3b 98 00 0e  2e cb c8 ba 08 00 45 00   ..u.;... ......E.
0010  00 d4 05 3c 40 00 40 06  bf b9 0a 01 02 51 5b c5   ...<@.@. .....Q[.
0020  0d 18 d0 3e 1f 8a 98 2b  17 54 73 81 aa f7 50 18   ...>...+ .Ts...P.
0030  00 5c 66 c5 00 00 5d 50  00 00 70 6c 01 b6 86 40   .\f...]P ..pl...@
0040  4a 6e 34 a4 4e 04 8f e2  17 59 f9 25 04 bf 20 44   Jn4.N... .Y.%.. D
0050  8b 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
0060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
0070  00 00 00 00 00 00 00 00  00 00 00 00 00 02 00 00   ........ ........
0080  00 00 00 00 00 67 03 00  00 00 00 00 00 00 00 00   .....g.. ........
0090  00 00 00 00 00 40 64 23  00 00 00 47 61 64 75 2d   .....@d# ...Gadu-
00a0  47 61 64 75 20 43 6c 69  65 6e 74 20 62 75 69 6c   Gadu Cli ent buil
00b0  64 20 31 30 2e 30 2e 30  2e 31 30 34 35 30 00 00   d 10.0.0 .10450..
00c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00e0  00 00                                              ..               

ale i tak nie działa ;/

0

Mi się udało :D
Użyłem też sha1 z openssl i działa :D

Kodzik:

//main.cpp:
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <string>
#include "declars.h"
#include "SHA1.h"
#include <openssl\sha.h>
using namespace std;

char *gg_sha_hash(const char *password, int seed)
{
	SHA_CTX ctx;
	static char result[20];

	SHA1_Init(&ctx);
	SHA1_Update(&ctx, password, strlen(password));
	SHA1_Update(&ctx, &seed, sizeof(seed));
	SHA1_Final((unsigned char*)result, &ctx);

	return result;
}

int main()
{
	gg_welcome welcome;
	gg_login80 login;


	SOCKET      sock;
	sockaddr_in addr;
	WSAData     data;

	WSAStartup(MAKEWORD(2,2), &data);
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	addr.sin_addr.S_un.S_addr = inet_addr("91.214.237.17");
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8074);

	if(connect(sock, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
	{
		cerr << "could not connect\n";
		cin.get();
		return -1;
	}

	cout << "connected\n";

	recv(sock, (char*)&welcome, sizeof(welcome), 0);
	cout << "seed: " << welcome.seed << endl;

	sprintf(login.hash, gg_sha_hash(pass, welcome.seed));
	for(unsigned int i = sizeof(login.hash); i > strlen(login.hash); i--)
	{
		login.hash[i] = '\0';
	}

	
	login.uin = 13039737;
	sprintf(login.language, "pl");
	login.hash_type = 0x02;
	login.status = 	0x0002;
	login.flags = 0;
	login.features = 0x00000367;
	login.local_ip = 0;
	login.local_port = 0;
	login.external_ip = 0;
	login.external_port = 0;
	login.image_size = 64;
	login.unknown1 = 0x64;
	login.version_len = 0x23;
	sprintf(login.version, "Gadu-Gadu Client build 10.0.0.10450");
	login.desc_size = 0;
	login.desc[0] = '\0';
	login.type = 0x0031;
	login.size = sizeof(login) - 8;

	send(sock, (char*)&login, sizeof(login), 0);
	int buf = 0;
	recv(sock, (char*)&buf, 4, 0);
	cout << buf;

	cin.get();
	return 0;
};


//declars.h:
#pragma pack(push)
#pragma pack(1)

#define VERLEN 0x23

struct gg_welcome {
	int type, size;
	int seed;	
};

struct gg_login80 {
		int type, size;
        int uin;              /* numer Gadu-Gadu */
        char language[2];     /* język: "pl" */
        char hash_type;       /* rodzaj funkcji skrótu hasła */
        char hash[64];        /* skrót hasła dopełniony \0 */
        int status;           /* początkowy status połączenia */
        int flags;            /* początkowe flagi połączenia */
        int features;         /* opcje protokołu (0x00000367)*/
        int local_ip;         /* lokalny adres połączeń bezpośrednich (nieużywany) */
        short local_port;     /* lokalny port połączeń bezpośrednich (nieużywany) */
        int external_ip;      /* zewnętrzny adres (nieużywany) */
        short external_port;  /* zewnętrzny port (nieużywany) */
        char image_size;      /* maksymalny rozmiar grafiki w KB */
        char unknown1;        /* 0x64 */
        int version_len;      /* długość ciągu z wersją (0x23) */
        char version[36];       /* "Gadu-Gadu Client build 10.0.0.10450" (bez \0) */
		int desc_size;
		char desc[32];
};
#pragma pack(pop)

Dostaję 53 (login OK), teraz się zajmę statusem.

0

czym kompilujesz ? devcpp ? podaj gg

0

Visual Studio 2010.
Moje GG masz w kodzie, ale na razie nie jestem dostępny.

0

Walczę ze statusem, ale coś nie wychodzi. Niby się loguję, ale na innym numerze na liście cały czas jestem niedostępny.

struct gg_new_status80 {
	int type, size;
	int status;		/* nowy status */
	int flags;              /* nowe flagi */
	int description_size;   /* rozmiar opisu */
	char description[32];	/* opis (nie musi wystąpić, bez \0) */
};
        gg_new_status80 status;
 	status.type = 0x0038;
	status.size = sizeof(status) - 8;
	status.status = 0x0002;
	status.flags = 0x00000001 | 0x00000002;
	status.description_size = 0;
	status.description[0] = '\0';

Po wysłaniu tego też cały czas niedostępny.

0

A wysłałeś listę kontaktów do serwera ?

Jeśli nie mamy nikogo na liście wysyłamy następujący pakiet o zerowej długości:

#define GG_LIST_EMPTY 0x0012


Mi się też udało zalogować. Tutaj rozwiązanie na linuxa i gcc/g++

#include <iostream>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <openssl/sha.h>

using namespace std;

#define GG_PACKED __attribute__((packed))
#define GG_WELCOME 0x0001
#define GG_LOGIN 0x0031
#define GG_LOGIN_OK 0x0035
#define GG_LOGIN_FAILED 0x0043

struct gg_header {

	int type;	/* typ */
	int length;	/* dl. reszty */
	
}GG_PACKED;

struct gg_welcome {

	int seed;	/* ziarno */

}GG_PACKED;

struct gg_login {

	int uin;		/* nr */
	char language[2];	/* "pl" */
	char hash_type;		/* 0x02 - sha1; 0x01 - starszy */
	char hash[64];		/* hash; na koncu \0 */
	int status;		/* 0x0002 */
	int flags;		/* chuj wi, 0 */
	int features;		/* 0x00000367 */
	int local_ip;		/*0*/
	short local_port;	/*0*/
	int external_ip;	/*0*/
	short external_port;	/*0*/
	char image_size;	/* max rozmiar grafiki w kb */
	char unknown1;		/* 0x64 */
	int version_len;	/* dl. wersji, 0x23 */
	char version[36];	/* "Gadu-Gadu Client build 10.0.0.10450" */
	int desc_s;		/* rozmiar opisu */
	char desc[8];		/* opis */

}GG_PACKED;

char *gg_sha_hash(const char *password, int seed)
{
	SHA_CTX ctx;
	static char result[20];
	  
	SHA1_Init(&ctx);  
	SHA1_Update(&ctx, password, strlen(password));
	SHA1_Update(&ctx, &seed, sizeof(seed));
	SHA1_Final((unsigned char *)result, &ctx);

	return result;
}

void clear(struct gg_header *pHead)
{

	pHead->type = 0;
	pHead->length = 0;

}

int main(int argc, char *argv[])
{

	struct gg_header header;
	struct gg_welcome welcome;
	struct gg_login login;
	struct sockaddr_in server;
	
	int sock = 0;
	int numer = 00000; // nr

	const char *passwd = "haslo"; // haslo
	
	server.sin_family = AF_INET;
	server.sin_port = htons((u_short)8074);
	server.sin_addr.s_addr = inet_addr("91.214.237.4");
	memset(&(server.sin_zero), '\0', 8);
	
	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
	{
	
		cout<<"socket()\r\n"<<flush;
		fprintf(stderr, "%s\r\n", strerror(errno));
		return -1;
	
	}
	
	cout<<"ip: "<<server.sin_addr.s_addr<<"\r\n";
	cout<<"port: "<<server.sin_port<<"\r\n";
	cout.flush();
	
	if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
	{
	
		cout<<"connect()\r\n"<<flush;
		fprintf(stderr, "%s\r\n", strerror(errno));
		return -1;
	
	}
	
	clear(&header);
	
	cout<<"header type: "<<header.type<<"\r\n";
	cout<<"header length: "<<header.length<<"\r\n";
	cout.flush();
	
	if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
	{
	
		if(recv(sock, (char *)&welcome, header.length, 0) > 0)
		{
		
			cout<<"header type: "<<header.type<<"\r\n";
			cout<<"seed: "<<welcome.seed<<"\r\n";
			cout.flush();
		
		} else {
		
			cout<<"recv seed 2\r\n"<<flush;
			return -1;
		
		}
	
	}
	
	clear(&header);
	
	header.type = GG_LOGIN;
	header.length = sizeof(login);
	
	login.uin = numer;
	sprintf(login.language, "pl");
	login.hash_type = 0x02;
	sprintf(login.hash, gg_sha_hash(passwd, welcome.seed));
	for(unsigned int i = sizeof(login.hash); i > strlen(login.hash); i--)
        {
                login.hash[i] = '\0';
        }
        login.status = 0x0002;
        login.flags = 0;
        login.features = 0x00000367;
	login.local_ip = 0;
	login.local_port = 0;
	login.external_ip = 0;
	login.external_port = 0;
	login.image_size = 64;
	login.unknown1 = 0x64;
	login.version_len = 0x23;
	sprintf(login.version, "Gadu-Gadu Client build 10.0.0.10450");
	login.desc_s = 0;
	login.desc[0] = '\0';
	
	if(send(sock, (char *)&header, sizeof(header), 0) > 0)
	{
		
		if(send(sock, (char *)&login, sizeof(login), 0) > 0)
		{
			
			clear(&header);
			
			if(recv(sock, (char *)&header, sizeof(header), 0) > 0)
			{
			
				if(header.type == GG_LOGIN_OK)
				{
				
					cout<<"login ok\r\n"<<flush;
					//...
				
				} else if(header.type = GG_LOGIN_FAILED) {
				
					cout<<"login failed\r\n"<<flush;
					return -1;
				
				} else {
				
					cout<<"wtf?!\r\n";
					cout<<"htype: "<<header.type<<"\r\n"<<flush;
					return -1;
				
				}
			
			}
		
		}
	
	}
	
	close(sock);

	return 0;

}
0
tomekdco napisał(a)
		cout<<"socket()\r\n"<<flush;
		fprintf(stderr, "%s\r\n", strerror(errno));

Po pierwsze - nie pisz jawnie '\r\n', bo to zależne od systemu. Poza tym nowa linia i flush to endl, zaś strumień błędów to cerr, ew. clog. Czyli po ludzku:

		cout << "socket()" << endl;
		cerr << strerror(errno) << endl;

Nie lepiej?

0

Lista jest potrzebna, żeby się dowiedzieć kto jest dostępny.

Ja na razie chcę siebie zrobić dostępnym, bo teraz mimo to, że dostaję w odpowiedzi 53 to cały czas jestem niedostępny na liście.

0
Świętowit napisał(a)
tomekdco napisał(a)
		cout<<"socket()\r\n"<<flush;
		fprintf(stderr, "%s\r\n", strerror(errno));

Po pierwsze - nie pisz jawnie '\r\n', bo to zależne od systemu. Poza tym nowa linia i flush to endl, zaś strumień błędów to cerr, ew. clog. Czyli po ludzku:

		cout << "socket()" << endl;
		cerr << strerror(errno) << endl;

Nie lepiej?

Lepiej, dzięki.

hck, musisz wysłać listę, inaczej nie zadziała, google :)

0

A, no tak! :D
Dziauuuuua :)

0

Jakbyś doszedł do tego, jak ustawić opis, wrzuć kod.

0

Teraz jestem na windowsie, nie mam dostepu do kodu i kompilatorow wiec nie wiem czy zadziala ale z tego co czytam w opisie protokolu to wydaje mi sie, ze to bedzie mniej wiecej tak

#include <cstring> // dla strlen()

//..

#define GG_NEW_STATUS80 0x0038

struct gg_new_status80 {
	int status;		/* nowy status */
	int flags;              /* nowe flagi */
	int description_size;   /* rozmiar opisu */
	char description[64];	/* opis (nie musi wystąpić, bez \0) */
};

//...

struct gg_new_status80 nStatus;

//...

wysylasz naglowek GG_NEW_STATUS80

wysylasz strukture gg_new_status wypelniana w ten sposob

nStatus.status = 0x0004; // dostepny z opisem
nStatus.flags = 0x00000001;
sprintf(nStatus.description, "opis :)");
nStatus.description_size = strlen(nStatus.description);

tak mi się wydaje, jutro albo pozniej to sprawdze

0

Niestety tak nie działa.

A jednak działa. Musiałem wtedy coś namieszać.

0

Sorry za post pod postem, ale mam kolejny problem.

Po wysłaniu listy kontaktów, którą na pewno wysyłam dobrze (na numerach z listy jestem dostępny, mam dobry opis itp.) w odpowiedzi od serwera dostaję nagłówek: typ: 4, wielkość: 1.
W opisie jest napisane, że powinienem dostać pakiet ze strukturami gg_notify_reply80, a tu dostaję takie badziewie ;/
Ktoś rozwiązał taki problem?
W tym bajcie, który powinien być resztą tego pakietu nic nie ma.

0

na pewno dobrze wysylasz liste ?

pokaz jak to robisz

http://toxygen.net/libgadu/protocol/#ch1.14
0

Chodzi o http://toxygen.net/libgadu/protocol/#ch1.5
Już chyba rozwiązałem problem, miałem jakiś zaległy, nieodebrany pakiet cały czas po zalogowaniu i przy próbie odebrania tej listy go dostawałem.

Już wiem dokładnie, po zalogowaniu odbierałem tylko 4 bajty żeby sprawdzić typ pakietu i o tym zapomniałem. Teraz odbieram pełną strukturę gg_login80_ok i jest git. Głupi błąd...

1 użytkowników online, w tym zalogowanych: 0, gości: 1