core/GameDataFetcher.cpp
changeset 2367 0a45bbad3bde
parent 2247 da4a6d013772
child 2371 323fbf1ab608
     1.1 --- a/core/GameDataFetcher.cpp	Sun Oct 19 16:18:22 2008 +1300
     1.2 +++ b/core/GameDataFetcher.cpp	Sun Oct 19 17:27:54 2008 +1300
     1.3 @@ -83,7 +83,7 @@
     1.4  
     1.5  	g_SourceMod.BuildPath(Path_SM, lock_path, sizeof(lock_path), "data/temp/gamedata.lock");
     1.6  
     1.7 -	g_Logger.LogMessage("Starting experimental gamedata update fetcher... please report problems to bugs.alliedmods.net");
     1.8 +	g_Logger.LogMessage("Starting Gamedata update fetcher... please report problems to bugs.alliedmods.net");
     1.9  
    1.10  	char log_path[PLATFORM_MAX_PATH];
    1.11  	g_SourceMod.BuildPath(Path_SM, log_path, sizeof(log_path), "logs/gamedata");
    1.12 @@ -111,6 +111,31 @@
    1.13  		fclose(fp);
    1.14  	}
    1.15  
    1.16 +	char query[QUERY_MAX_LENGTH];
    1.17 +
    1.18 +	/* Check for updated gamedata files */
    1.19 +	int len = BuildGameDataQuery(query, QUERY_MAX_LENGTH);
    1.20 +
    1.21 +	if (len == 0)
    1.22 +	{
    1.23 +		g_Logger.LogToOpenFile(logfile, "Query Writing failed");
    1.24 +
    1.25 +		fclose(logfile);
    1.26 +		unlink(lock_path);
    1.27 +		return;
    1.28 +	}
    1.29 +
    1.30 +	if (g_disableGameDataUpdate)
    1.31 +	{
    1.32 +#ifdef DEBUG
    1.33 +		g_Logger.LogMessage("Skipping GameData Query due to DisableAutoUpdate being set to true");
    1.34 +#endif
    1.35 +
    1.36 +		fclose(logfile);
    1.37 +		unlink(lock_path);
    1.38 +		return;
    1.39 +	}
    1.40 +
    1.41  	/* Create a new socket for this connection */
    1.42  	int socketDescriptor = ConnectSocket();
    1.43  
    1.44 @@ -121,38 +146,15 @@
    1.45  		return;
    1.46  	}
    1.47  
    1.48 -	char query[QUERY_MAX_LENGTH];
    1.49 -
    1.50 -	/* Check for updated gamedata files */
    1.51 -	int len = BuildGameDataQuery(query, QUERY_MAX_LENGTH);
    1.52 -
    1.53 -	if (len == 0)
    1.54 -	{
    1.55 -		g_Logger.LogToOpenFile(logfile, "Query Writing failed");
    1.56 +	int sent = SendData(socketDescriptor, query, len);
    1.57  
    1.58 -		closesocket(socketDescriptor);
    1.59 -		fclose(logfile);
    1.60 -		unlink(lock_path);
    1.61 -		return;
    1.62 -	}
    1.63 -
    1.64 -	if (g_disableGameDataUpdate)
    1.65 -	{
    1.66 -		g_Logger.LogMessage("Skipping GameData Query due to DisableAutoUpdate being set to true");
    1.67 -
    1.68 -		closesocket(socketDescriptor);
    1.69 -		fclose(logfile);
    1.70 -		unlink(lock_path);
    1.71 -		return;
    1.72 -	}
    1.73 -
    1.74 -	int sent = NonBlockingSend(socketDescriptor, query, len);
    1.75 -
    1.76 +#ifdef DEBUG
    1.77  	g_Logger.LogToOpenFile(logfile, "Sent Query!");
    1.78 +#endif
    1.79  
    1.80  	if (sent == 0)
    1.81  	{
    1.82 -		g_Logger.LogToOpenFile(logfile, "Failed to send data");
    1.83 +		g_Logger.LogToOpenFile(logfile, "Failed to send gamedata query data to remote host");
    1.84  
    1.85  		closesocket(socketDescriptor);
    1.86  		fclose(logfile);
    1.87 @@ -227,12 +229,16 @@
    1.88  					}
    1.89  					else
    1.90  					{
    1.91 +#ifdef DEBUG
    1.92  						g_Logger.LogToOpenFile(logfile, "%s no md5?", file);
    1.93 +#endif
    1.94  					}
    1.95  				}
    1.96  				else
    1.97  				{
    1.98 +#ifdef DEBUG
    1.99  					g_Logger.LogToOpenFile(logfile, "%s failed!", file);
   1.100 +#endif
   1.101  				}
   1.102  			}
   1.103  		}
   1.104 @@ -264,7 +270,11 @@
   1.105  	if (socketDescriptor == INVALID_SOCKET)
   1.106  	{
   1.107  		//bugger aye?
   1.108 -		g_Logger.LogToOpenFile(logfile, "Failed to create a new socket");
   1.109 +#ifdef WIN32
   1.110 +		g_Logger.LogToOpenFile(logfile, "Failed to create a new socket - Error %i", WSAGetLastError());
   1.111 +#else
   1.112 +		g_Logger.LogToOpenFile(logfile, "Failed to create a new socket - Error %i", errno);
   1.113 +#endif
   1.114  		closesocket(socketDescriptor);
   1.115  		return INVALID_SOCKET;
   1.116  	}
   1.117 @@ -281,7 +291,7 @@
   1.118  	{
   1.119  		if ((local_addr.sin_addr.s_addr = inet_addr(g_serverAddress)) == INADDR_NONE)
   1.120  		{
   1.121 -			g_Logger.LogToOpenFile(logfile, "Couldnt locate address");
   1.122 +			g_Logger.LogToOpenFile(logfile, "Couldn't locate address");
   1.123  			closesocket(socketDescriptor);
   1.124  			return INVALID_SOCKET;
   1.125  		}
   1.126 @@ -293,7 +303,11 @@
   1.127  
   1.128  	if (connect(socketDescriptor, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0)
   1.129  	{
   1.130 -		g_Logger.LogToOpenFile(logfile, "Couldn't connect");
   1.131 +#ifdef WIN32
   1.132 +		g_Logger.LogToOpenFile(logfile, "Couldn't connect - Error %i", WSAGetLastError());
   1.133 +#else
   1.134 +		g_Logger.LogToOpenFile(logfile, "Couldn't connect - Error %i", errno);
   1.135 +#endif
   1.136  		closesocket(socketDescriptor);
   1.137  		return INVALID_SOCKET;
   1.138  	}
   1.139 @@ -304,28 +318,35 @@
   1.140  void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
   1.141  {
   1.142  	char buffer[50];
   1.143 -
   1.144 +#ifdef DEBUG
   1.145  	g_Logger.LogToOpenFile(logfile, "Waiting for reply!");
   1.146 +#endif
   1.147  
   1.148  	//Read in the header bytes
   1.149 -	int returnLen = NonBlockingRecv(socketDescriptor, buffer, 12);
   1.150 +	int returnLen = RecvData(socketDescriptor, buffer, 12);
   1.151  
   1.152 +#ifdef DEBUG
   1.153  	g_Logger.LogToOpenFile(logfile, "Recv Completed");
   1.154 +#endif
   1.155  
   1.156  	if (returnLen == 0)
   1.157  	{
   1.158 +#ifdef DEBUG
   1.159  		g_Logger.LogToOpenFile(logfile, ",but it failed.");
   1.160 +#endif
   1.161  		/* Timeout or fail? */
   1.162  		return;
   1.163  	}
   1.164  
   1.165 +#ifdef DEBUG
   1.166  	g_Logger.LogToOpenFile(logfile, "Received Header!");
   1.167 +#endif
   1.168  
   1.169  	bf_read Reader = bf_read("GameDataQuery", buffer, 12);
   1.170  
   1.171  	if (Reader.ReadByte() != 'A' || Reader.ReadByte() != 'G')
   1.172  	{
   1.173 -		g_Logger.LogToOpenFile(logfile, "Invalid Query to handle");
   1.174 +		g_Logger.LogToOpenFile(logfile, "Unknown Query Response");
   1.175  		return;
   1.176  	}
   1.177  
   1.178 @@ -338,18 +359,22 @@
   1.179  	build[2] = Reader.ReadShort();
   1.180  	build[3] = Reader.ReadShort();
   1.181  
   1.182 +#ifdef DEBUG
   1.183  	g_Logger.LogToOpenFile(logfile, "Update Status: %i - Latest %i.%i.%i.%i", updateStatus, build[0], build[1], build[2], build[3]);
   1.184 +#endif
   1.185  
   1.186  	HandleUpdateStatus(updateStatus, build);
   1.187  
   1.188  	int changedFiles = Reader.ReadByte();
   1.189  
   1.190 +#ifdef DEBUG
   1.191  	g_Logger.LogToOpenFile(logfile, "Files to download: %i", changedFiles);
   1.192 +#endif
   1.193  
   1.194  	for (int i=0; i<changedFiles; i++)
   1.195  	{
   1.196  		//Read in the file index and byte count
   1.197 -		returnLen = NonBlockingRecv(socketDescriptor, buffer, 5);
   1.198 +		returnLen = RecvData(socketDescriptor, buffer, 5);
   1.199  
   1.200  		if (returnLen == 0)
   1.201  		{
   1.202 @@ -362,15 +387,19 @@
   1.203  		int index = Reader.ReadByte();
   1.204  		int tempLen = Reader.ReadUBitLong(32);
   1.205  
   1.206 +#ifdef DEBUG
   1.207  		g_Logger.LogToOpenFile(logfile, "File index %i and length %i", index, tempLen);
   1.208 +#endif
   1.209  
   1.210  		void *memPtr;
   1.211  		memtable->CreateMem(tempLen+1, &memPtr);
   1.212  
   1.213  		//Read the contents of our file into the memtable
   1.214 -		returnLen = NonBlockingRecv(socketDescriptor, (char *)memPtr, tempLen);
   1.215 +		returnLen = RecvData(socketDescriptor, (char *)memPtr, tempLen);
   1.216  
   1.217 +#ifdef DEBUG
   1.218  		g_Logger.LogToOpenFile(logfile, "Recieved %i bytes", returnLen);
   1.219 +#endif
   1.220  
   1.221  		if (returnLen == 0)
   1.222  		{
   1.223 @@ -393,6 +422,10 @@
   1.224  				fprintf(fp, (const char *)memPtr);
   1.225  				fclose(fp);
   1.226  			}
   1.227 +			else
   1.228 +			{
   1.229 +				g_Logger.LogToOpenFile(logfile, "Failed to open file \"%s\"", filename);
   1.230 +			}
   1.231  		}
   1.232  		else
   1.233  		{
   1.234 @@ -401,10 +434,14 @@
   1.235  
   1.236  		memtable->Reset();
   1.237  
   1.238 +#ifdef DEBUG
   1.239  		g_Logger.LogToOpenFile(logfile, "Updated File %s", filename);
   1.240 +#endif
   1.241  	}
   1.242  
   1.243 +#ifdef DEBUG
   1.244  	g_Logger.LogToOpenFile(logfile, "File Downloads Completed!");
   1.245 +#endif
   1.246  
   1.247  	bool needsRestart = false;
   1.248  
   1.249 @@ -415,7 +452,7 @@
   1.250  	}
   1.251  
   1.252  	//Read changed file count
   1.253 -	returnLen = NonBlockingRecv(socketDescriptor, buffer, 1);
   1.254 +	returnLen = RecvData(socketDescriptor, buffer, 1);
   1.255  
   1.256  	if (returnLen == 0)
   1.257  	{
   1.258 @@ -430,20 +467,26 @@
   1.259  
   1.260  	if (changedFiles == 0)
   1.261  	{
   1.262 +#ifdef DEBUG
   1.263  		g_Logger.LogToOpenFile(logfile, "No unknown files. We're all done");
   1.264 +#endif
   1.265  		return;
   1.266  	}
   1.267  
   1.268  	char *changedFileIndexes = new char[changedFiles];
   1.269 -	
   1.270 +
   1.271 +#ifdef DEBUG
   1.272  	g_Logger.LogToOpenFile(logfile, "%i Files were unknown", changedFiles);
   1.273 -	
   1.274 -	returnLen = NonBlockingRecv(socketDescriptor, changedFileIndexes, changedFiles);
   1.275 +#endif
   1.276 +
   1.277 +	returnLen = RecvData(socketDescriptor, changedFileIndexes, changedFiles);
   1.278  
   1.279  	if (returnLen == 0)
   1.280  	{
   1.281  		/* Timeout or fail? */
   1.282 +#ifdef DEBUG
   1.283  		g_Logger.LogToOpenFile(logfile, "Failed to receive unknown list");
   1.284 +#endif
   1.285  		return;
   1.286  	}
   1.287  
   1.288 @@ -466,8 +509,9 @@
   1.289  		}
   1.290  
   1.291  		g_LibSys.GetFileFromPath(fileName, sizeof(fileName), pathname);
   1.292 -
   1.293 +#ifdef DEBUG
   1.294  		g_Logger.LogToOpenFile(logfile, "Unknown File %i : %s", index, fileName);
   1.295 +#endif
   1.296  	}
   1.297  
   1.298  	delete [] changedFileIndexes;
   1.299 @@ -479,7 +523,7 @@
   1.300  	}
   1.301  }
   1.302  
   1.303 -int FetcherThread::NonBlockingRecv( int socketDescriptor, char *buffer, int len )
   1.304 +int FetcherThread::RecvData( int socketDescriptor, char *buffer, int len )
   1.305  {
   1.306  	fd_set fds;
   1.307  	struct timeval tv;
   1.308 @@ -488,35 +532,37 @@
   1.309  	tv.tv_sec = 10;
   1.310  	tv.tv_usec = 0;
   1.311  
   1.312 -	/* Add our socket to a socket set */
   1.313 -	FD_ZERO(&fds);
   1.314 -	FD_SET(socketDescriptor, &fds);
   1.315 +	int bytesReceivedTotal = 0;
   1.316  
   1.317 -	/* Wait max of 10 seconds for recv to become available */
   1.318 -	select(socketDescriptor+1, &fds, NULL, NULL, &tv);
   1.319 +	while (bytesReceivedTotal < len)
   1.320 +	{
   1.321 +		/* Add our socket to a socket set */
   1.322 +		FD_ZERO(&fds);
   1.323 +		FD_SET(socketDescriptor, &fds);
   1.324 +
   1.325 +		/* Wait max of 10 seconds for recv to become available */
   1.326 +		select(socketDescriptor+1, &fds, NULL, NULL, &tv);
   1.327 +
   1.328 +		int bytesReceived = 0;
   1.329  
   1.330 -	int bytesReceived = 0;
   1.331 +		/* Is there a limit on how much we can receive? Some site said 1024 bytes, which will be well short of a file */
   1.332 +		if (FD_ISSET(socketDescriptor, &fds))
   1.333 +		{
   1.334 +			bytesReceived = recv(socketDescriptor, buffer, len, 0);
   1.335 +		}
   1.336  
   1.337 -	/* Is there a limit on how much we can receive? Some site said 1024 bytes, which will be well short of a file */
   1.338 -	if (FD_ISSET(socketDescriptor, &fds))
   1.339 -	{
   1.340 -		bytesReceived = recv(socketDescriptor, buffer, len, 0);
   1.341 +		if (bytesReceived == 0 || bytesReceived == -1)
   1.342 +		{
   1.343 +			return 0;
   1.344 +		}
   1.345 +
   1.346 +		bytesReceivedTotal += bytesReceived;
   1.347  	}
   1.348  
   1.349 -	if (bytesReceived == 0 || bytesReceived == -1)
   1.350 -	{
   1.351 -		return 0;
   1.352 -	}
   1.353 -
   1.354 -	if (bytesReceived < len)
   1.355 -	{
   1.356 -		return bytesReceived + NonBlockingRecv(socketDescriptor, buffer+bytesReceived, len-bytesReceived);
   1.357 -	}
   1.358 -
   1.359 -	return bytesReceived;	
   1.360 +	return bytesReceivedTotal;	
   1.361  }
   1.362  
   1.363 -int FetcherThread::NonBlockingSend( int socketDescriptor, char *buffer, int len )
   1.364 +int FetcherThread::SendData( int socketDescriptor, char *buffer, int len )
   1.365  {
   1.366  	fd_set fds;
   1.367  	struct timeval tv;
   1.368 @@ -524,29 +570,31 @@
   1.369  	tv.tv_sec = 10;
   1.370  	tv.tv_usec = 0;
   1.371  
   1.372 -	FD_ZERO(&fds);
   1.373 -	FD_SET(socketDescriptor, &fds);
   1.374 +	int sentBytesTotal = 0;
   1.375  
   1.376 -	select(socketDescriptor+1, NULL, &fds, NULL, &tv);
   1.377 +	while (sentBytesTotal < len)
   1.378 +	{
   1.379 +		FD_ZERO(&fds);
   1.380 +		FD_SET(socketDescriptor, &fds);
   1.381 +
   1.382 +		select(socketDescriptor+1, NULL, &fds, NULL, &tv);
   1.383 +
   1.384 +		int sentBytes = 0;
   1.385  
   1.386 -	int sentBytes = 0;
   1.387 +		if (FD_ISSET(socketDescriptor, &fds))
   1.388 +		{
   1.389 +			sentBytes = send(socketDescriptor, buffer, len, 0);
   1.390 +		}
   1.391  
   1.392 -	if (FD_ISSET(socketDescriptor, &fds))
   1.393 -	{
   1.394 -		sentBytes = send(socketDescriptor, buffer, len, 0);
   1.395 +		if (sentBytes == 0 || sentBytes == -1)
   1.396 +		{
   1.397 +			return 0;
   1.398 +		}		
   1.399 +
   1.400 +		sentBytesTotal += sentBytes;
   1.401  	}
   1.402  
   1.403 -	if (sentBytes == 0 || sentBytes == -1)
   1.404 -	{
   1.405 -		return 0;
   1.406 -	}
   1.407 -
   1.408 -	if (sentBytes < len)
   1.409 -	{
   1.410 -		return sentBytes + NonBlockingSend(socketDescriptor, buffer+sentBytes, len-sentBytes);
   1.411 -	}
   1.412 -
   1.413 -	return sentBytes;
   1.414 +	return sentBytesTotal;
   1.415  }
   1.416  
   1.417  void FetcherThread::HandleUpdateStatus( UpdateStatus status, short version[4] )
   1.418 @@ -561,7 +609,7 @@
   1.419  
   1.420  		case Update_NewBuild:
   1.421  		{
   1.422 -			g_Logger.LogMessage("SourceMod Update: A new SVN build is available from sourcemod.net");
   1.423 +			g_Logger.LogMessage("SourceMod Update: A new Mercurial build is available from sourcemod.net");
   1.424  			g_Logger.LogMessage("Current Version: %i.%i.%i.%i Available: %i.%i.%i.%i", version[0], version[1], version[2], version[3], version[0], version[1], version[2], version[3]);
   1.425  			break;
   1.426  		}