Johdanto
Näillä ohjeilla voit integroida Steamin perustilastoja sovellukseesi alle kymmenessä minuutissa, alle kymmenellä koodirivillä tietokantaasi.
Steamworks-sovelluskehityspaketissa on mainio
Spacewar-esimerkkisovellus, joka esittelee Steam-toiminnot koko laajuudessaan. Steamin toimintojen tarkastelu kannattaa aloittaa käytännössä esimerkkisovelluksesta. Selkeyden vuoksi tähän ohjeeseen on tiivistetty vain tarpeelliset Spacewarin, tilastojen ja saavutusten ohjelmointirajapintojen tiedot, joita tarvitaan Steam-tilastoja varten. Huomaa, että tilasto- ja saavutustiedoissa on paljon päällekkäisyyksiä. Jos integroit molemmat, huomaa, että monet kutsuista voi yhdistää.
Vaihe 1 – Pelitilastojen määrittäminen
Tilastot ovat sovelluskohtaisia, ja ne määritetään
Tilastojen määrittäminen -sivulla Steamworks-sovellushallinnan taustajärjestelmässä. Alla on lista Steamworksin Spacewar-esimerkkipelin tilastoista:
:
Vaihe 2 – Tilastojen toiminta lyhyesti
Seuraava koodi on pelistä riippumaton, ja se voidaan lisätä peliin haluamallasi tavalla. Luokka on täysin toimiva sellaisenaan, mutta sen voi helposti muokata muita tarpeita varten. Koodi on otettu suoraan Spacewar-esimerkkitiedostoista:
StatsAndAchievements.cpp/h
.
Otsikkotiedosto
Aluksi määritämme rakenteen, jolla säilytämme Steamistä haetut tilastotiedot. Määritä tilastotyypit näppärästi enum-muuttujina ja tuo makro tilastokohteiden luomiseksi. Nämä tiedot ovat suoraan yhteydessä
Tilastojen määritys -sivun tietoihin.
#define _STAT_ID( id,type,name ) { id, type, name, 0, 0, 0, 0 }
enum EStatTypes
{
STAT_INT = 0,
STAT_FLOAT = 1,
STAT_AVGRATE = 2,
};
struct Stat_t
{
int m_ID;
EStatTypes m_eStatType;
const char *m_pchStatName;
int m_iValue;
float m_flValue;
float m_flAvgNumerator;
float m_flAvgDenominator;
};
Seuraavaksi määritetään apuluokka, joka pakkaa kaikki Steam-tilastojen ohjelmointirajapintakutsut ja luo kaikki
Steam-takaisinkutsut.
class CSteamStats
{
private:
int64 m_iAppID; // Sovelluksen nykyinen sovellustunnus (AppID)
Stat_t *m_pStats; // Tilastotiedot
int m_iNumStats; // Tilastojen lukumäärä
bool m_bInitialized; // Olemmeko kutsuneet Request stats ja saaneet takaisinkutsun?
public:
CSteamStats(Stat_t *Stats, int NumStats);
~CSteamStats();
bool RequestStats();
bool StoreStats();
STEAM_CALLBACK( CSteamStats, OnUserStatsReceived, UserStatsReceived_t,
m_CallbackUserStatsReceived );
STEAM_CALLBACK( CSteamStats, OnUserStatsStored, UserStatsStored_t,
m_CallbackUserStatsStored );
};
Kooditiedosto
Konstruktori
Parametrit – Konstruktori saa parametrinaan osoittimen tilastotaulukkoon sekä taulukon pituuden. Taulukon muotoilua käsitellään emopelin koodissa myöhemmin.
Paluuarvot – Ei sovelleta.
Toiminta – Konstruktori alustaa useita jäseniä ja poimii parhaillaan käyttämämme sovellustunnuksen. Lisäksi se kytkee takaisinkutsumetodit käsittelemään Steamiin tehtyjä asynkronisia kutsuja. Lopuksi konstruktori kutsuu
RequestStats()
, jolla se noutaa senhetkisen käyttäjän tilasto- ja saavutustiedot.
CSteamStats::CSteamStats(Stat_t *Stats, int NumStats) :
m_iAppID( 0 ),
m_bInitialized( false ),
m_CallbackUserStatsReceived( this, &CSteamStats::OnUserStatsReceived ),
m_CallbackUserStatsStored( this, &CSteamStats::OnUserStatsStored )
{
m_iAppID = SteamUtils()->GetAppID();
m_pStats = Stats;
m_iNumStats = NumStats;
RequestStats();
}
RequestStats()
Parametrit – Ei ole.
Paluuarvot – Boolean-arvo, joka osoittaa, onnistuiko kutsu vai ei. Jos kutsu epäonnistui, Steamia ei todennäköisesti ole alustettu. Varmista, että sinulla on Steam-sovellus auki, kun yrität suorittaa kutsun, ja sitä ennen on kutsuttu
SteamAPI_Init.
Toiminta – Tämä metodi paketoi Steamille lähetettävän asynkronisen
ISteamUserStats::RequestCurrentStats-kutsun, jolla pyydetään nykyisen käyttäjän tilastoja. Tämä kutsu on suoritettava, ennen kuin tilastoja tai saavutuksia voidaan määrittää. Metodin alustava kutsu tehdään konstruktorissa. Jos haluat tarkistaa päivitettyjä tilastoja tai saavutuksia, voit kutsua sitä aina uudelleen.
bool CSteamStats::RequestStats()
{
// Onko Steam ladattu? Jos ei, emme voi hakea tilastoja.
if ( NULL == SteamUserStats() || NULL == SteamUser() )
{
return false;
}
// Onko käyttäjä kirjautuneena? Jos ei, emme voi hakea tilastoja.
if ( !SteamUser()->BLoggedOn() )
{
return false;
}
// Pyydä käyttäjätilastoja.
return SteamUserStats()->RequestCurrentStats();
}
StoreStats()
Parametrit – Ei ole.
Paluuarvot – Boolean-arvo, joka osoittaa, onnistuiko kutsu vai ei. Steamiä ei ole todennäköisesti alustettu, jos kutsu epäonnistui. Varmista, että sinulla on Steam-sovellus auki, kun yrität suorittaa kutsun, ja sitä ennen on kutsuttu
SteamAPI_Init.
Toiminta – Metodi käytännössä tekee kutsun
ISteamUserStats::StoreStats, joka on Steamille lähetettävä asynkroninen kutsu, jolla tallennetaan nykyisen käyttäjän tilastot palvelimelle. Kutsu tulee tehdä aina, kun haluat päivittää käyttäjän tilastoja.
bool CSteamStats::StoreStats()
{
if ( m_bInitialized )
{
// lataa tilastot
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 );
// Keskiarvotulos on laskettu.
SteamUserStats()->GetStat(stat.m_pchStatName, &stat.m_flValue );
break;
default:
break;
}
}
return SteamUserStats()->StoreStats();
}
}
OnUserStatsReceived()
Parametrit – Ei sovelleta.
Paluuarvot – Ei mitään.
Toiminta – Tämä metodi on takaisinkutsu, jota kutsutaan aina, kun yrität pyytää tilastoja. Tilastoja pyydetään käyttämällä
RequestStats()
. Metodi päivittää m_Stats-jäsenmuuttujan vastaamaan viimeisimpiä Steamistä palautettuja tilastotietoja.
void CSteamStats::OnUserStatsReceived( UserStatsReceived_t *pCallback )
{
// Muiden pelien tilastoilta voi tulla takaisinkutsuja. Ohita ne.
if ( m_iAppID == pCallback->m_nGameID )
{
if ( k_EResultOK == pCallback->m_eResult )
{
OutputDebugString( "Received stats and achievements from Steam\n" );
// lataa tilastot
for ( int iStat = 0; iStat < m_iNumStats; ++iStat )
{
Stat_t &stat = m_Stats[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 );
OutputDebugString( buffer );
}
}
}
OnUserStatsStored()
Parametrit – Ei sovelleta.
Paluuarvot – Ei mitään.
Toiminta – Tämä metodi on takaisinkutsu, jota kutsutaan aina, kun yrität tallentaa tilastoja Steamiin. Jos jotkin tilastoista, jotka yritimme määrittää, rikkoivat rajoitetta, ne palautetaan vanhaan arvoon, joten lataamme niiden arvot uudelleen.
void CSteamStats::OnUserStatsStored( UserStatsStored_t *pCallback )
{
// Muiden pelien tilastoilta voi tulla takaisinkutsuja. Ohita ne.
if ( m_iAppID == pCallback->m_nGameID )
{
if ( k_EResultOK == pCallback->m_eResult )
{
OutputDebugString( "StoreStats - success\n" );
}
else if ( k_EResultInvalidParam == pCallback->m_eResult )
{
// Yksi tai useampi määrittämistämme tilastoista rikkoi rajoitteen. Ne on palautettu,
// ja arvot tulisi iteroida uudelleen, jotta pysymme tahdistuksessa.
OutputDebugString( "StoreStats - some failed to validate\n" );
// Tee virheellinen takaisinkutsu tässä, jotta voimme ladata arvot uudestaan.
UserStatsReceived_t callback;
callback.m_eResult = k_EResultOK;
callback.m_nGameID = m_iAppID;
OnUserStatsReceived( &callback );
}
else
{
char buffer[128];
_snprintf( buffer, 128, "StoreStats - failed, %d\n", pCallback->m_eResult );
OutputDebugString( buffer );
}
}
}
Vaihe 3 – Integrointi peliin
Seuraavassa on täydellinen lista koodipätkistä, jotka sinun tulisi integroida asianmukaisiin kohtiin pelissä.
Määritykset ja globaalit muuttujat
Tässä on lista sisällytettävistä tiedoista, joita tarvitaan tilastojen, pelikohtaisen tilastotaulukon ja avustajaobjektin yleisosoittimen tekemiseen. Huomaa, että tilastot vastaavat Steamworksin hallintasivulla olevia.
...
#include "steam_api.h"
#include "isteamuserstats.h"
#include "SteamStats.h"
// Tilastotaulukko, joka säilyttää tilastotiedot ja niiden tilan
Stat_t g_Stats[] =
{
_STAT_ID( 1, STAT_INT, "NumGames"),
_STAT_ID( 2, STAT_INT, "NumWins"),
_STAT_ID( 3, STAT_INT, "NumLosses"),
_STAT_ID( 4, STAT_FLOAT, "FeetTraveled"),
_STAT_ID( 5, STAT_AVGRATE, "AverageSpeed"),
_STAT_ID( 7, STAT_FLOAT, "MaxFeetTraveled"),
};
// Yleisoikeudet tilastokohteeseen
CSteamStats* g_SteamStats = NULL;
...
Alustaminen
Koko Steam alustetaan kutsumalla
SteamAPI_Init. Sitä on kutsuttava ennen muita. Jos tämä kutsu onnistuu, luomme apuobjektin antamalla sille tilastotaulukon ja sen koon.
...
// Alusta Steam.
bool bRet = SteamAPI_Init();
// Luo SteamStats-objektit, jos Steamin alustus onnistui.
if (bRet)
{
g_SteamStats = new CSteamStats(g_Stats, 6);
}
...
Takaisinkutsujen käsittely
Jotta voimme varmistua, että kaikki Steam-takaisinkutsut tulevat käsitellyiksi, uusia viestejä on haettava säännöllisesti. Tämä saavutetaan lisäämällä tämä kutsu pelisilmukkaan.
...
SteamAPI_RunCallbacks();
...
Tilastojen tallentaminen
Tilastot tallennetaan suorittamalla yksittäisellä kutsulla
StoreStats()
.
...
if (g_SteamStats)
g_SteamStats->StoreStats();
...
Sammutus
Koodisi sisältää todennäköisesti jo
SteamAPI_Shutdown-funktion kutsun. Se sammuttaa Steamin. Koodia on kutsuttava ennen sovelluksen sulkeutumista. Lopuksi poistamme luomamme apuobjektin.
...
// Sulje Steam
SteamAPI_Shutdown();
// Poista SteamStats-objekti
if (g_SteamStats)
delete g_SteamStats;
...
Vaihe 4 – Testaus ja vianmääritys
Esimerkkikoodi tulostaa virheenkorjaustiedot debug-konsoliin, mikä voi auttaa ymmärtämään, mitkä kutsuista onnistuvat ja mitkä epäonnistuvat. Seuraavat ovat tyypillisiä virheilmoituksia ja korjausehdotuksia.
Sovelluksen käynnistyminen epäonnistui, koska steam_api.dll-tiedostoa ei löytynyt. Sovelluksen uudelleenkäynnistäminen voi korjata ongelman.Varmista, että steam_api.dll-tiedosto on samassa hakemistossa kuin suoritettava tiedosto.
[S_API FAIL] SteamAPI_Init() epäonnistui. Käynnissä olevaa Steamiä tai paikallista steamclient.dll-tiedostoa ei löytynyt.Sinulla ei todennäköisesti ole Steam-asiakasohjelma käynnissä. Käynnistä Steam ja kirjaudu sisään.
[S_API FAIL] SteamAPI_Init() epäonnistui. Sovellustunnusta ei löytynyt.Tiedosto steam_appid.txt ei todennäköisesti ole oikeassa paikassa. Lisää se lähdekansioon ja varmista, että siinä on sovellustunnusnumerosi.