mirror of
https://github.com/blendogames/quadrilateralcowboy.git
synced 2024-11-10 06:41:36 +00:00
430 lines
9.3 KiB
C++
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
|