int main( int argc, char **argv )
{
	spInitNet();
	printf("Init spNet\n");

	//C4A Example
	spNetC4AScorePointer score;
	spNetC4AProfilePointer profile = spNetC4AGetProfile();
	if (profile)
	{
		printf("Your profile:\n");
		printf("Long Name: %s\n",profile->longname);
		printf("Short Name: %s\n",profile->shortname);
		printf("E-Mail: %s\n",profile->email);
		printf("Password: %s\n",profile->password);
	}
	else
		printf("No profile found. Put it to this folder or create it with compo4all!\n");
	
	//spNetC4AGetScoreOfMonth(&score,profile,"puzzletube_points",2013,6);
	printf("Getting Scores serial:\n");
	int i;
	int result = 0;
	for (i = 0; i < 2; i++)
	{
		switch (i)
		{
			case 0:
				result = spNetC4AGetScore(&score,profile,"snowman_hard",10000);
				printf("Highscore of Snowman Hard (with profile if available):\n");
				break;
			case 1:
				result = spNetC4AGetScore(&score,NULL,"snowman_easy",10000);
				printf("Highscore of Snowman Easy (wihtout profile):\n");
				break;
		}
		if (result == 0)
			while (spNetC4AGetStatus() == SP_C4A_PROGRESS)
			#ifdef WIN32
				Sleep(1);
			#else
				usleep(200);
			#endif
		if (result == 0 && spNetC4AGetStatus() == SP_C4A_OK)
		{
			spNetC4AScorePointer mom = score;
			while (mom)
			{
				struct tm * local = localtime (&(mom->commitTime));
				printf("  %2i: %2i.%2i.%i - %2i:%02i: %s (%s) - %i\n",mom->rank,local->tm_mday,local->tm_mon+1,local->tm_year+1900,local->tm_hour,local->tm_min,mom->longname,mom->shortname,mom->score);
				mom = mom->next;
			}
			printf("  Same with every player just once:\n");
			spNetC4AMakeScoresUnique(&score);
			mom = score;
			while (mom)
			{
				struct tm * local = localtime (&(mom->commitTime));
				printf("  %2i: %2i.%2i.%i - %2i:%02i: %s (%s) - %i\n",mom->rank,local->tm_mday,local->tm_mon+1,local->tm_year+1900,local->tm_hour,local->tm_min,mom->longname,mom->shortname,mom->score);
				mom = mom->next;
			}
			spNetC4ADeleteScores(&score);
		}
		else
		if (result == 1)
			printf("Fetshing Highscore failed with error code: %i\n",result);
		else
			printf("Fetshing Highscore failed with status code: %i\n",spNetC4AGetStatus());
	}




	printf("Getting Scores parallel:\n");
	spNetC4AScorePointer score1;
	spNetC4AScorePointer score2;
	spNetC4AScorePointer score3;
	spNetC4ATaskPointer p1 = spNetC4AGetScoreParallel(&score1,profile,"puzzletube_points",10000);
	spNetC4ATaskPointer p2 = spNetC4AGetScoreParallel(&score2,NULL,"puzzletube_race",10000);
	spNetC4ATaskPointer p3 = spNetC4AGetScoreParallel(&score3,NULL,"puzzletube_survival",10000);
	if (p1 && p2 && p3)
	while (spNetC4AGetStatusParallel(p1) == SP_C4A_PROGRESS ||
			spNetC4AGetStatusParallel(p2) == SP_C4A_PROGRESS ||
			spNetC4AGetStatusParallel(p3) == SP_C4A_PROGRESS)
	#ifdef WIN32
		Sleep(1);
	#else
		usleep(200);
	#endif
	for (i = 0; i < 3; i++)
	{
		spNetC4ATaskPointer p;
		switch (i)
		{
			case 0:
				printf("Highscore of Puzzletube Points (with profile if available):\n");
				p = p1;
				score = score1;
				break;
			case 1:
				printf("Highscore of Puzzletube Race (wihtout profile):\n");
				p = p2;
				score = score2;
				break;
			case 2:
				printf("Highscore of Puzzletube Survival (without profile):\n");
				p = p3;
				score = score3;
				break;
		}
		if (p && spNetC4AGetStatusParallel(p) == SP_C4A_OK)
		{
			spNetC4AScorePointer mom = score;
			while (mom)
			{
				struct tm * local = localtime (&(mom->commitTime));
				printf("  %2i: %2i.%2i.%i - %2i:%02i: %s (%s) - %i\n",mom->rank,local->tm_mday,local->tm_mon+1,local->tm_year+1900,local->tm_hour,local->tm_min,mom->longname,mom->shortname,mom->score);
				mom = mom->next;
			}
			spNetC4ADeleteScores(&score);
		}
		else
		if (p == NULL)
			printf("Fetshing Highscore failed with error code: 0\n");
		else
			printf("Fetshing Highscore failed with status code: %i\n",spNetC4AGetStatusParallel(p));
		spNetC4ADeleteTask(p);
	}
	//Client setup
	spNetIP ip;
	if (argc < 2)
	{
		ip = spNetResolve("localhost",12345);
		printf("Connection to localhost\nUse ./testnet.sh SERVER to specify another server to connect to!\n");
	}
	else
	{
		printf("Connecting to %s\n",argv[1]);
		ip = spNetResolve(argv[1],12345);
	}
	client_connection = spNetOpenClientTCP(ip);
	if (client_connection == NULL)
		printf("No client_connection! I will crash!\n");
	
	do_stuff();
	
	spNetCloseTCP(client_connection);
	
	//After the loop because spNetC4AGetScore works in the background. ;)

	spQuitNet();
	return 0;
}
Beispiel #2
0
pMessage sendMessage(pMessage message,char* binary_name,void* binary,int count,char* dest,char* server)
{
	char boundary[17] = "A9B8C7D6E5F4G3H2"; //This should maybe random...
	int boundary_len = 16;
	int direction = 1;
	if (count < 0)
	{
		count *= -1;
		direction = -1;
	}
	int length = 0;
	pMessage mom = message;
	while (mom)
	{
		mom->l =
			2+boundary_len+2 + //boundary start + return
			39+strlen(mom->name)+2 + //Content-Disposition: form-data; name="<name>" + return
			strlen(mom->content)+4; // content + 2 returns
		length += mom->l;
		mom = mom->next;
	}
	length += boundary_len+2+4; //--boundary-- + 2 returns;
	spNetTCPConnection server_connection = spNetOpenClientTCP(ip);
	if (server_connection == NULL)
		return NULL;
	//int buffer_size = 2048+count;//spMax(length+1,512);
	int buffer_size = 65536;
	char in_buffer[buffer_size];
	char* buffer = in_buffer;
	#ifndef WIN32
		char out_buffer[buffer_size];
	#endif
	char header[4096]; //magic number ftw!
	char host[512];
	int pos = 0;
	mom = message;
	char temp[512];
	while (mom)
	{
		sprintf(temp,
			"\r\n--%s\r\n"
			"Content-Disposition: form-data; name=\"%s\"\r\n"
			"\r\n"
			"%s",boundary,mom->name,mom->content);
		memcpy(&(buffer[pos]),temp,mom->l);
		pos += mom->l;
		mom = mom->next;
	}
	if (binary && direction == 1)
	{
		#ifdef INPUT_COMPRESSION
		if (hase_gzip)
		{
			//compress data
			z_stream strm;
			strm.zalloc = Z_NULL;
			strm.zfree = Z_NULL;
			strm.opaque = Z_NULL;
			strm.avail_in = count;
			strm.next_in = binary;
			if (deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31,8,Z_DEFAULT_STRATEGY) != Z_OK)
			{
				printf("Error: ZStream Init error\n");
				return NULL;
			}
			strm.avail_out = buffer_size;
			strm.next_out = out_buffer;
			switch (deflate(&strm, Z_FINISH))
			{
				case Z_STREAM_ERROR:
					printf("Error: ZStream error\n");
					deflateEnd(&strm);
					return NULL;
				case Z_DATA_ERROR:
					printf("Error: ZStream data error\n");
					return NULL;
				case Z_MEM_ERROR:
					deflateEnd(&strm);
					printf("Error: ZStream mem error\n");
					return NULL;
				case Z_NEED_DICT:
					printf("Error: ZStream need dict error\n");
					return NULL;
			}
			//printf("Compression saved %i%% (%i vs. %i)\n",100-(int)strm.total_out*100/count,(int)strm.total_out,count);
			count = (int)strm.total_out;
			deflateEnd(&strm);
			binary = out_buffer;
		}
		#endif
		length +=
			2+boundary_len+2 + //boundary start + return
			39+strlen(binary_name)+2 + //Content-Disposition: form-data; name="<name>" + return
			count + 4; // content + 2 returns
		int l =
			2+boundary_len+2 + //boundary start + return
			39+strlen(binary_name)+2 + //Content-Disposition: form-data; name="<name>" + return
			4; // content + 2 returns
		sprintf(temp,
			"\r\n--%s\r\n"
			"Content-Disposition: form-data; name=\"%s\"\r\n"
			"\r\n",boundary,binary_name);
		memcpy(&(buffer[pos]),temp,l);
		pos += l;
		memcpy(&(buffer[pos]),binary,count);
		pos += count;
	}
	sprintf(temp,
		"\r\n--%s--",boundary);
	memcpy(&(buffer[pos]),temp,2+4+boundary_len+1);

	sprintf(host,"%s",server);
	char* server_directory = strchr(host,'/');
	if (server_directory)
	{
		server_directory[0] = 0;
		server_directory++;
		sprintf(header,
			"POST /%s/%s HTTP/1.1\r\n"
			"Origin: http://%s\r\n"
			"User-Agent: Hase\r\n"
			"Connection: Close\r\n"
			"Content-Type: multipart/form-data; boundary=%s\r\n"
			"Content-Length: %i\r\n"
			#ifndef WIN32
			"Accept-Encoding: gzip\r\n"
			#endif
			"Host: %s\r\n"
			"\r\n",server_directory,dest,host,boundary,length,host);
	}
	else
	{
		sprintf(header,
			"POST /%s HTTP/1.1\r\n"
			"Origin: http://%s\r\n"
			"User-Agent: Hase\r\n"
			"Connection: Close\r\n"
			"Content-Type: multipart/form-data; boundary=%s\r\n"
			"Content-Length: %i\r\n"
			#ifndef WIN32
			"Accept-Encoding: gzip\r\n"
			#endif
			"Host: %s\r\n"
			"\r\n",dest,host,boundary,length,host);
	}
	//printf("Header:\n%s",header);
	spNetSendHTTP(server_connection,header);
	//printf("\nMessage\n%sEND\n",buffer);
	spNetSendTCP(server_connection,buffer,length);
	int res = spNetReceiveHTTP(server_connection,buffer,buffer_size-1);
	buffer[res] = 0;
	spNetCloseTCP(server_connection);
	//HTTP error check + jumping to begin
	if (
		buffer[ 0] != 'H' ||
		buffer[ 1] != 'T' ||
		buffer[ 2] != 'T' ||
		buffer[ 3] != 'P' ||
		buffer[ 4] != '/' ||
		buffer[ 5] != '1' ||
		buffer[ 6] != '.' ||
		buffer[ 7] != '1' ||
		buffer[ 8] != ' ' ||
		buffer[ 9] != '2' ||
		buffer[10] != '0' ||
		buffer[11] != '0' ||
		buffer[12] != ' ' ||
		buffer[13] != 'O' ||
		buffer[14] != 'K')
		return NULL;
	pos = 15;
	#ifndef WIN32
		int encoded = 0;
	#endif
	int content_length = 0;
	int chunked = 0;
	while (
		buffer[pos  ] != '\r' ||
		buffer[pos+1] != '\n' ||
		buffer[pos+2] != '\r' ||
		buffer[pos+3] != '\n')
	{
		if (buffer[pos] == 0)
			return NULL;
		#ifndef WIN32
		if (
			buffer[pos+ 0] == 'C' &&
			buffer[pos+ 1] == 'o' &&
			buffer[pos+ 2] == 'n' &&
			buffer[pos+ 3] == 't' &&
			buffer[pos+ 4] == 'e' &&
			buffer[pos+ 5] == 'n' &&
			buffer[pos+ 6] == 't' &&
			buffer[pos+ 7] == '-')
		{
			if (
				buffer[pos+ 8] == 'E' &&
				buffer[pos+ 9] == 'n' &&
				buffer[pos+10] == 'c' &&
				buffer[pos+11] == 'o' &&
				buffer[pos+12] == 'd' &&
				buffer[pos+13] == 'i' &&
				buffer[pos+14] == 'n' &&
				buffer[pos+15] == 'g' &&
				buffer[pos+16] == ':' &&
				buffer[pos+17] == ' ' &&
				buffer[pos+18] == 'g' &&
				buffer[pos+19] == 'z' &&
				buffer[pos+20] == 'i' &&
				buffer[pos+21] == 'p')
					encoded = 1;
			else
			if (
				buffer[pos+ 8] == 'L' &&
				buffer[pos+ 9] == 'e' &&
				buffer[pos+10] == 'n' &&
				buffer[pos+11] == 'g' &&
				buffer[pos+12] == 't' &&
				buffer[pos+13] == 'h' &&
				buffer[pos+14] == ':' &&
				buffer[pos+15] == ' ')
					content_length = atoi(&buffer[pos+16]);
		}
		#endif
		if (
			buffer[pos+ 0] == 'T' &&
			buffer[pos+ 1] == 'r' &&
			buffer[pos+ 2] == 'a' &&
			buffer[pos+ 3] == 'n' &&
			buffer[pos+ 4] == 's' &&
			buffer[pos+ 5] == 'f' &&
			buffer[pos+ 6] == 'e' &&
			buffer[pos+ 7] == 'r' &&
			buffer[pos+ 8] == '-' &&
			buffer[pos+ 9] == 'E' &&
			buffer[pos+10] == 'n' &&
			buffer[pos+11] == 'c' &&
			buffer[pos+12] == 'o' &&
			buffer[pos+13] == 'd' &&
			buffer[pos+14] == 'i' &&
			buffer[pos+15] == 'n' &&
			buffer[pos+16] == 'g' &&
			buffer[pos+17] == ':' &&
			buffer[pos+18] == ' ' &&
			buffer[pos+19] == 'c' &&
			buffer[pos+20] == 'h' &&
			buffer[pos+21] == 'u' &&
			buffer[pos+22] == 'n' &&
			buffer[pos+23] == 'k' &&
			buffer[pos+24] == 'e' &&
			buffer[pos+25] == 'd')
			chunked = 1;
		pos++;
	}
	pos+=4;
	if (chunked) //Remove chunk informations
	{
		int difference = 0;
		while (
			buffer[pos + difference + 0] != '\r' ||
			buffer[pos + difference + 1] != '\n')
			difference++;
		int next_chunk = strtol(&(buffer[pos]),NULL,16);
		difference += 2; // \r\n
		int work_pos = pos;
		while (next_chunk)
		{
			int i;
			for (i = work_pos; i < work_pos + next_chunk; i++)
				buffer[i] = buffer[i+difference];
			difference += 2; // \r\n
			work_pos += next_chunk;
			next_chunk = strtol(&(buffer[work_pos+difference]),NULL,16);
			while (
				buffer[work_pos + difference + 0] != '\r' ||
				buffer[work_pos + difference + 1] != '\n')
				difference++;
			difference += 2; // \r\n
		}
		buffer[work_pos] = 0;
		content_length -= difference;
	}
	#ifndef WIN32
	if (encoded)
	{
		z_stream strm;
		strm.zalloc = Z_NULL;
		strm.zfree = Z_NULL;
		strm.opaque = Z_NULL;
		strm.avail_in = content_length;
		strm.next_in = &in_buffer[pos];
		if (inflateInit2 (&strm, 31) != Z_OK)
		{
			printf("Error: ZStream Init error\n");
			return NULL;
		}
		strm.avail_out = buffer_size-pos;
		strm.next_out = &out_buffer[pos];
		switch (inflate(&strm, Z_NO_FLUSH))
		{
			case Z_STREAM_ERROR:
				printf("Error: ZStream error\n");
				inflateEnd(&strm);
				return NULL;
            case Z_DATA_ERROR:
				printf("Error: ZStream data error\n");
				return NULL;
            case Z_MEM_ERROR:
				inflateEnd(&strm);
				printf("Error: ZStream mem error\n");
				return NULL;
            case Z_NEED_DICT:
				printf("Error: ZStream need dict error\n");
				return NULL;

		}
		//printf("Compression saved %i%% (%i vs. %i)\n",100-content_length*100/(int)strm.total_out,content_length,(int)strm.total_out);
		inflateEnd(&strm);
		out_buffer[pos+(int)strm.total_out] = 0;
		buffer = out_buffer;
	}
	else
	#endif
		buffer = in_buffer;
	//printf("%s\n",&buffer[pos]);

	if (direction == -1) //incoming file
	{
		if (buffer[pos+1] == 'A' &&
			buffer[pos+2] == 'C' &&
			buffer[pos+3] == 'K')
		{
			memcpy(binary,&buffer[pos+4],count);
			last_heartbeat_diff = *((int*)(&buffer[pos+4+count]));
			pMessage result = NULL;
			numToMessage(&result,"Okay",1);
			return result;
		}
		if (buffer[pos+1] == 'N' &&
			buffer[pos+2] == 'U' &&
			buffer[pos+3] == 'L')
		{
			memset(binary,1+2+16+32,count);
			last_heartbeat_diff = (int)(buffer[pos+4]);
			pMessage result = NULL;
			numToMessage(&result,"Kicked",1);
			return result;
		}
		if (buffer[pos+1] == 'E' &&
			buffer[pos+2] == 'R' &&
			buffer[pos+3] == 'R')
		{
			last_heartbeat_diff = (int)(buffer[pos+4]);
			return NULL;
		}
		return NULL;
	}
	//Parsing in init style
	pMessage result = NULL;
	char* found;
	char* rest = &buffer[pos];
	//printf("_____\n%s\n^^^^^\n",rest);
	while ((found = strchr(rest,'\n')) || (found = strchr(rest,0)))
	{
		char exit_afterwards = 0;
		if (found[0] == 0)
			exit_afterwards = 1;
		found[0] = 0;
		char* line = rest;
		char* middle = strchr(line,':');
		if (middle && line[0] != '<') //some free hosting website add statistic bullshit
		{
			middle[0] = 0;
			middle++;
			middle++;
			addToMessage(&result,line,middle);
			//printf("Add %s -> %s\n",line,middle);
		}
		if (exit_afterwards)
			break;
		rest = ++found;
	}
	return result;
}