/** This version of DecodeMessageData() will extract a 'v' region. The region values will be assigned to vBuf once it has been determined that this message is a 'put' query. */ void DHTMessage::DecodeMessageData(byte* bencMessageBytes, int numBytes) { std::vector<const char*> keys; keys.push_back("a\0v\0"); keys.push_back("r\0v\0"); if(!BencEntity::ParseInPlace(bencMessageBytes, *_bDict, bencMessageBytes + numBytes, keys, ®ion)){ _parseSuccessful = false; dhtMessageType = DHT_UNDEFINED_MESSAGE; return; } _parseSuccessful = true; DecodeMessageData(*_bDict); }
//Translates a string message in the format of <type, var1, var2,...> //into its appropriate structure //param:message->The message to translate //param:gameData->The game data structure to fill with the results //Returns true if successful, false if message is invalid format. If returned //false, then the values in the gameData structure are invalid bool Translator::DecodeData(std::string message, GameData &gameData) { try { //Find the first comma int firstComma = message.find_first_of(','); //Check for errors if(firstComma == std::string::npos) { throw std::exception("Message Not Complete Or Correct Format"); return false; } //Get the type of Data it is std::string type = message.substr(1, firstComma); //Try to convert from string to integer int dataType = std::stoi(type); //Call the appropriate decode message based on the type switch (dataType) { case Type::clientData: if(DecodeClientData(message, gameData.Data.clientdata)) { gameData.Data.clientdata.type = clientData; return true; } break; case Type::inputData: if(DecodeInputData(message, gameData.Data.inputdata)) { gameData.Data.inputdata.type = inputData; return true; } break; case Type::mapData: if(DecodeMapData(message, gameData.Data.mapdata)) { gameData.Data.mapdata.type = inputData; return true; } break; case Type::messageData: if(DecodeMessageData(message, gameData.Data.messagedata, gameData.message)) { gameData.Data.messagedata.type = messageData; return true; } break; case Type::playerData: if(DecodePlayerData(message, gameData.Data.playerdata)) { gameData.Data.playerdata.type = playerData; return true; } break; case Type::projectileData: if(DecodeProjectileData(message, gameData.Data.projectiledata)) { gameData.Data.projectiledata.type = projectileData; return true; } break; case Type::serverData: if(DecodeServerData(message, gameData.Data.serverdata)) { gameData.Data.serverdata.type = serverData; return true; } break; case Type::statsData: if(DecodeStatsData(message, gameData.Data.statsdata)) { gameData.Data.statsdata.type = statsData; return true; } break; case Type::loginData: if(DecodeLoginData(message, gameData.Data.logindata)) { gameData.Data.logindata.type = loginData; return true; } break; case Type::loginResultsData: if(DecodeLoginResultsData(message, gameData.Data.loginresultsdata)) { gameData.Data.loginresultsdata.type = loginResultsData; return true; } break; case Type::requestData: if(DecodeRequestData(message, gameData.Data.requestdata)) { gameData.Data.requestdata.type = requestData; return true; } break; default: break; } } catch(std::invalid_argument e) { //If we find an exception, we will return false return false; } return false; }
DHTMessage::DHTMessage(byte* bencMessageBytes, int numBytes) { Init(); _bDict = new BencodedDict; DecodeMessageData(bencMessageBytes, numBytes); }