void MessageOverlordConnection::sendAchievements(set<Achievement*> achievements)
	{
		stringstream s;

		s << "{";
		s << "\"achievements\":";

			s << "{";
			bool first = true;
			set<Achievement*>::const_iterator it;
			for (it = achievements.begin(); it != achievements.end(); it++)
			{
				if (!first)
				{
					s << ",";
				}
				else
				{
					first = false;
				}

				Achievement *achievement = *it;

				string achievementName = achievement->getName();

				s << "\"" << achievementName << "\": {}";
			}
			s << "}";

		s << "}";

		string jsonMessage = s.str();
		messageInterface.sendMessage(jsonMessage);
	}
Пример #2
0
 /** A handy shortcut to increase points for an achievement key of the
  *  current player. */
 static void increaseAchievement(unsigned int index, const std::string &key,
                                 int increase = 1)
 {
     Achievement *a = getCurrentAchievementsStatus()->getAchievement(index);
     if (!a)
     {
         Log::fatal("PlayerManager", "Achievement '%d' not found.", index);
     }
     a->increase(key, increase);
 }   // increaseAchievement
Пример #3
0
int listSpecificAchievementCallback(void *userdata, int argc, char **argv, char **azColName)
    {
        Achievement *results;
        results = static_cast<Achievement *>(userdata);
        char* col;
        for(int i = 0; i< argc-1 ; i++)
        {
            col = azColName[i];
            if(stricmp(col,"Ach_name")== 0) results->setName(argv[i]);
            else if(stricmp(col,"Status")== 0) results->setStatus(argv[i]);
            else if(stricmp(col,"Description")== 0) results->setDescription(argv[i]);
            else if(stricmp(col,"Id")==0) results->setId(argv[i]);
        }
        return 0;
    }
Пример #4
0
/** Loads the saved state of all achievements from an XML file.
 *  \param input The XML node to load the data from.
 */
void AchievementsStatus::load(const XMLNode * input)
{
    std::vector<XMLNode*> xml_achievements;
    input->getNodes("achievement", xml_achievements);
    for (unsigned int i = 0; i < xml_achievements.size(); i++)
    {
        uint32_t achievement_id(0);
        xml_achievements[i]->get("id", &achievement_id);
        Achievement * achievement = getAchievement(achievement_id);
        if (achievement == NULL)
        {
            Log::warn("AchievementsStatus",
                "Found saved achievement data for a non-existent "
                "achievement. Discarding.");
            continue;
        }
        achievement->load(xml_achievements[i]);
    }   // for i in xml_achievements

}   // load
Пример #5
0
/** Synchronises the achievements between local and online usage. It takes
 *  the list of online achievements, and marks them all to be achieved 
 *  locally. Then it issues 'achieved' requests to the server for all local
 *  achievements that are not set online.
*/
void AchievementsStatus::sync(const std::vector<uint32_t> & achieved_ids)
{
    std::vector<bool> done;
    for(unsigned int i =0; i < achieved_ids.size(); ++i)
    {
        if(done.size()< achieved_ids[i]+1)
            done.resize(achieved_ids[i]+1);
        done[achieved_ids[i]] = true;
        Achievement * achievement = getAchievement(achieved_ids[i]);
        if(achievement != NULL)
            achievement->setAchieved();
    }

    std::map<uint32_t, Achievement*>::iterator i;

    // String to collect all local ids that are not synched
    // to the online account
    std::string ids;
    for(i=m_achievements.begin(); i!=m_achievements.end(); i++)
    {
        unsigned int id = i->second->getID();
        if(i->second->isAchieved() && (id>=done.size() || !done[id]) )
        {
            ids=ids+StringUtils::toString(id)+",";
        }
    }

    if(ids.size()>0)
    {
        ids = ids.substr(0, ids.size() - 1); // delete the last "," in the string
        Log::info("Achievements", "Synching achievement %d to server.",
                  ids.c_str());
        Online::HTTPRequest * request = new Online::HTTPRequest(true, 2);
        PlayerManager::setUserDetails(request, "achieving");
        request->addParameter("achievementid", ids);
        request->queue();
    }
}   // sync
Пример #6
0
/** Called at the end of a race. Updates highscores, pauses the game, and
 *  informs the unlock manager about the finished race. This function must
 *  be called after all other stats were updated from the different game
 *  modes.
 */
