GPResult gpiReadMessageFromBuffer( GPConnection * connection, GPIBuffer * inputBuffer, char ** message, int * type, int * plen ) { char * str; int len; char intValue[16]; // Default. /////////// *message = NULL; // Check for not enough data. ///////////////////////////// if(inputBuffer->len < 5) return GP_NO_ERROR; // Find the end of the header. ////////////////////////////// str = strchr(inputBuffer->buffer, '\n'); if(str != NULL) { // Check that this is the msg. ////////////////////////////// if(strncmp(str - 5, "\\msg\\", 5) != 0) return GP_NETWORK_ERROR; // Cap the header. ////////////////// *str = '\0'; // Read the header. /////////////////// if(!gpiValueForKey(inputBuffer->buffer, "\\m\\", intValue, sizeof(intValue))) return GP_NETWORK_ERROR; *type = atoi(intValue); // Get the length. ////////////////// if(!gpiValueForKey(inputBuffer->buffer, "\\len\\", intValue, sizeof(intValue))) return GP_NETWORK_ERROR; len = atoi(intValue); len++; // Is the whole message available? ////////////////////////////////// if(inputBuffer->len > ((str - inputBuffer->buffer) + len)) { // Does it not end with a NUL? ////////////////////////////// if(str[len] != '\0') return GP_NETWORK_ERROR; // Set the message stuff. ///////////////////////// *message = &str[1]; *plen = (len - 1); // Set the position to the end of the message. ////////////////////////////////////////////// inputBuffer->pos = ((str - inputBuffer->buffer) + len + 1); } else { // Put the LF back. /////////////////// *str = '\n'; } } GSI_UNUSED(connection); return GP_NO_ERROR; }
GPResult gpiProcessConnect( GPConnection * connection, GPIOperation * operation, const char * input ) { char buffer[512]; char check[33]; char uniquenick[GP_UNIQUENICK_LEN]; GPIConnectData * data; GPIConnection * iconnection = (GPIConnection*)*connection; GPICallback callback; GPIProfile * profile; char userBuffer[GP_NICK_LEN + GP_EMAIL_LEN]; char partnerBuffer[11]; char * user; // Check for an error. ////////////////////// if(gpiCheckForError(connection, input, GPIFalse)) { // Is this a deleted profile? ///////////////////////////// if((iconnection->errorCode == GP_LOGIN_PROFILE_DELETED) && iconnection->profileid) { // Remove this profile object. ////////////////////////////// gpiRemoveProfileByID(connection, iconnection->profileid); // If we have the profileid/userid cached, lose them. ///////////////////////////////////////////////////// iconnection->userid = 0; iconnection->profileid = 0; } // Check for creating an existing profile. ////////////////////////////////////////// else if(iconnection->errorCode == GP_NEWUSER_BAD_NICK) { // Store the pid. ///////////////// if(gpiValueForKey(input, "\\pid\\", buffer, sizeof(buffer))) iconnection->profileid = atoi(buffer); } // Call the callbacks. ////////////////////// CallbackFatalError(connection, GP_SERVER_ERROR, iconnection->errorCode, iconnection->errorString); } // Get a pointer to the data. ///////////////////////////// data = (GPIConnectData*)operation->data; switch(operation->state) { case GPI_CONNECTING: // This should be \lc\1. //////////////////////// if(strncmp(input, "\\lc\\1", 5) != 0) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the server challenge. //////////////////////////// if(!gpiValueForKey(input, "\\challenge\\", data->serverChallenge, sizeof(data->serverChallenge))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Check if this is a new user. /////////////////////////////// if(data->newuser) { // Send a new user message. /////////////////////////// CHECK_RESULT(gpiSendNewuser(connection, data)); // Update the operation's state. //////////////////////////////// operation->state = GPI_REQUESTING; } else { // Send a login message. //////////////////////// CHECK_RESULT(gpiSendLogin(connection, data)); // Update the operation's state. //////////////////////////////// operation->state = GPI_LOGIN; } break; case GPI_REQUESTING: // This should be \nur\. //////////////////////// if(strncmp(input, "\\nur\\", 5) != 0) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the userid. ////////////////// if(!gpiValueForKey(input, "\\userid\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->userid = atoi(buffer); // Get the profileid. ///////////////////// if(!gpiValueForKey(input, "\\profileid\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->profileid = atoi(buffer); // Send a login request. //////////////////////// CHECK_RESULT(gpiSendLogin(connection, data)); // Update the operation's state. //////////////////////////////// operation->state = GPI_LOGIN; break; case GPI_LOGIN: // This should be \lc\2. //////////////////////// if(strncmp(input, "\\lc\\2", 5) != 0) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the sesskey. /////////////////// if(!gpiValueForKey(input, "\\sesskey\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->sessKey = atoi(buffer); // Get the userid. ////////////////// if(!gpiValueForKey(input, "\\userid\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->userid = atoi(buffer); // Get the profileid. ///////////////////// if(!gpiValueForKey(input, "\\profileid\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->profileid = atoi(buffer); // Get the uniquenick. ////////////////////// if(!gpiValueForKey(input, "\\uniquenick\\", uniquenick, sizeof(uniquenick))) uniquenick[0] = '\0'; // Get the loginticket. ////////////////////// if(!gpiValueForKey(input, "\\lt\\", iconnection->loginTicket, sizeof(iconnection->loginTicket))) iconnection->loginTicket[0] = '\0'; // Construct the user. ////////////////////// if(iconnection->partnerID != GP_PARTNERID_GAMESPY) { sprintf(partnerBuffer, "%d@", iconnection->partnerID); } else { // GS ID's do not stash the partner ID in the auth challenge to support legacy clients. strcpy(partnerBuffer, ""); } if(data->authtoken[0]) user = data->authtoken; else if(iconnection->uniquenick[0]) { sprintf(userBuffer, "%s%s", partnerBuffer, iconnection->uniquenick); user = userBuffer; } else { sprintf(userBuffer, "%s%s@%s", partnerBuffer, iconnection->nick, iconnection->email); user = userBuffer; } // Construct the check. /////////////////////// sprintf(buffer, "%s%s%s%s%s%s", data->passwordHash, " ", user, data->serverChallenge, data->userChallenge, data->passwordHash); MD5Digest((unsigned char *)buffer, strlen(buffer), check); // Get the proof. ///////////////// if(!gpiValueForKey(input, "\\proof\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); // Check the server authentication. /////////////////////////////////// if(memcmp(check, buffer, 32) != 0) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_LOGIN_SERVER_AUTH_FAILED, "Could not authenticate server."); // Add the local profile to the list. ///////////////////////////////////// if(iconnection->infoCaching) { profile = gpiProfileListAdd(connection, iconnection->profileid); profile->profileId = iconnection->profileid; profile->userId = iconnection->userid; } // Set the connect state. ///////////////////////// iconnection->connectState = GPI_CONNECTED; // Call the connect-response callback. ////////////////////////////////////// callback = operation->callback; if(callback.callback != NULL) { GPConnectResponseArg * arg; arg = (GPConnectResponseArg *)gsimalloc(sizeof(GPConnectResponseArg)); if(arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); memset(arg, 0, sizeof(GPConnectResponseArg)); arg->profile = (GPProfile)iconnection->profileid; arg->result = GP_NO_ERROR; #ifndef GSI_UNICODE strzcpy(arg->uniquenick, uniquenick, GP_UNIQUENICK_LEN); #else UTF8ToUCS2StringLen(uniquenick, arg->uniquenick, GP_UNIQUENICK_LEN); #endif CHECK_RESULT(gpiAddCallback(connection, callback, arg, operation, 0)); } // This operation is complete. ////////////////////////////// gpiRemoveOperation(connection, operation); // Get the local profile's info. //////////////////////////////// #if 0 gpiAddOperation(connection, GPI_GET_INFO, NULL, &operation, GP_NON_BLOCKING, NULL, NULL); gpiSendGetInfo(connection, iconnection->profileid, operation->id); #endif #ifdef _PS3 // We just connected, so setup buddy sync && start NP init // For future, we can limit syncs by setting flags to turn on/off here ////////////////////////////////////////////////////////////////////// iconnection->npPerformBuddySync = gsi_true; iconnection->npPerformBlockSync = gsi_true; iconnection->loginTime = current_time(); if (!iconnection->npInitialized) gpiInitializeNpBasic(connection); #endif break; default: break; } return GP_NO_ERROR; }
GPResult gpiProcessRecvBuddyStatusInfo(GPConnection *connection, const char *input) { char buffer[1024]; int profileid; time_t date; GPICallback callback; GPIProfile * profile; GPIBuddyStatusInfo * buddyStatusInfo; GPIConnection * iconnection = (GPIConnection*)*connection; // This is what the message should look like. Its broken up for easy viewing. // // "\bsi\\state\\profile\\bip\\bport\\hostip\\hprivip\" // "\qport\\hport\\sessflags\\rstatus\\gameType\" // "\gameVnt\\gameMn\\product\\qmodeflags\" //////////////////////////////// date = time(NULL); // Get the buddy's profile //////////////////////////////// if(!gpiValueForKey(input, "\\profile\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); profileid = atoi(buffer); // Get the profile from the SDK's list, adding it if needed. ///////////////////////////////////// profile = gpiProfileListAdd(connection, profileid); if(!profile) Error(connection, GP_MEMORY_ERROR, "Out of memory."); // Make sure profile wasn't blocked prior to getting the status update ////////////////////////////////////////////////////////////////////// if (!profile->blocked) { // This is a buddy. /////////////////// if(!profile->buddyStatusInfo) { profile->buddyStatusInfo = (GPIBuddyStatusInfo *)gsimalloc(sizeof(GPIBuddyStatusInfo)); if(!profile->buddyStatusInfo) Error(connection, GP_MEMORY_ERROR, "Out of memory."); memset(profile->buddyStatusInfo, 0, sizeof(GPIBuddyStatusInfo)); if (profile->buddyStatus) { profile->buddyStatusInfo->buddyIndex = profile->buddyStatus->buddyIndex; gpiRemoveBuddyStatus(profile->buddyStatus); profile->buddyStatus = NULL; } else profile->buddyStatusInfo->buddyIndex = iconnection->profileList.numBuddies++; profile->buddyStatusInfo->extendedInfoKeys = ArrayNew(sizeof(GPIKey), GPI_INITIAL_NUM_KEYS, gpiStatusInfoKeyFree); if (!profile->buddyStatusInfo->extendedInfoKeys) Error(connection, GP_MEMORY_ERROR, "Out of memory."); } // extract the buddy status information and // fill in appropriate information. ///////////////////////////////////////////// buddyStatusInfo = profile->buddyStatusInfo; if (!gpiValueForKey(input, "\\state\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->statusState = (GPEnum)atoi(buffer); if (!gpiValueForKey(input, "\\bip\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->buddyIp = htonl((unsigned int)atoi(buffer)); if (!gpiValueForKey(input, "\\bport\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->buddyPort = (unsigned short)atoi(buffer); if (!gpiValueForKey(input, "\\hostip\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->hostIp = htonl((unsigned int)atoi(buffer)); if (!gpiValueForKey(input, "\\hprivip\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->hostPrivateIp = htonl((unsigned int)atoi(buffer)); if (!gpiValueForKey(input, "\\qport\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->queryPort = (unsigned short)atoi(buffer); if (!gpiValueForKey(input, "\\hport\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->hostPort = (unsigned short)atoi(buffer); if (!gpiValueForKey(input, "\\sessflags\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->sessionFlags = (unsigned int)atoi(buffer); freeclear(buddyStatusInfo->richStatus); if (!gpiValueForKey(input, "\\rstatus\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->richStatus = goastrdup(buffer); freeclear(buddyStatusInfo->gameType); if (!gpiValueForKey(input, "\\gameType\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->gameType = goastrdup(buffer); freeclear(buddyStatusInfo->gameVariant); if (!gpiValueForKey(input, "\\gameVnt\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->gameVariant = goastrdup(buffer); freeclear(buddyStatusInfo->gameMapName); if (!gpiValueForKey(input, "\\gameMn\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->gameMapName = goastrdup(buffer); if (!gpiValueForKey(input, "\\product\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->productId = (int)atoi(buffer); if (!gpiValueForKey(input, "\\qmodeflags\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->quietModeFlags = (GPEnum)atoi(buffer); callback = iconnection->callbacks[GPI_RECV_BUDDY_STATUS]; if (callback.callback != NULL) { GPRecvBuddyStatusArg *anArg; anArg = (GPRecvBuddyStatusArg *)gsimalloc(sizeof(GPRecvBuddyStatusArg)); if (anArg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); anArg->date = (unsigned int)date; anArg->index = buddyStatusInfo->buddyIndex; anArg->profile = profileid; CHECK_RESULT(gpiAddCallback(connection, callback, anArg, NULL, 0)); } } return GP_NO_ERROR; }
GPResult gpiProcessRecvBuddyMessage( GPConnection * connection, const char * input ) { char buffer[4096]; int type; int profileid; time_t date; GPICallback callback; GPIProfile * profile; GPIBuddyStatus * buddyStatus; char intValue[16]; char * str; unsigned short port; int productID; GPIConnection * iconnection = (GPIConnection*)*connection; char strTemp[max(GP_STATUS_STRING_LEN, GP_LOCATION_STRING_LEN)]; // Check the type of bm. //////////////////////// if(!gpiValueForKey(input, "\\bm\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); type = atoi(buffer); // Get the profile this is from. //////////////////////////////// if(!gpiValueForKey(input, "\\f\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); profileid = atoi(buffer); // Get the time. //////////////// if(!gpiValueForKey(input, "\\date\\", buffer, sizeof(buffer))) date = time(NULL); else date = atoi(buffer); // What type of message is this? //////////////////////////////// switch(type) { case GPI_BM_MESSAGE: // Call the callback. ///////////////////// callback = iconnection->callbacks[GPI_RECV_BUDDY_MESSAGE]; if(callback.callback != NULL) { GPRecvBuddyMessageArg * arg; arg = (GPRecvBuddyMessageArg *)gsimalloc(sizeof(GPRecvBuddyMessageArg)); if(arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); #ifndef GSI_UNICODE arg->message = (char *)gsimalloc(strlen(buffer) + 1); if(arg->message == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); strcpy(arg->message, buffer); arg->profile = (GPProfile)profileid; arg->date = (unsigned int)date; #else arg->message = (unsigned short*)gsimalloc(strlen(buffer)*2+2); if(arg->message == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); UTF8ToUCS2String(buffer, arg->message); arg->profile = (GPProfile)profileid; arg->date = (unsigned int)date; #endif CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_MESSAGE)); } break; case GPI_BM_UTM: // Call the callback. ///////////////////// callback = iconnection->callbacks[GPI_RECV_BUDDY_UTM]; if(callback.callback != NULL) { GPRecvBuddyUTMArg * arg; arg = (GPRecvBuddyUTMArg *)gsimalloc(sizeof(GPRecvBuddyUTMArg)); if(arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); #ifndef GSI_UNICODE arg->message = (char *)gsimalloc(strlen(buffer) + 1); if(arg->message == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); strcpy(arg->message, buffer); arg->profile = (GPProfile)profileid; arg->date = (unsigned int)date; #else arg->message = (unsigned short*)gsimalloc(strlen(buffer)*2+2); if(arg->message == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); UTF8ToUCS2String(buffer, arg->message); arg->profile = (GPProfile)profileid; arg->date = (unsigned int)date; #endif CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDYUTM)); } break; case GPI_BM_REQUEST: // Get the profile, adding if needed. ///////////////////////////////////// profile = gpiProfileListAdd(connection, profileid); if(!profile) Error(connection, GP_MEMORY_ERROR, "Out of memory."); // Get the reason. ////////////////// if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Find where the sig starts. ///////////////////////////// str = strstr(buffer, "|signed|"); if(str == NULL) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the sig out of the message. ////////////////////////////////// *str = '\0'; str += 8; if(strlen(str) != 32) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); freeclear(profile->authSig); profile->authSig = goastrdup(str); profile->requestCount++; // Call the callback. ///////////////////// callback = iconnection->callbacks[GPI_RECV_BUDDY_REQUEST]; if(callback.callback != NULL) { GPRecvBuddyRequestArg * arg; arg = (GPRecvBuddyRequestArg *)gsimalloc(sizeof(GPRecvBuddyRequestArg)); if(arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); #ifndef GSI_UNICODE strzcpy(arg->reason, buffer, GP_REASON_LEN); #else UTF8ToUCS2String(buffer, arg->reason); #endif arg->profile = (GPProfile)profileid; arg->date = (unsigned int)date; CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDDYREQUEST)); } break; case GPI_BM_AUTH: // call the callback callback = iconnection->callbacks[GPI_RECV_BUDDY_AUTH]; if(callback.callback != NULL) { GPRecvBuddyAuthArg * arg; arg = (GPRecvBuddyAuthArg *)gsimalloc(sizeof(GPRecvBuddyAuthArg)); if (arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); arg->profile = (GPProfile)profileid; arg->date = (unsigned int)date; CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDYAUTH)); } break; case GPI_BM_REVOKE: // call the callback callback = iconnection->callbacks[GPI_RECV_BUDDY_REVOKE]; if(callback.callback != NULL) { GPRecvBuddyRevokeArg * arg; arg = (GPRecvBuddyRevokeArg *)gsimalloc(sizeof(GPRecvBuddyRevokeArg)); if (arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); arg->profile = (GPProfile)profileid; arg->date = (unsigned int)date; CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_BUDDYREVOKE)); } break; case GPI_BM_STATUS: // Get the profile, adding if needed. ///////////////////////////////////// profile = gpiProfileListAdd(connection, profileid); if(!profile) Error(connection, GP_MEMORY_ERROR, "Out of memory."); // Make sure profile wasn't blocked prior to getting the status update ////////////////////////////////////////////////////////////////////// if (!profile->blocked) { // This is a buddy. /////////////////// if(!profile->buddyStatus) { profile->buddyStatus = (GPIBuddyStatus *)gsimalloc(sizeof(GPIBuddyStatus)); if(!profile->buddyStatus) Error(connection, GP_MEMORY_ERROR, "Out of memory."); memset(profile->buddyStatus, 0, sizeof(GPIBuddyStatus)); if (profile->buddyStatusInfo) { profile->buddyStatus->buddyIndex = profile->buddyStatusInfo->buddyIndex; gpiRemoveBuddyStatusInfo(profile->buddyStatusInfo); profile->buddyStatusInfo = NULL; } else profile->buddyStatus->buddyIndex = iconnection->profileList.numBuddies++; } // Get the buddy status. //////////////////////// buddyStatus = profile->buddyStatus; // Get the msg. /////////////// if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the status. ////////////////// if(!gpiValueForKey(buffer, "|s|", intValue, sizeof(intValue))) { CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); } else { buddyStatus->status = (GPEnum)atoi(intValue); } // Get the status string. ///////////////////////// freeclear(buddyStatus->statusString); if(!gpiValueForKey(buffer, "|ss|", strTemp, GP_STATUS_STRING_LEN)) strTemp[0] = '\0'; buddyStatus->statusString = goastrdup(strTemp); if(!buddyStatus->statusString) Error(connection, GP_MEMORY_ERROR, "Out of memory."); // Get the location string. /////////////////////////// freeclear(buddyStatus->locationString); if(!gpiValueForKey(buffer, "|ls|", strTemp, GP_LOCATION_STRING_LEN)) strTemp[0] = '\0'; buddyStatus->locationString = goastrdup(strTemp); if(!buddyStatus->locationString) Error(connection, GP_MEMORY_ERROR, "Out of memory."); // Get the ip. ////////////// if(!gpiValueForKey(buffer, "|ip|", intValue, sizeof(intValue))) buddyStatus->ip = 0; else buddyStatus->ip = htonl((unsigned int)atoi(intValue)); // Get the port. //////////////// if(!gpiValueForKey(buffer, "|p|", intValue, sizeof(intValue))) buddyStatus->port = 0; else { port = (unsigned short)atoi(intValue); buddyStatus->port = htons(port); } // Get the quiet mode flags. //////////////////////////// if(!gpiValueForKey(buffer, "|qm|", intValue, sizeof(intValue))) buddyStatus->quietModeFlags = GP_SILENCE_NONE; else buddyStatus->quietModeFlags = (GPEnum)atoi(intValue); // Call the callback. ///////////////////// callback = iconnection->callbacks[GPI_RECV_BUDDY_STATUS]; if(callback.callback != NULL) { GPRecvBuddyStatusArg * arg; arg = (GPRecvBuddyStatusArg *)gsimalloc(sizeof(GPRecvBuddyStatusArg)); if(arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); arg->profile = (GPProfile)profileid; arg->index = buddyStatus->buddyIndex; arg->date = (unsigned int)date; CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, GPI_ADD_STATUS)); } } break; case GPI_BM_INVITE: // Get the msg. /////////////// if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Find the productid. ////////////////////// str = strstr(buffer, "|p|"); if(str == NULL) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Skip the |p|. //////////////// str += 3; if(str[0] == '\0') CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the productid. ///////////////////// productID = atoi(str); // Find the location string (optional - older versions won't have) str = strstr(buffer, "|l|"); if(str != NULL) strzcpy(strTemp, (str+3), sizeof(strTemp)); else strTemp[0] = '\0'; // no location, set to empty string // Call the callback. ///////////////////// callback = iconnection->callbacks[GPI_RECV_GAME_INVITE]; if(callback.callback != NULL) { GPRecvGameInviteArg * arg; arg = (GPRecvGameInviteArg *)gsimalloc(sizeof(GPRecvGameInviteArg)); if(arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); arg->profile = (GPProfile)profileid; arg->productID = productID; #ifdef GSI_UNICODE AsciiToUCS2String(strTemp, arg->location); #else strcpy(arg->location, strTemp); #endif CHECK_RESULT(gpiAddCallback(connection, callback, arg, NULL, 0)); } break; case GPI_BM_PING: // Get the msg. /////////////// if(!gpiValueForKey(input, "\\msg\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Send back a pong. //////////////////// gpiSendBuddyMessage(connection, profileid, GPI_BM_PONG, "1", 0, NULL); break; #ifndef NOFILE case GPI_BM_PONG: // Lets the transfers handle this. ////////////////////////////////// gpiTransfersHandlePong(connection, profileid, NULL); break; #endif } return GP_NO_ERROR; }
static GPResult gpiProcessPeerAcceptingConnection( GPConnection * connection, GPIPeer * peer ) { GPIConnection * iconnection = (GPIConnection*)*connection; GSUdpPeerState aPeerState; char * str; //int len; GPIBool connClosed; char intValue[16]; int pid; char nick[GP_NICK_LEN]; char sig[33]; char sigCheck[33]; char buffer[256]; // Check the state. /////////////////// GS_ASSERT(peer->state == GPI_PEER_WAITING); if (peer->state != GPI_PEER_WAITING) return GP_NETWORK_ERROR; // Read any pending info. ///////////////////////// //CHECK_RESULT(gpiRecvToBuffer(connection, peer->sock, &peer->inputBuffer, &len, &connClosed, "PR")); gsUdpEngineGetPeerState(peer->ip, peer->port, &aPeerState); // Check for a closed connection. ///////////////////////////////// if(aPeerState == GS_UDP_PEER_CLOSED) { peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Check for a final. ///////////////////// str = strstr(peer->inputBuffer.buffer, "\\final\\"); if(str != NULL) { str[0] = '\0'; str += 7; // Is it an auth? ///////////////// if(strncmp(peer->inputBuffer.buffer, "\\auth\\", 6) == 0) { // Get the pid. /////////////// if(!gpiValueForKey(peer->inputBuffer.buffer, "\\pid\\", intValue, sizeof(intValue))) { peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } pid = atoi(intValue); // Get the nick. //////////////// if(!gpiValueForKey(peer->inputBuffer.buffer, "\\nick\\", nick, sizeof(nick))) { peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Get the sig. /////////////// if(!gpiValueForKey(peer->inputBuffer.buffer, "\\sig\\", sig, sizeof(sig))) { peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Compute what the sig should be. ////////////////////////////////// sprintf(buffer, "%s%d%d", iconnection->password, iconnection->profileid, pid); MD5Digest((unsigned char *)buffer, strlen(buffer), sigCheck); // Check the sig. ///////////////// if(strcmp(sig, sigCheck) != 0) { // Bad sig. /////////// gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\anack\\"); gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\final\\"); gpiSendBufferToPeer(connection, peer->ip, peer->port, &peer->outputBuffer, &connClosed, GPITrue); peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Send an ack. /////////////// gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\aack\\"); gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\final\\"); peer->state = GPI_PEER_CONNECTED; peer->profile = (GPProfile)pid; } else { // Unrecognized command. //////////////////////// peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Update the buffer length. //////////////////////////// peer->inputBuffer.len = 0; } return GP_NO_ERROR; }