bool CStatsAndAchievements::LoadUserStatsOnPS3() { #ifdef _PS3 // On PS3, we need to load the user's stats & achievement information from the save container. In this example, we are simply // reading the data from a known location on disk FILE *file = fopen( GetUserSaveDataPath(), "rb" ); if ( !file ) { // we need to tell Steam that there is no data SteamUserStats()->SetUserStatsData( NULL, 0 ); return true; } fseek( file, 0, SEEK_END ); long nSize = ftell( file ); fseek( file, 0, SEEK_SET ); byte *buffer = new byte[nSize]; fread( buffer, 1, nSize, file ); fclose( file ); bool bRet = SteamUserStats()->SetUserStatsData( buffer, nSize ); delete [] buffer; return bRet; #else return true; #endif }
void CSteamAchievements::OnUserStatsReceived( UserStatsReceived_t *pCallback ) { // we may get callbacks for other games' stats arriving, ignore them if ( m_iAppID == pCallback->m_nGameID ) { if ( k_EResultOK == pCallback->m_eResult ) { //OutputDebugString("Received stats and achievements from Steam\n"); m_bInitialized = true; // load achievements for ( int iAch = 0; iAch < m_iNumAchievements; ++iAch ) { Achievement_t &ach = m_pAchievements[iAch]; SteamUserStats()->GetAchievement(ach.m_pchAchievementID, &ach.m_bAchieved); _snprintf( ach.m_rgchName, sizeof(ach.m_rgchName), "%s", SteamUserStats()->GetAchievementDisplayAttribute(ach.m_pchAchievementID, "name")); _snprintf( ach.m_rgchDescription, sizeof(ach.m_rgchDescription), "%s", SteamUserStats()->GetAchievementDisplayAttribute(ach.m_pchAchievementID, "desc")); } } else { char buffer[128]; _snprintf( buffer, 128, "RequestStats - failed, %d\n", pCallback->m_eResult ); //OutputDebugString( buffer ); } } }
bool CSteamStats::StoreStats() { if ( m_bInitialized ) { // load stats for ( int iStat = 0; iStat < m_iNumStats; ++iStat ) { Stat_t &stat = m_pStats[iStat]; switch (stat.m_eStatType) { case STAT_INT: SteamUserStats()->SetStat(stat.m_pchStatName, stat.m_iValue); break; case STAT_FLOAT: SteamUserStats()->SetStat(stat.m_pchStatName, stat.m_flValue); break; case STAT_AVGRATE: SteamUserStats()->UpdateAvgRateStat(stat.m_pchStatName, stat.m_flAvgNumerator, stat.m_flAvgDenominator ); // The averaged result is calculated for us SteamUserStats()->GetStat(stat.m_pchStatName, &stat.m_flValue ); break; default: break; } } return SteamUserStats()->StoreStats(); } return 0; }
void SteamObject::clear_achievement(const chowstring & name) { #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) return; SteamUserStats()->ClearAchievement(name.c_str()); SteamUserStats()->StoreStats(); #endif }
void SteamObject::clear_achievements() { #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) return; SteamUserStats()->ResetAllStats(true); SteamUserStats()->StoreStats(); #endif }
bool CSteamAchievements::SetAchievement(const char* ID) { // Have we received a call back from Steam yet? if (m_bInitialized) { SteamUserStats()->SetAchievement(ID); return SteamUserStats()->StoreStats(); } // If not then we can't set achievements yet return false; }
bool CSteamAchievements::RequestStats() { // Is Steam loaded? If not we can't get stats. if ( NULL == SteamUserStats() || NULL == SteamUser() ) { return false; } // Is the user logged on? If not we can't get stats. if ( !SteamUser()->BLoggedOn() ) { return false; } // Request user stats. return SteamUserStats()->RequestCurrentStats(); }
int SteamGlobal::init() { #if defined(CHOWDREN_FORCE_STEAM_OPEN) && defined(CHOWDREN_STEAM_APPID) if (SteamAPI_RestartAppIfNecessary(CHOWDREN_STEAM_APPID)) { return EXIT_FAILURE; } #endif initialized = SteamAPI_Init(); if (!initialized) { std::cout << "Could not initialize Steam API" << std::endl; #ifdef CHOWDREN_FORCE_STEAM_OPEN SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Steam error", "Could not initialize Steam API. " "Please make sure you are logged in to Steam " "before opening the game.", NULL); return EXIT_FAILURE; #endif return 0; } std::cout << "Initialized Steam API" << std::endl; bool debug_achievements = getenv("CHOWDREN_DEBUG_ACHIEVEMENTS") != NULL; if (debug_achievements) { if (!SteamUserStats()->ResetAllStats(true)) std::cout << "Could not reset stats" << std::endl; } if (!SteamUserStats()->RequestCurrentStats()) std::cout << "Could not request Steam stats" << std::endl; #ifdef CHOWDREN_STEAM_APPID ISteamApps * ownapp = SteamApps(); if (!ownapp->BIsSubscribedApp(CHOWDREN_STEAM_APPID)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Steam error", "Please purchase the Steam version of the " "game if you want to play it on Steam.", NULL); return EXIT_FAILURE; } #endif steam_language = SteamApps()->GetCurrentGameLanguage(); if (steam_language.empty()) steam_language = "english"; steam_language[0] = toupper(steam_language[0]); std::cout << "Detected Steam language: " << steam_language << std::endl; return 0; }
CStatsAndAchievements::CStatsAndAchievements( IGameEngine *pGameEngine ) : m_pGameEngine( pGameEngine ), m_pSteamUser( NULL ), m_pSteamUserStats( NULL ), m_GameID( SteamUtils()->GetAppID() ), m_CallbackUserStatsReceived( this, &CStatsAndAchievements::OnUserStatsReceived ), m_CallbackUserStatsStored( this, &CStatsAndAchievements::OnUserStatsStored ), m_CallbackAchievementStored( this, &CStatsAndAchievements::OnAchievementStored ), m_CallbackPS3TrophiesInstalled( this, &CStatsAndAchievements::OnPS3TrophiesInstalled ) { m_pSteamUser = SteamUser(); m_pSteamUserStats = SteamUserStats(); m_bRequestedStats = false; m_bStatsValid = false; m_bStoreStats = false; m_flGameFeetTraveled = 0; m_nTotalGamesPlayed = 0; m_nTotalNumWins = 0; m_nTotalNumLosses = 0; m_flTotalFeetTraveled = 0; m_flMaxFeetTraveled = 0; m_flAverageSpeed = 0; m_hDisplayFont = pGameEngine->HCreateFont( ACHDISP_FONT_HEIGHT, FW_MEDIUM, false, "Arial" ); if ( !m_hDisplayFont ) OutputDebugString( "Stats font was not created properly, text won't draw\n" ); m_bInstalledPS3Trophies = false; m_bStartedPS3TrophyInstall = false; }
void SteamObject::unlock_achievement(const chowstring & name) { #ifndef NDEBUG std::cout << "Unlock achievement: " << name << std::endl; #endif #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) return; SteamUserStats()->SetAchievement(name.c_str()); SteamUserStats()->StoreStats(); #endif #ifndef CHOWDREN_IS_DESKTOP platform_unlock_achievement(name); #endif }
void SteamObject::request_user_data() { #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) return; SteamUserStats()->RequestCurrentStats(); #endif }
void SteamObject::store_user_data() { #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) return; SteamUserStats()->StoreStats(); #endif }
void CSteamLeaderboards::FindLeaderboard( const char *pchLeaderboardName ) { m_CurrentLeaderboard = NULL; SteamAPICall_t hSteamAPICall = SteamUserStats()->FindLeaderboard(pchLeaderboardName); m_callResultFindLeaderboard.Set(hSteamAPICall, this, &CSteamLeaderboards::OnFindLeaderboard); }
void SteamObject::set_int(const chowstring & name, int value) { #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) return; int32 v = value; SteamUserStats()->SetStat(name.c_str(), v); #endif }
bool SteamObject::is_achievement_unlocked(const chowstring & name) { #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) return false; bool achieved; SteamUserStats()->GetAchievement(name.c_str(), &achieved); return achieved; #else return false; #endif }
int SteamObject::get_int(const chowstring & name) { #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) return 0; int32 ret; if (!SteamUserStats()->GetStat(name.c_str(), &ret)) return 0; return ret; #else return 0; #endif }
// The constructor :o CStatsAndAchievements::CStatsAndAchievements(const char* sAIModel) : m_pSteamUser( NULL ), m_pSteamUserStats( NULL ), m_GameID( SteamUtils()->GetAppID() ), m_CallbackUserStatsStored( this, &CStatsAndAchievements::OnUserStatsStored ), m_CallbackAchievementStored( this, &CStatsAndAchievements::OnAchievementStored ), m_CallbackUserStatsReceived( this, &CStatsAndAchievements::OnUserStatsReceived ) { m_pSteamUser = SteamUser(); m_pSteamUserStats = SteamUserStats(); m_bRequestedStats = false; m_bStatsValid = false; m_sAIModel = sAIModel; }
void CSteamStats::OnUserStatsReceived( UserStatsReceived_t *pCallback ) { // we may get callbacks for other games' stats arriving, ignore them if ( m_iAppID == pCallback->m_nGameID ) { if ( k_EResultOK == pCallback->m_eResult ) { sysLogPrintDebug("[STEAM stats] Received stats and achievements from Steam\n" ); // load stats for ( int iStat = 0; iStat < m_iNumStats; ++iStat ) { Stat_t &stat = m_pStats[iStat]; switch (stat.m_eStatType) { case STAT_INT: SteamUserStats()->GetStat(stat.m_pchStatName, &stat.m_iValue); break; case STAT_FLOAT: case STAT_AVGRATE: SteamUserStats()->GetStat(stat.m_pchStatName, &stat.m_flValue); break; default: break; } } m_bInitialized = true; } else { char buffer[128]; _snprintf( buffer, 128, "RequestStats - failed, %d\n", pCallback->m_eResult ); sysLogPrintDebug("[STEAM stats] %s",buffer ); } } }
bool CSteamLeaderboards::UploadScore( int score ) { if (!m_CurrentLeaderboard) { sysLogPrintDebug("CSteamLeaderboards::UploadScore() m_CurrentLeaderBoard = 0"); return false; } SteamAPICall_t hSteamAPICall = SteamUserStats()->UploadLeaderboardScore( m_CurrentLeaderboard, k_ELeaderboardUploadScoreMethodKeepBest, score, NULL, 0 ); m_callResultUploadScore.Set(hSteamAPICall, this, &CSteamLeaderboards::OnUploadScore); return true; }
bool CStatsAndAchievements::SaveUserStatsOnPS3() { #ifdef _PS3 // On PS3, we need to save the user's stats & achievement information into the save container. In this example, we are simply // saving the data to a known location on disk // get required buffer size uint32 unSize = 0; if ( !SteamUserStats()->GetUserStatsData( NULL, 0, &unSize ) && unSize == 0 ) return false; // get data byte *buffer = new byte[unSize]; uint32 unWritten = 0; bool bRet = SteamUserStats()->GetUserStatsData( buffer, unSize, &unWritten ); if ( bRet ) { FILE *file = fopen( GetUserSaveDataPath(), "wb" ); if ( file ) { bRet = (fwrite( buffer, 1, unWritten, file ) == unWritten); fclose( file ); } else { bRet = false; } } delete [] buffer; return bRet; #else return true; #endif }
bool SteamObject::is_activated() { #ifdef CHOWDREN_ENABLE_STEAM if (!global_steam_obj.initialized) #ifdef CHOWDREN_FORCE_STEAM_OPEN return false; #else return true; #endif SteamUserStats()->RequestCurrentStats(); ISteamApps * ownapp = SteamApps(); return ownapp->BIsSubscribedApp(CHOWDREN_STEAM_APPID); #else return true; #endif }
/** * ** INTERNAL ** * Called by an async task after completing an achievement read. * * @param PlayerId - id of a player we were making read for * @param bReadSuccessfully - whether the read completed successfully */ void FOnlineAchievementsSteam::UpdateAchievementsForUser(const FUniqueNetIdSteam& PlayerId, bool bReadSuccessfully) { // shouldn't get this far if no achievements are configured check(bHaveConfiguredAchievements); ISteamUserStats* SteamUserStatsPtr = SteamUserStats(); check(SteamUserStatsPtr); CSteamID SteamUserId = PlayerId; // new array TArray<FOnlineAchievement> AchievementsForPlayer; const int32 AchNum = Achievements.Num(); for (int32 AchIdx = 0; AchIdx < AchNum; ++AchIdx) { // get the info bool bUnlocked; uint32 UnlockUnixTime; if (!SteamUserStatsPtr->GetAchievementAndUnlockTime(TCHAR_TO_UTF8(*Achievements[AchIdx].Id), &bUnlocked, &UnlockUnixTime)) { UE_LOG_ONLINE(Warning, TEXT("GetAchievementAndUnlockTime() failed for achievement '%s'"), *Achievements[AchIdx].Id); // skip this achievement continue; } FOnlineAchievementSteam NewAch = Achievements[ AchIdx ]; NewAch.bReadFromSteam = true; NewAch.Progress = bUnlocked ? 100.0 : 0.0; // TODO: we may want to support more fine-grained progress based on associated stat and min/max, // although we can only map it one-way (i.e. when reading, but not when writing) NewAch.UnlockTime = FDateTime::FromUnixTimestamp(UnlockUnixTime); NewAch.Title = FText::FromString( UTF8_TO_TCHAR( SteamUserStatsPtr->GetAchievementDisplayAttribute(TCHAR_TO_UTF8(*Achievements[AchIdx].Id), "name") ) ); NewAch.LockedDesc = FText::FromString( UTF8_TO_TCHAR( SteamUserStatsPtr->GetAchievementDisplayAttribute(TCHAR_TO_UTF8(*Achievements[AchIdx].Id), "desc") ) ); NewAch.UnlockedDesc = NewAch.LockedDesc; NewAch.bIsHidden = FCString::Atoi( UTF8_TO_TCHAR( SteamUserStatsPtr->GetAchievementDisplayAttribute(TCHAR_TO_UTF8(*Achievements[AchIdx].Id), "desc") ) ) != 0; UE_LOG_ONLINE(Verbose, TEXT("Read achievement %d: %s"), AchIdx, *NewAch.ToDebugString()); AchievementsForPlayer.Add( NewAch ); // add mapping (should replace any existing one) AchievementDescriptions.Add(NewAch.Id, NewAch); } // should replace any already existing values PlayerAchievements.Add(PlayerId, AchievementsForPlayer); }
bool FOnlineAchievementsSteam::ResetAchievements(const FUniqueNetId& PlayerId) { if (!bHaveConfiguredAchievements) { // we don't have achievements UE_LOG_ONLINE(Warning, TEXT("Steam achievements have not been configured in .ini")); return false; } FUniqueNetIdSteam SteamId(PlayerId); // check if this is our player (cannot report for someone else) if (SteamUser() == NULL || SteamUser()->GetSteamID() != SteamId) { // we don't have achievements UE_LOG_ONLINE(Warning, TEXT("Cannot clear Steam achievements for non-local player %s"), *PlayerId.ToString()); return false; } const TArray<FOnlineAchievement> * PlayerAch = PlayerAchievements.Find(SteamId); if (NULL == PlayerAch) { // achievements haven't been read for a player UE_LOG_ONLINE(Warning, TEXT("Steam achievements have not been read for player %s"), *PlayerId.ToString()); return false; } const int32 AchNum = PlayerAch->Num(); for (int32 AchIdx = 0; AchIdx < AchNum; ++AchIdx) { SteamUserStats()->ClearAchievement(TCHAR_TO_UTF8(*(*PlayerAch)[ AchIdx ].Id)); } // TODO: provide a separate method to just store stats? StatsInt->FlushLeaderboards(FName(TEXT("UNUSED"))); return true; };
SW_PY bool SetAchievement(const char* name) { return SteamUserStats()->SetAchievement(name); }
// Steam User Stats SW_PY bool ClearAchievement(const char* name) { return SteamUserStats()->ClearAchievement(name); }
SW_PY bool GetAchievement(const char* name) { bool achieved = false; SteamUserStats()->GetAchievement(name, &achieved); return achieved; }
SW_PY float GetStatFloat(const char* name) { float statval = 0; SteamUserStats()->GetStat(name, &statval); return statval; }
SW_PY int32 GetStatInt(const char* name) { int32 statval = 0; SteamUserStats()->GetStat(name, &statval); return statval; }
SW_PY bool ResetAllStats(bool achievesToo) { return SteamUserStats()->ResetAllStats(achievesToo); }
SW_PY bool RequestCurrentStats() { return SteamUserStats()->RequestCurrentStats(); }