void World::terminateRace()
{
    m_schedule_pause = false;
    m_schedule_unpause = false;

    // Update the estimated finishing time for all karts that haven't
    // finished yet.
    const unsigned int kart_amount = getNumKarts();
    for(unsigned int i = 0; i < kart_amount ; i++)
    {
        if(!m_karts[i]->hasFinishedRace() && !m_karts[i]->isEliminated())
        {
            m_karts[i]->finishedRace(estimateFinishTimeForKart(m_karts[i]));

        }
    }   // i<kart_amount

    // Update highscores, and retrieve the best highscore if relevant
    // to show it in the GUI
    int best_highscore_rank = -1;
    int best_finish_time = -1;
    std::string highscore_who = "";
    StateManager::ActivePlayer* best_player = NULL;
    if (!this->isNetworkWorld())
    {
        updateHighscores(&best_highscore_rank, &best_finish_time, &highscore_who,
                     &best_player);
    }

    // Check achievements
    PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_COLUMBUS,
                                       getTrack()->getIdent(), 1);
    if (raceHasLaps())
    {
        PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_MARATHONER,
                                           "laps", race_manager->getNumLaps());
    }

    Achievement *achiev = PlayerManager::getCurrentAchievementsStatus()->getAchievement(AchievementInfo::ACHIEVE_GOLD_DRIVER);
    if (achiev)
    {
        std::string mode_name = getIdent(); // Get the race mode name
        int winner_position = 1;
        unsigned int opponents = achiev->getInfo()->getGoalValue("opponents"); // Get the required opponents number
        if (mode_name == IDENT_FTL)
        {
            winner_position = 2;
            opponents++;
        }
        for(unsigned int i = 0; i < kart_amount; i++)
        {
            // Retrieve the current player
            StateManager::ActivePlayer* p = m_karts[i]->getController()->getPlayer();
            if (p && p->getConstProfile() == PlayerManager::getCurrentPlayer())
            {
                // Check if the player has won
                if (m_karts[i]->getPosition() == winner_position && kart_amount > opponents )
                {
                    // Update the achievement
                    mode_name = StringUtils::toLowerCase(mode_name);
                    if (achiev->getValue("opponents") <= 0)
                        PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_GOLD_DRIVER,
                                                            "opponents", opponents);
                    PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_GOLD_DRIVER,
                                                        mode_name, 1);
                }
            }
        } // for i < kart_amount
    } // if (achiev)

    Achievement *win = PlayerManager::getCurrentAchievementsStatus()->getAchievement(AchievementInfo::ACHIEVE_UNSTOPPABLE);
    //if achivement has been unlocked
    if (win->getValue("wins") < 5 )
    {
        for(unsigned int i = 0; i < kart_amount; i++)
        {
            // Retrieve the current player
            StateManager::ActivePlayer* p = m_karts[i]->getController()->getPlayer();
            if (p && p->getConstProfile() == PlayerManager::getCurrentPlayer())
            {
                // Check if the player has won
                if (m_karts[i]->getPosition() == 1 )
                {
                    // Increase number of consecutive wins
                       PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_UNSTOPPABLE,
                                                            "wins", 1);
                }
                else
                {
                      //Set number of consecutive wins to 0
                      win->reset();
                }
            }
         }
    }
    PlayerManager::getCurrentPlayer()->raceFinished();

    if (m_race_gui) m_race_gui->clearAllMessages();
    // we can't delete the race gui here, since it is needed in case of
    // a restart: the constructor of it creates some textures which assume
    // that no scene nodes exist. In case of a restart there are scene nodes,
    // so we can't create the race gui again, so we keep it around
    // and save the pointer.
    assert(m_saved_race_gui==NULL);
    m_saved_race_gui = m_race_gui;

    RaceResultGUI* results = RaceResultGUI::getInstance();
    m_race_gui       = results;

    if (best_highscore_rank > 0)
    {
        results->setHighscore(highscore_who, best_player, best_highscore_rank,
                              best_finish_time);
    }
    else
    {
        results->clearHighscores();
    }

    results->push();
    WorldStatus::terminateRace();
}   // terminateRace
Пример #7
0
bool SQLiteConnector::createAchievement(Achievement saved)
{
    char sentence[256];
    if(dbConnect())
    {
            // sprintf(sentence,"UPDATE Achievements SET Ach_name='%s', Description='%s', Status='%s' WHERE Id='%s');",saved.getName(),saved.getDescription(),saved.getStatus(),saved.getId());
            sprintf(sentence,"INSERT OR REPLACE INTO Achievements (Id, Ach_name, Description, Status) Values ('%s', '%s', '%s', '%s');",saved.getId(),saved.getName(),saved.getDescription(),saved.getStatus());
            msg = sqlite3_exec(db,sentence,NULL,NULL,&error);
            if (msg != SQLITE_OK)
            {
                //cout << error << endl;
                return false;
            }

       dbDisconnect();
       return true;
    }
    return false;
}
Пример #8
0
void AchievementSet::LoadProgress( const char* sLoadStateFilename )
{
	char buffer[4096];
	long nFileSize = 0;
	unsigned int CondNumHits[50];	//	50 conditions per achievement
	unsigned int CondSourceVal[50];
	unsigned int CondSourceLastVal[50];
	unsigned int CondTargetVal[50];
	unsigned int CondTargetLastVal[50];
	unsigned int nID = 0;
	unsigned int nNumCond = 0;
	char cheevoProgressString[4096];
	unsigned int i = 0;
	unsigned int j = 0;
	char* pGivenProgressMD5 = NULL;
	char* pGivenCheevoMD5 = NULL;
	char cheevoMD5TestMangled[4096];
	int nMemStringLen = 0;

	if( !RAUsers::LocalUser().IsLoggedIn() )
		return;

	if( sLoadStateFilename == NULL )
		return;

	sprintf_s( buffer, 4096, "%s%s.rap", RA_DIR_DATA, sLoadStateFilename );

	char* pRawFile = _MallocAndBulkReadFileToBuffer( buffer, nFileSize );

	if( pRawFile != NULL )
	{
		unsigned int nOffs = 0;
		while( nOffs < (unsigned int)(nFileSize-2) && pRawFile[nOffs] != '\0' )
		{
			char* pIter = &pRawFile[nOffs];

			//	Parse achievement id and num conditions
			nID		 = strtol( pIter, &pIter, 10 ); pIter++;
			nNumCond = strtol( pIter, &pIter, 10 );	pIter++;

			//	Concurrently build the md5 checkstring
			sprintf_s( cheevoProgressString, 4096, "%d:%d:", nID, nNumCond );

			ZeroMemory( CondNumHits, 50*sizeof(unsigned int) );
			ZeroMemory( CondSourceVal, 50*sizeof(unsigned int) );
			ZeroMemory( CondSourceLastVal, 50*sizeof(unsigned int) );
			ZeroMemory( CondTargetVal, 50*sizeof(unsigned int) );
			ZeroMemory( CondTargetLastVal, 50*sizeof(unsigned int) );

			for( i = 0; i < nNumCond && i < 50; ++i )
			{
				//	Parse next condition state
				CondNumHits[i]		 = strtol( pIter, &pIter, 10 ); pIter++;
				CondSourceVal[i]	 = strtol( pIter, &pIter, 10 ); pIter++;
				CondSourceLastVal[i] = strtol( pIter, &pIter, 10 ); pIter++;
				CondTargetVal[i]	 = strtol( pIter, &pIter, 10 ); pIter++;
				CondTargetLastVal[i] = strtol( pIter, &pIter, 10 ); pIter++;
			
				//	Concurrently build the md5 checkstring
				sprintf_s( buffer, 4096, "%d:%d:%d:%d:%d:", 
					CondNumHits[i], 
					CondSourceVal[i],
					CondSourceLastVal[i],
					CondTargetVal[i],
					CondTargetLastVal[i] );

				strcat_s( cheevoProgressString, 4096, buffer );
			}

			//	Read the given md5:
			pGivenProgressMD5 = strtok_s( pIter, ":", &pIter );
			pGivenCheevoMD5 = strtok_s( pIter, ":", &pIter );
		
			//	Regenerate the md5 and see if it sticks:
			sprintf_s( cheevoMD5TestMangled, 4096, "%s%s%s%d", 
				RAUsers::LocalUser().Username().c_str(), cheevoProgressString, RAUsers::LocalUser().Username().c_str(), nID );

			std::string sRecalculatedProgressMD5 = RAGenerateMD5( cheevoMD5TestMangled );

			if( sRecalculatedProgressMD5.compare( pGivenProgressMD5 ) == 0 )
			{
				//	Embed in achievement:
				Achievement* pAch = Find( nID );
				if( pAch != NULL )
				{
					std::string sMemStr = pAch->CreateMemString();

					//	Recalculate the current achievement to see if it's compatible:
					std::string sMemMD5 = RAGenerateMD5( sMemStr );
					if( sMemMD5.compare( 0, 32, pGivenCheevoMD5 ) == 0 )
					{
						for( size_t nGrp = 0; nGrp < pAch->NumConditionGroups(); ++nGrp )
						{
							for( j = 0; j < pAch->NumConditions( nGrp ); ++j )
							{
								Condition& cond = pAch->GetCondition( nGrp, j );

								cond.OverrideCurrentHits( CondNumHits[ j ] );
								cond.CompSource().SetValues( CondSourceVal[ j ], CondSourceLastVal[ j ] );
								cond.CompTarget().SetValues( CondTargetVal[ j ], CondTargetLastVal[ j ] );

								pAch->SetDirtyFlag( Dirty_Conditions );
							}
						}
					}
					else
					{
						ASSERT( !"Achievement progress savestate incompatible (achievement has changed?)" );
						RA_LOG( "Achievement progress savestate incompatible (achievement has changed?)" );
					}
				}
				else
				{
					ASSERT( !"Achievement doesn't exist!" );
					RA_LOG( "Achievement doesn't exist!" );
				}
			}
			else
			{
				//assert(!"MD5 invalid... what to do... maybe they're trying to hack achievements?");
			}
		
			nOffs = (pIter - pRawFile);
		}
	
		free( pRawFile );
		pRawFile = NULL;
	}
}
Пример #9
0
void AchievementSet::SaveProgress( const char* sSaveStateFilename )
{
	if( !RAUsers::LocalUser().IsLoggedIn() )
		return;

	if( sSaveStateFilename == NULL )
		return;
	
	SetCurrentDirectory( Widen( g_sHomeDir ).c_str() );
	char buffer[ 4096 ];
	sprintf_s( buffer, 4096, "%s.rap", sSaveStateFilename );
	FILE* pf = NULL;
	fopen_s( &pf, buffer, "w" );
	if( pf == NULL )
	{
		ASSERT( !"Could not save progress!" );
		return;
	}

	for( size_t i = 0; i < NumAchievements(); ++i )
	{
		Achievement* pAch = &m_Achievements[i];
		if( !pAch->Active() )
			continue;

		//	Write ID of achievement and num conditions:
		char cheevoProgressString[4096];
		memset( cheevoProgressString, '\0', 4096 );

		for( unsigned int nGrp = 0; nGrp < pAch->NumConditionGroups(); ++nGrp )
		{
			sprintf_s( buffer, "%d:%d:", pAch->ID(), pAch->NumConditions( nGrp ) );
			strcat_s( cheevoProgressString, 4096, buffer );

			for( unsigned int j = 0; j < pAch->NumConditions( nGrp ); ++j )
			{
				Condition& cond = pAch->GetCondition( nGrp, j );
				sprintf_s( buffer, 4096, "%d:%d:%d:%d:%d:", 
					cond.CurrentHits(),
					cond.CompSource().RawValue(),
					cond.CompSource().RawPreviousValue(),
					cond.CompTarget().RawValue(),
					cond.CompTarget().RawPreviousValue() );
				strcat_s( cheevoProgressString, 4096, buffer );
			}
		}
		
		//	Generate a slightly different key to md5ify:
		char sCheevoProgressMangled[4096];
		sprintf_s( sCheevoProgressMangled, 4096, "%s%s%s%d", 
			RAUsers::LocalUser().Username().c_str(), cheevoProgressString, RAUsers::LocalUser().Username().c_str(), pAch->ID() );
		
		std::string sMD5Progress = RAGenerateMD5( std::string( sCheevoProgressMangled ) );
		std::string sMD5Achievement = RAGenerateMD5( pAch->CreateMemString() );
		
		fwrite( cheevoProgressString, sizeof(char), strlen(cheevoProgressString), pf );
		fwrite( sMD5Progress.c_str(), sizeof(char), sMD5Progress.length(), pf );
		fwrite( ":", sizeof(char), 1, pf );
		fwrite( sMD5Achievement.c_str(), sizeof(char), sMD5Achievement.length(), pf );
		fwrite( ":", sizeof(char), 1, pf );	//	Check!
	}

	fclose( pf );
}