Steamworks-dokumentaatio
Vaiheittaiset ohjeet: tilastot

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ä. Tässä on Steamworksin Spacewar-esimerkkisovelluksen tilastolista:
stats_spacewar.png

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; // Nykyinen sovellustunnus. Stat_t *m_pStats; // Tilastotiedot. int m_iNumStats; // Tilastojen määrä. bool m_bInitialized; // Onko RequestStats()-funktiota kutsuttu ja takaisinkutsu vastaanotettu? 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 mitään.
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() { // Is Steam latautunut? Jos ei, tietoja ei voi hakea. if ( NULL == SteamUserStats() || NULL == SteamUser() ) { return false; } // Onko käyttäjä kirjautunut sisään? Jos ei, tietoja ei voi hakea. if ( !SteamUser()->BLoggedOn() ) { return false; } // Pyytää käyttäjätilastoja. return SteamUserStats()->RequestCurrentStats(); }

StoreStats()

Parametrit - Ei mitään.
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 ); // Keskimääräinen tulos on laskettu valmiiksi. 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 ) { // Saatamme saada takaisinkutsuja muiden pelien tilastoista, ne ohitetaan. if ( m_iAppID == pCallback->m_nGameID ) { if ( k_EResultOK == pCallback->m_eResult ) { OutputDebugString( "Steamistä saadut saavutukset ja tilastot\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 ) { // Saatamme saada takaisinkutsuja muiden pelien tilastoista, ne ohitetaan. 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 asetettu tilasto rikkoi rajoitteen. Ne on peruttu, // ja arvot pitäisi nyt iteroida uudelleen, jotta ne pysyvät synkronoituina. OutputDebugString( "StoreStats - some failed to validate\n" ); // Luo tähän väärennetyn takaisinkutsun, jotta arvot ladataan uudelleen. 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 sisältää tietoja tilastoista ja niiden tilasta. 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"), }; // Tilasto-objektin globaali käyttöoikeus. CSteamStats* g_SteamStats = NULL; ...

Alustaminen

Koko Steam alustetaan kutsumalla SteamAPI_Init-funktiota. Sitä on kutsuttava ennen muita. Jos tämä kutsu onnistuu, luomme apuobjektin antamalla sille tilastotaulukon ja sen koon.
... // Alustetaan Steam. bool bRet = SteamAPI_Init(); // Luo SteamStats-objektin, jos Steam alustettiin onnistuneesti. if (bRet) { g_SteamStats = new CSteamStats(g_Stats, 6); } ...

Takaisinkutsujen käsittely

Jotta voidaan 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.
... // Sammutetaan Steam. SteamAPI_Shutdown(); // Poistetaan 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.