-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathSteamLeaderboards.cpp
More file actions
156 lines (136 loc) · 5.63 KB
/
SteamLeaderboards.cpp
File metadata and controls
156 lines (136 loc) · 5.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//
// AGSteam: Steam API Plugin for AGS
// (C) 2011-2017 MonkeyMoto Productions, Inc.
//
// NOTICE: This file contains references to the Steamworks API. See the included
// LICENSE file for details and restrictions on using this file.
#include <algorithm>
#include <vector>
#include "ags2client/IAGS2Client.h"
#include "SteamLeaderboards.h"
#include "steam/steam_api.h"
#include "ags2client/Cpp11Fix.h"
using namespace AGSteam::Plugin;
struct LeaderboardListener
{
private:
friend SteamLeaderboards_Statics;
#ifdef AGS2CLIENT_HAS_CPP11
LeaderboardListener() = default;
#else
LeaderboardListener() {};
#endif // AGS2CLIENT_HAS_CPP11
public:
static LeaderboardListener& GetLeaderboardListener() noexcept;
#define LEADERBOARD_LISTENER_CALLRESULT(thisclass, func, param, var) CCallResult<thisclass, param> var; void func(param *pParam, bool bIOFailure)
LEADERBOARD_LISTENER_CALLRESULT(LeaderboardListener, OnFindLeaderboard, LeaderboardFindResult_t, CallResultFindLeaderboard);
LEADERBOARD_LISTENER_CALLRESULT(LeaderboardListener, OnUploadScore, LeaderboardScoreUploaded_t, CallResultUploadScore);
LEADERBOARD_LISTENER_CALLRESULT(LeaderboardListener, OnDownloadScore, LeaderboardScoresDownloaded_t, CallResultDownloadScore);
#undef LEADERBOARD_LISTENER_CALLRESULT
};
namespace AGSteam
{
namespace Plugin
{
struct SteamLeaderboards_Statics
{
public:
static LeaderboardListener LISTENER;
static SteamLeaderboards LEADERBOARDS;
};
}
}
LeaderboardListener SteamLeaderboards_Statics::LISTENER;
SteamLeaderboards SteamLeaderboards_Statics::LEADERBOARDS;
LeaderboardListener& LeaderboardListener::GetLeaderboardListener() noexcept
{
return SteamLeaderboards_Statics::LISTENER;
}
static struct
{
bool HasLeaderboard;
SteamLeaderboard_t CurrentLeaderboard;
std::vector<LeaderboardEntry_t> Entries;
int Limit;
ELeaderboardDataRequest Type;
} leaderboard;
SteamLeaderboards& SteamLeaderboards::GetSteamLeaderboards() noexcept
{
return SteamLeaderboards_Statics::LEADERBOARDS;
}
void SteamLeaderboards::RequestLeaderboard(char const *leaderboardName, AGS2Client::LeaderboardScore::Type type, int limit) const noexcept
{
if (leaderboardName == nullptr) return;
leaderboard.HasLeaderboard = false;
leaderboard.Entries.clear();
leaderboard.Limit = limit;
leaderboard.Type = static_cast<ELeaderboardDataRequest>(type);
LeaderboardListener &listener = LeaderboardListener::GetLeaderboardListener();
listener.CallResultFindLeaderboard.Set(SteamUserStats()->FindLeaderboard(leaderboardName), &listener, &LeaderboardListener::OnFindLeaderboard);
}
extern "C" void SteamLeaderboards_FindLeaderboard(char const *leaderboardName)
{
SteamLeaderboards::GetSteamLeaderboards().RequestLeaderboard(nullptr, AGS2Client::LeaderboardScore::AroundUser, 10);
}
void LeaderboardListener::OnUploadScore(LeaderboardScoreUploaded_t *callback, bool IOFailure)
{
}
void LeaderboardListener::OnFindLeaderboard(LeaderboardFindResult_t *callback, bool IOFailure)
{
// see if there was an error
if ((!callback->m_bLeaderboardFound) || (IOFailure)) return;
leaderboard.HasLeaderboard = true;
leaderboard.CurrentLeaderboard = callback->m_hSteamLeaderboard;
int rangeStart = 1;
int rangeEnd = std::min(SteamUserStats()->GetLeaderboardEntryCount(leaderboard.CurrentLeaderboard), leaderboard.Limit);
if (leaderboard.Type == k_ELeaderboardDataRequestGlobalAroundUser)
{
rangeStart = -(rangeEnd / 2) + !(rangeEnd % 2);
rangeEnd = -rangeStart + 1;
}
CallResultDownloadScore.Set(SteamUserStats()->DownloadLeaderboardEntries(leaderboard.CurrentLeaderboard, static_cast<ELeaderboardDataRequest>(0), rangeStart, rangeEnd),
&LeaderboardListener::GetLeaderboardListener(), &LeaderboardListener::OnDownloadScore);
}
void LeaderboardListener::OnDownloadScore(LeaderboardScoresDownloaded_t *callback, bool IOFailure)
{
if (IOFailure) return;
leaderboard.Entries.reserve(callback->m_cEntryCount);
LeaderboardEntry_t entry;
for (int i = 0; i < callback->m_cEntryCount; ++i)
{
SteamUserStats()->GetDownloadedLeaderboardEntry(callback->m_hSteamLeaderboardEntries, i, &entry, nullptr, 0);
leaderboard.Entries.push_back(entry);
}
}
bool SteamLeaderboard_HasValidLeaderboardInfo(int *index) noexcept
{
return ((AGS2Client::GetClient()->IsInitialized()) && (leaderboard.HasLeaderboard) &&
((index == nullptr) || (((*index) >= 0) && ((*index) < static_cast<int>(leaderboard.Entries.size())) && (leaderboard.Entries[*index].m_steamIDUser.IsValid()))));
}
bool SteamLeaderboards::UploadScore(int score) const noexcept
{
if (!SteamLeaderboard_HasValidLeaderboardInfo(nullptr)) return false;
LeaderboardListener &listener = LeaderboardListener::GetLeaderboardListener();
listener.CallResultUploadScore.Set(SteamUserStats()->UploadLeaderboardScore(leaderboard.CurrentLeaderboard,
k_ELeaderboardUploadScoreMethodKeepBest, static_cast<int32>(score), nullptr, 0), &listener, &LeaderboardListener::OnUploadScore);
return true;
}
char const* SteamLeaderboards::GetCurrentLeaderboardName() const noexcept
{
if (!SteamLeaderboard_HasValidLeaderboardInfo(nullptr)) return nullptr;
return SteamUserStats()->GetLeaderboardName(leaderboard.CurrentLeaderboard);
}
char const* SteamLeaderboards::GetLeaderName(int index) const noexcept
{
if (!SteamLeaderboard_HasValidLeaderboardInfo(&index)) return nullptr;
return SteamFriends()->GetFriendPersonaName(leaderboard.Entries[index].m_steamIDUser);
}
int SteamLeaderboards::GetLeaderScore(int index) const noexcept
{
if (!SteamLeaderboard_HasValidLeaderboardInfo(&index)) return 0;
return static_cast<int>(leaderboard.Entries[index].m_nScore);
}
int SteamLeaderboards::GetLeaderCount() const noexcept
{
return leaderboard.Entries.size();
}