quadrilateralcowboy/d3xp/steamstats.cpp

430 lines
9.3 KiB
C++

#include "../idlib/precompiled.h"
#pragma hdrstop
#ifdef STEAM
#include "steam_api.h"
#include "isteamuserstats.h"
#include "steamstats.h"
#include "Game_local.h"
// index // stat type // statname on admin page.
//NOTE this list has to retain the exact same order as the Steam admin page.
Stat_t g_Stats[] =
{
_STAT_ID( 20, STAT_INT, "time_val_0"),
_STAT_ID( 32, STAT_INT, "attempts_val_0"),
_STAT_ID( 33, STAT_INT, "attempts_satsuma_0"),
_STAT_ID( 37, STAT_INT, "attempts_satsuma_1"),
_STAT_ID( 38, STAT_INT, "attempts_satsuma_2"),
_STAT_ID( 48, STAT_INT, "attempts_funi_0"),
_STAT_ID( 49, STAT_INT, "attempts_funi_1"),
_STAT_ID( 50, STAT_INT, "attempts_funi_2"),
_STAT_ID( 51, STAT_INT, "attempts_towers2_0"),
_STAT_ID( 52, STAT_INT, "attempts_towers2_1"),
_STAT_ID( 53, STAT_INT, "attempts_towers2_2"),
_STAT_ID( 54, STAT_INT, "attempts_villa_0"),
_STAT_ID( 55, STAT_INT, "attempts_villa_1"),
_STAT_ID( 56, STAT_INT, "attempts_villa_2"),
_STAT_ID( 34, STAT_INT, "time_satsuma_0"),
_STAT_ID( 35, STAT_INT, "time_satsuma_1"),
_STAT_ID( 36, STAT_INT, "time_satsuma_2"),
_STAT_ID( 42, STAT_INT, "time_funi_0"),
_STAT_ID( 43, STAT_INT, "time_funi_1"),
_STAT_ID( 44, STAT_INT, "time_funi_2"),
_STAT_ID( 45, STAT_INT, "time_towers2_0"),
_STAT_ID( 46, STAT_INT, "time_towers2_1"),
_STAT_ID( 47, STAT_INT, "time_towers2_2"),
_STAT_ID( 39, STAT_INT, "time_villa_0"),
_STAT_ID( 40, STAT_INT, "time_villa_1"),
_STAT_ID( 41, STAT_INT, "time_villa_2"),
_STAT_ID( 21, STAT_INT, "stat_deckcommands"),
_STAT_ID( 22, STAT_INT, "stat_death_oxygen"),
_STAT_ID( 23, STAT_INT, "stat_death_other"),
_STAT_ID( 24, STAT_INT, "stat_launches_player"),
_STAT_ID( 25, STAT_INT, "stat_throws"),
_STAT_ID( 26, STAT_INT, "stat_clambers"),
_STAT_ID( 27, STAT_INT, "stat_glassbreaks"),
_STAT_ID( 28, STAT_INT, "stat_stickynotes"),
_STAT_ID( 29, STAT_INT, "stat_buzzsaws"),
_STAT_ID( 30, STAT_INT, "stat_screws"),
_STAT_ID( 31, STAT_INT, "stat_bugreports"),
};
// Global access to Stats Object
CSteamStats* g_SteamStats = NULL;
CSteamStats::CSteamStats(Stat_t *Stats) :
m_iAppID( 0 ),
m_bInitialized( false ),
m_CallbackUserStatsReceived( this, &CSteamStats::OnUserStatsReceived ),
m_CallbackUserStatsStored( this, &CSteamStats::OnUserStatsStored )
{
int numStats = sizeof(g_Stats) / sizeof(g_Stats[0]);
m_iAppID = SteamUtils()->GetAppID();
m_pStats = Stats;
m_iNumStats = numStats;
RequestStats();
}
CSteamStats::~CSteamStats()
{
m_CallbackUserStatsReceived.Unregister();
m_CallbackUserStatsStored.Unregister();
}
void CSteamStats::ResetStats()
{
if (SteamUserStats()->ResetAllStats(true))
{
common->Printf("STEAM: STATS RESET.\n");
}
}
int CSteamStats::GetNumStats()
{
return (sizeof(g_Stats) / sizeof(g_Stats[0]));
}
bool CSteamStats::RequestStats()
{
// Is Steam loaded? If not we can't get stats.
if ( NULL == SteamUserStats() || NULL == SteamUser() )
{
common->Warning("STEAM: Steam is not loaded. (RequestStats)");
return false;
}
// Is the user logged on? If not we can't get stats.
if ( !SteamUser()->BLoggedOn() )
{
common->Warning("STEAM: User not logged on. (RequestStats)");
return false;
}
// Request user stats.
if (!SteamUserStats()->RequestCurrentStats())
{
common->Warning("STEAM: problem requesting stats (RequestStats).\n");
return false;
}
common->Printf("STEAM: recieved stats. (RequestStats)\n");
return true;
}
bool CSteamStats::RequestUserStats(CSteamID id)
{
// Is Steam loaded? If not we can't get stats.
if ( NULL == SteamUserStats() || NULL == SteamUser() )
{
common->Warning("STEAM: Steam is not loaded. (RequestUserStats)");
return false;
}
// Is the user logged on? If not we can't get stats.
if ( !SteamUser()->BLoggedOn() )
{
common->Warning("STEAM: User not logged on. (RequestUserStats)");
return false;
}
// Request user stats.
if (!SteamUserStats()->RequestUserStats(id))
{
common->Warning("STEAM: problem requesting stats (RequestUserStats).\n");
return false;
}
return true;
}
void CSteamStats::RequestGlobalStats()
{
SteamAPICall_t hSteamAPICall = SteamUserStats()->RequestGlobalStats(0);
m_SteamCallResultRequestGlobalStats.Set( hSteamAPICall, this, &CSteamStats::OnRequestGlobalStats );
}
void CSteamStats::OnRequestGlobalStats(GlobalStatsReceived_t *pResult, bool bIOFailure)
{
if (pResult->m_eResult != k_EResultOK)
{
common->Warning("STEAM: failed to request global stats. Result = %d\n", (int)pResult->m_eResult);
return;
}
//success.
/*
int64 output;
GetGlobalStat("m0j0_time", output);
common->Printf("%d\n", output);*/
}
//GLOBAL STATS.
bool CSteamStats::GetGlobalStat(const char *statname, int &output)
{
if (!gameLocal.steamInitialized)
{
common->Warning("STEAM: Steam is not initialized. (GetGlobalStat)");
return false;
}
int64 value;
if (!SteamUserStats()->GetGlobalStat(statname, &value))
{
common->Warning("STEAM: failed to get global stat (GetGlobalStat): %s\n", statname);
return false;
}
//success.
output = value;
return true;
}
bool CSteamStats::GetStat(const char *statname, int &value )
{
if (!gameLocal.steamInitialized)
{
return false;
}
if (!SteamUserStats()->GetStat(statname, &value))
{
common->Warning("STEAM: failed to get stat.\n");
return false;
}
return true;
}
bool CSteamStats::SetStatDelta(const char *statname, int delta )
{
if (!gameLocal.steamInitialized)
{
return false;
}
if (!m_bInitialized)
{
common->Warning("STEAM: cannot set stat before stat initialization. (SetStatDelta)");
return false;
}
for (int i = 0; i < m_iNumStats; i++)
{
if ( idStr::Icmp(g_Stats[i].m_pchStatName, statname) == 0)
{
g_Stats[i].m_iValue += delta;
return SetStat(statname, g_Stats[i].m_iValue);
}
}
return false;
}
bool CSteamStats::SetStat(const char *statname, int value )
{
if (!gameLocal.steamInitialized)
{
return false;
}
if (!m_bInitialized)
{
common->Warning("STEAM: cannot set stat before stat initialization. (SetStat)");
return false;
}
if (!SteamUserStats()->SetStat(statname, value))
{
common->Warning("STEAM: failed to set stat: %s (SetStat)", statname);
return false;
}
if (!SteamUserStats()->StoreStats())
{
common->Warning("STEAM: failed to store stat. (SetStat)\n");
return false;
}
return true;
}
//Store user stats.
bool CSteamStats::StoreStats()
{
if ( !m_bInitialized )
{
common->Warning("STEAM: Steam is not initialized. (StoreStats)");
return false;
}
// load stats
int m_NumStats = sizeof(g_Stats) / sizeof(g_Stats[0]);
for ( int iStat = 0; iStat < m_NumStats; ++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 );
SteamUserStats()->GetStat(stat.m_pchStatName, &stat.m_flValue );
break;
default:
break;
}
}
if (!SteamUserStats()->StoreStats())
{
common->Warning("STEAM: problem storing stats (StoreStats).\n");
return false;
}
return true;
}
//Retrieve user stats.
void CSteamStats::OnUserStatsReceived( UserStatsReceived_t *pCallback )
{
if (m_iAppID != pCallback->m_nGameID)
{
//app id doesn't match.
return;
}
if ( k_EResultOK != pCallback->m_eResult )
{
common->Warning("STEAM: Failed to receive stats. (OnUserStatsReceived)");
return;
}
for (int i = 0; i < m_iNumStats; i++)
{
Stat_t &stat = g_Stats[i];
switch (stat.m_eStatType)
{
case STAT_INT:
SteamUserStats()->GetStat(stat.m_pchStatName, &stat.m_iValue);
//common->Printf("STEAM: Stat received (int): %s = %d\n", stat.m_pchStatName, stat.m_iValue);
break;
case STAT_FLOAT:
case STAT_AVGRATE:
SteamUserStats()->GetStat(stat.m_pchStatName, &stat.m_flValue);
//common->Printf("STEAM: Stat received (float): %s = %f\n",stat.m_pchStatName, stat.m_flValue);
break;
default:
break;
}
}
//common->Printf("STEAM: Received stats.\n");
m_bInitialized = true;
}
void CSteamStats::OnUserStatsStored( UserStatsStored_t *pCallback )
{
if ( m_iAppID != pCallback->m_nGameID )
{
return;
}
if ( k_EResultInvalidParam == pCallback->m_eResult )
{
// One or more stats we set broke a constraint. They've been reverted,
// and we should re-iterate the values now to keep in sync.
common->Warning("STEAM: StoreStats - some failed to validate\n" );
// Fake up a callback here so that we re-load the values.
UserStatsReceived_t callback;
callback.m_eResult = k_EResultOK;
callback.m_nGameID = m_iAppID;
OnUserStatsReceived( &callback );
}
}
bool CSteamStats::GetUserStat(CSteamID id, const char *statname, int &value)
{
return SteamUserStats()->GetUserStat(id, statname, &value);
}
bool CSteamStats::SetAchievement(const char *achievementName)
{
if (g_skill.GetInteger() <= 0)
{
return false;
}
idPlayer *player;
player = gameLocal.GetLocalPlayer();
if (!player)
{
return false;
}
if ( player->godmode || player->noclip )
{
return false;
}
if (!SteamUserStats()->SetAchievement(achievementName))
{
common->Warning("STEAM: failed to set achievement. (SetAchievement)\n");
return false;
}
if (!SteamUserStats()->StoreStats())
{
common->Warning("STEAM: failed to store stat. (SetAchievement)\n");
return false;
}
return true;
}
#endif