示例#1
0
GPResult
gpiDeleteBuddy(
  GPConnection * connection,
  GPProfile profile,
  GPIBool sendServerRequest
)
{
	GPIProfile * pProfile;
	GPIConnection * iconnection = (GPIConnection*)*connection;
	int index;

	// Get the profile object.
	//////////////////////////
	if(!gpiGetProfile(connection, profile, &pProfile))
		Error(connection, GP_PARAMETER_ERROR, "Invalid profile.");

	// Check that this is a buddy.
	//////////////////////////////
	// Removed - 092404 BED - User could be a buddy even though we don't have the status
	//if(!pProfile->buddyStatus)
	//	Error(connection, GP_PARAMETER_ERROR, "Profile not a buddy.");

	// Send the request.
	////////////////////
	if (GPITrue == sendServerRequest)
	{
		gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\delbuddy\\");
		gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\sesskey\\");
		gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey);
		gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\delprofileid\\");
		gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, pProfile->profileId);
		gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\");
	}

	// Need to fix up the buddy indexes.
	////////////////////////////////////
	if (pProfile->buddyStatus)
	{
		index = pProfile->buddyStatus->buddyIndex;
		assert(index >= 0);
		freeclear(pProfile->buddyStatus->statusString);
		freeclear(pProfile->buddyStatus->locationString);
		freeclear(pProfile->buddyStatus);
		if(gpiCanFreeProfile(pProfile))
			gpiRemoveProfile(connection, pProfile);
		iconnection->profileList.numBuddies--;
		assert(iconnection->profileList.numBuddies >= 0);
#ifndef _PS2
		gpiProfileMap(connection, gpiFixBuddyIndices, (void *)(unsigned long)index);
#else
		gpiProfileMap(connection, gpiFixBuddyIndices, (void *)index);
#endif
	}
	if (pProfile->buddyStatusInfo)
	{
		index = pProfile->buddyStatusInfo->buddyIndex;
		assert(index >= 0);
		freeclear(pProfile->buddyStatusInfo->richStatus);
		freeclear(pProfile->buddyStatusInfo->gameType);
		freeclear(pProfile->buddyStatusInfo->gameVariant);
		freeclear(pProfile->buddyStatusInfo->gameMapName);
		freeclear(pProfile->buddyStatusInfo);
		if (pProfile->buddyStatusInfo->extendedInfoKeys)
		{
			ArrayFree(pProfile->buddyStatusInfo->extendedInfoKeys);
			pProfile->buddyStatusInfo->extendedInfoKeys = NULL;
		}

		if(gpiCanFreeProfile(pProfile))
			gpiRemoveProfile(connection, pProfile);
		iconnection->profileList.numBuddies--;
		assert(iconnection->profileList.numBuddies >= 0);
#ifndef _PS2
		gpiProfileMap(connection, gpiFixBuddyIndices, (void *)(unsigned long)index);
#else
		gpiProfileMap(connection, gpiFixBuddyIndices, (void *)index);
#endif
	}
	return GP_NO_ERROR;
}
示例#2
0
GPResult gpiBuddyHandleKeyReply(GPConnection *connection, GPIPeer *peer, char *buffer)
{
	GPIProfile *pProfile;
		
	// Get the profile object to store the keys internally
	//////////////////////////////////////////////////////
	
	if(!gpiGetProfile(connection, peer->profile, &pProfile))
		Error(connection, GP_PARAMETER_ERROR, "Invalid profile.");
	
	// calculate the B64Decoded string len
	if (strcmp(buffer, "") == 0)
	{
		GPIPeerOp *anIterator;
		
		for (anIterator = peer->peerOpQueue.first; anIterator != NULL; anIterator = anIterator->next)
			if (anIterator->type == GPI_BM_KEYS_REQUEST)
				break;
		
		if (!anIterator)
		{
			return GP_NO_ERROR;
		}
		else if (anIterator->type == GPI_BM_KEYS_REQUEST && anIterator->callback)
		{
			GPGetBuddyStatusInfoKeysArg *arg = (GPGetBuddyStatusInfoKeysArg *)gsimalloc(sizeof(GPGetBuddyStatusInfoKeysArg));
			GPICallback callback;
			callback.callback = anIterator->callback;
			callback.param = anIterator->userData;
			
			arg->keys = NULL;
			arg->numKeys = 0;
			arg->values = NULL;
			arg->profile = peer->profile;
			gpiAddCallback(connection, callback, arg, NULL, 0);
			gpiPeerRemoveOp(peer, anIterator);
		}
	}
	else
	{
		int decodedLen = 0,
			index = 0, numKeys, i;
		char keyName[512];
		char keyVal[512];
		char decodeKey[512];
		char decodeVal[512];
		gsi_char **keys;
		gsi_char **values;
		GPIPeerOp *anIterator;
		char *checkKey = NULL;

		// start by getting the number of keys 
		gpiReadKeyAndValue(connection, buffer, &index,  keyName, keyVal);
		
		// do not continue further if the header is missing
		if (strcmp(keyName, "keys") != 0)
			CallbackError(connection, GP_NETWORK_ERROR, GP_PARSE, "Error reading keys reply message");
		
		numKeys = atoi(keyVal);

		if (numKeys == 0)
		{
			GPIPeerOp *anIterator;
			
			for (anIterator = peer->peerOpQueue.first; anIterator != NULL; anIterator = anIterator->next)
				if (anIterator->type == GPI_BM_KEYS_REQUEST)
					break;

			if (!anIterator)
			{
				return GP_NO_ERROR;
			}
			else if (anIterator->type == GPI_BM_KEYS_REQUEST && anIterator->callback)
			{
				GPGetBuddyStatusInfoKeysArg *arg = (GPGetBuddyStatusInfoKeysArg *)gsimalloc(sizeof(GPGetBuddyStatusInfoKeysArg));
				GPICallback callback;
				callback.callback = anIterator->callback;
				callback.param = anIterator->userData;

				arg->keys = NULL;
				arg->numKeys = 0;
				arg->values = NULL;
				arg->profile = peer->profile;
				gpiAddCallback(connection, callback, arg, NULL, 0);
				gpiPeerRemoveOp(peer, anIterator);
			}
		}
		else
		{
			keys = (gsi_char **)gsimalloc(sizeof(gsi_char *) * numKeys);
			values = (gsi_char **)gsimalloc(sizeof(gsi_char *) * numKeys);

			for (i = 0; i < numKeys; i++)
			{			
				gpiReadKeyAndValue(connection, buffer, &index,  keyName, keyVal);
				B64Decode(keyName, decodeKey, (int)strlen(keyName), &decodedLen, 2);
				decodeKey[decodedLen] = '\0';
				B64Decode(keyVal, decodeVal, (int)strlen(keyVal), &decodedLen, 2);
				decodeVal[decodedLen] = '\0';
	#ifdef GSI_UNICODE
				keys[i] = UTF8ToUCS2StringAlloc(decodeKey);
				values[i]= UTF8ToUCS2StringAlloc(decodeVal);
	#else
				keys[i] = goastrdup(decodeKey);
				values[i] = goastrdup(decodeVal);
	#endif

				if (gpiStatusInfoCheckKey(connection, pProfile->buddyStatusInfo->extendedInfoKeys, decodeKey, &checkKey) == GP_NO_ERROR
					&& checkKey == NULL)
				{
					gpiStatusInfoAddKey(connection, pProfile->buddyStatusInfo->extendedInfoKeys, decodeKey, decodeVal);
				}
				else
				{
					gpiStatusInfoSetKey(connection, pProfile->buddyStatusInfo->extendedInfoKeys, decodeKey, decodeVal);
				}
			}
			
			for (anIterator = peer->peerOpQueue.first; anIterator != NULL; anIterator = anIterator->next)
				if (anIterator->type == GPI_BM_KEYS_REQUEST)
					break;

			if (!anIterator)
			{
				return GP_NO_ERROR;
			}
			else if (anIterator->type == GPI_BM_KEYS_REQUEST && anIterator->callback)
			{
				GPICallback callback;
				GPGetBuddyStatusInfoKeysArg *arg = (GPGetBuddyStatusInfoKeysArg *)gsimalloc(sizeof(GPGetBuddyStatusInfoKeysArg));
				
				callback.callback = anIterator->callback;
				callback.param = anIterator->userData;
				
				// allocate a key array that points to each extended info key for that player
				arg->numKeys = numKeys;

				arg->keys = keys;
				arg->values = values;
				arg->profile = peer->profile;
				
				gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDYKEYS);
				gpiPeerRemoveOp(peer, anIterator);
			}
		}
	}
	
	return GP_NO_ERROR;
}
示例#3
0
GPResult
gpiPeerStartConnect(
  GPConnection * connection,
  GPIPeer * peer
)
{
	//int rcode;
	//struct sockaddr_in address;
	GPIProfile * profile;
	GPIConnection * iconnection = (GPIConnection*)*connection;
	GSUdpErrorCode anError;

	// Get the profile object.
	//////////////////////////
	if(!gpiGetProfile(connection, peer->profile, &profile))
		Error(connection, GP_NETWORK_ERROR, "Error connecting to a peer.");

	/*
	// Create the socket.
	/////////////////////
	peer->sock = socket(AF_INET, SOCK_STREAM, 0);
	if(peer->sock == INVALID_SOCKET)
		CallbackError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error creating a socket.");

	// Make it non-blocking.
	////////////////////////
	rcode = SetSockBlocking(peer->sock, 0);
	if(rcode == 0)
		CallbackError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error making a socket non-blocking.");

	// Bind the socket.
	///////////////////

// BD: PS2 Insock has bug with binding to port 0
// No sockets after the first will be able to bind

	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
	rcode = bind(peer->sock, (struct sockaddr *)&address, sizeof(struct sockaddr_in));
	if (gsiSocketIsError(rcode))
		CallbackError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error binding a socket.");

	// Set the socket sizes.
	////////////////////////
	gpiSetPeerSocketSizes(peer->sock);
	
	// Connect the socket.
	//////////////////////
	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
	address.sin_addr.s_addr = profile->buddyStatus->ip;
	address.sin_port = (gsi_u16)profile->buddyStatus->port;
	rcode = connect(peer->sock, (struct sockaddr *)&address, sizeof(struct sockaddr_in));
	if (gsiSocketIsError(rcode))
	{
		int error = GOAGetLastError(peer->sock);
		if((error != WSAEWOULDBLOCK) && (error != WSAEINPROGRESS) && (error != WSAETIMEDOUT) )
		{
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error connecting a socket.");
		}
	}
	*/

	if (profile->buddyStatusInfo)
	{
		GSUdpPeerState aPeerState;
		gsUdpEngineGetPeerState(profile->buddyStatusInfo->buddyIp , profile->buddyStatusInfo->buddyPort, &aPeerState);
		if (aPeerState != GS_UDP_PEER_CONNECTED || aPeerState != GS_UDP_PEER_CONNECTING)
		{
			anError = gsUdpEngineStartTalkingToPeer(profile->buddyStatusInfo->buddyIp , profile->buddyStatusInfo->buddyPort, 
			iconnection->mHeader, GPI_PEER_TIMEOUT);
			if (anError != GS_UDP_ADDRESS_ALREADY_IN_USE)
				CallbackError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error starting communication with a peer.");
		}
		peer->ip = profile->buddyStatusInfo->buddyIp;
		peer->port = profile->buddyStatusInfo->buddyPort;
	}
	// We're waiting for the connect to complete.
	/////////////////////////////////////////////
	peer->state = GPI_PEER_CONNECTING;

	return GP_NO_ERROR;
}
示例#4
0
GPResult
gpiSendBuddyMessage(
  GPConnection * connection,
  int profileid,
  int type,
  const char * message,
  int sendOption,
  GPIPeerOp *peerOp
)
{
	GPIPeer * peer;
	GPIProfile * profile;
	//GPIConnection *iconnection = (GPIConnection *)*connection;
	peer = gpiGetPeerByProfile(connection, profileid);
	if(!peer)
	{
		// Check if we should send this through the server.
		////////////////////////////////////////////////////
		if(!gpiGetProfile(connection, profileid, &profile) ||
		   (!profile->buddyStatusInfo || !profile->buddyStatusInfo->buddyPort))
		{
			if (sendOption == GP_DONT_ROUTE)
				return GP_NETWORK_ERROR;
			return gpiSendServerBuddyMessage(connection, profileid, type, message);
		}

		// Create a new peer connection for this message.
		/////////////////////////////////////////////////
		peer = gpiAddPeer(connection, profileid, GPITrue);
		if(!peer)
			return GP_MEMORY_ERROR;

		// Check if we need a sig.
		//////////////////////////
		if(!profile->peerSig)
		{
			// Get the sig.
			///////////////
			CHECK_RESULT(gpiPeerGetSig(connection, peer));
		}
		else
		{
			// Try to connect to the peer.
			//////////////////////////////
			CHECK_RESULT(gpiPeerStartConnect(connection, peer));
		}
	}
	else if (peer->state == GPI_PEER_DISCONNECTED)
	{
		if (gpiGetProfile(connection, profileid, &profile))
		{
			// clear the buddy port to prevent future messages from 
			// being sent via UDP layer
			if (profile->buddyStatusInfo)
				profile->buddyStatusInfo->buddyPort = 0;

			// send the message through the server
			if (sendOption == GP_DONT_ROUTE)
				return GP_NETWORK_ERROR;
			if (type < 100)
				return gpiSendServerBuddyMessage(connection, profileid, type, message);
		}
	}
	
	if (peerOp)
	{
		gpiPeerAddOp(peer, peerOp);
	}
	// Copy the message.
	////////////////////
	CHECK_RESULT(gpiPeerAddMessage(connection, peer, type, message));

	return GP_NO_ERROR;
}
示例#5
0
//FUNCTIONS
///////////
static GPResult
gpiProcessPeerInitiatingConnection(
  GPConnection * connection,
  GPIPeer * peer
)
{
	GPIConnection * iconnection = (GPIConnection*)*connection;
	//int state;
	char * str = NULL;
	//int len;
	GPIBool connClosed;
	GPIProfile * pProfile;
	GPResult result;
	GSUdpPeerState aPeerState;
	
	GS_ASSERT(peer);
	if (!peer)
		return GP_NETWORK_ERROR;

	GS_ASSERT(peer->state != GPI_PEER_DISCONNECTED && peer->state != GPI_PEER_NOT_CONNECTED);
	if (peer->state == GPI_PEER_DISCONNECTED || peer->state == GPI_PEER_NOT_CONNECTED)
		return GP_NETWORK_ERROR;
	// Check the state.
	///////////////////
	switch(peer->state)
	{
		case GPI_PEER_GETTING_SIG:
			// Do nothing - we're waiting for getinfo to get the sig.
			/////////////////////////////////////////////////////////
			break;

		case GPI_PEER_GOT_SIG:
		{
			// Start the connect.
			/////////////////////
			gsDebugFormat(GSIDebugCat_GP, GSIDebugType_State, GSIDebugLevel_Verbose, "Got the peer signature for profileid: %d\n", peer->profile);
			CHECK_RESULT(gpiPeerStartConnect(connection, peer));

			break;
		}
		case GPI_PEER_CONNECTING:
		{	
			// Check if the connect finished.
			/////////////////////////////////
			/*
			CHECK_RESULT(gpiCheckSocketConnect(connection, peer->sock, &state));
			if(state == GPI_DISCONNECTED)
			{
				Error(connection, GP_NETWORK_ERROR, "Error connecting to a peer.");
			}
			*/

			gsUdpEngineGetPeerState(peer->ip, peer->port, &aPeerState);

			if(aPeerState == GS_UDP_PEER_CONNECTED)
			{
				GPIPeer * pcurr;
				GPIBool freePeerSig = GPITrue;

				// Get the profile object.
				//////////////////////////
				if(!gpiGetProfile(connection, peer->profile, &pProfile))
					Error(connection, GP_NETWORK_ERROR, "Error connecting to a peer.");

				// Send the auth.
				/////////////////
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\auth\\");
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\pid\\");
				gpiAppendIntToBuffer(connection, &peer->outputBuffer, iconnection->profileid);
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\nick\\");
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, iconnection->nick);
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\sig\\");
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, pProfile->peerSig);
				gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\final\\");

				// Are there any other peers still connecting?
				//////////////////////////////////////////////
				for(pcurr = iconnection->peerList ; pcurr != NULL ; pcurr = pcurr->pnext)
					if((pcurr->profile == peer->profile) && (pcurr != peer))
						if(pcurr->state <= GPI_PEER_CONNECTING)
							freePeerSig = GPIFalse;

				// freeclear it?
				///////////
				if(freePeerSig)
				{
					freeclear(pProfile->peerSig);
					if(gpiCanFreeProfile(pProfile))
						gpiRemoveProfile(connection, pProfile);
				}

				// Update the state.
				////////////////////
				peer->state = GPI_PEER_WAITING;
			}
			
			break;
		}
		case GPI_PEER_WAITING:
		{
			// Check for a response.
			////////////////////////
			//CHECK_RESULT(gpiRecvToBuffer(connection, peer->sock, &peer->inputBuffer, &len, &connClosed, "PR"));

			// Check for a final.
			/////////////////////
			if (peer->inputBuffer.buffer)
				str = strstr(peer->inputBuffer.buffer, "\\final\\");
			if(str != NULL)
			{
				str[0] = '\0';
				str += 7;

				// Was it rejected?
				///////////////////
				if(strncmp(peer->inputBuffer.buffer, "\\anack\\", 7) == 0)
				{
					// Rejected.
					////////////
					peer->nackCount++;

					// Is this more than once?
					//////////////////////////
					if(peer->nackCount > 1)
					{
						// we shouldn't reach this case unless there is a problem with 
						// the server when getting a buddy's signature

						// Give up already.
						///////////////////
						Error(connection, GP_NETWORK_ERROR, "Error getting buddy authorization.");
					}

					// Try getting the latest sig.
					//////////////////////////////
					CHECK_RESULT(gpiPeerGetSig(connection, peer));
				}
				else if(strncmp(peer->inputBuffer.buffer, "\\aack\\", 6) != 0)
				{
					// Unknown message.
					///////////////////
					Error(connection, GP_NETWORK_ERROR, "Error parsing buddy message.");
				}

				// The connection has been established.
				///////////////////////////////////////
				peer->state = GPI_PEER_CONNECTED;
				peer->inputBuffer.len = 0;
			}

			break;
		}
		// code should not reach here.
		default: break;
	}

	// Send stuff that needs to be sent.
	////////////////////////////////////
	if(peer->outputBuffer.len > 0)
	{
		//result = gpiSendFromBuffer(connection, peer->sock, &peer->outputBuffer, &connClosed, GPITrue, "PR");
		result = gpiSendBufferToPeer(connection, peer->ip, peer->port, &peer->outputBuffer, &connClosed, GPITrue);
		if(connClosed || (result != GP_NO_ERROR))
			peer->state = GPI_PEER_DISCONNECTED;
	}
	
	return GP_NO_ERROR;
}