2 #include <mysql/mysql.h>
11 uint32_t limit, uint32_t offset)
13 std::lock_guard<std::mutex> guard(this->
_mutex);
15 std::string query =
"";
17 query +=
" `rank`, `profileid`, `uniquenick`, `" + type +
"` ";
19 query +=
" `Leaderboard_" + type +
"` ";
21 query +=
" `rank` ASC, ";
22 query +=
" `" + type +
"` DESC ";
23 query +=
"LIMIT ? OFFSET ?";
27 char output_uniquenick[VARCHAR_LEN(32)];
28 uint32_t output_value;
31 MYSQL_BIND* input_bind = (MYSQL_BIND *)calloc(2,
sizeof(MYSQL_BIND));
32 input_bind[0].buffer_type = MYSQL_TYPE_LONG;
33 input_bind[0].buffer = &limit;
34 input_bind[0].is_unsigned =
true;
35 input_bind[1].buffer_type = MYSQL_TYPE_LONG;
36 input_bind[1].buffer = &offset;
37 input_bind[1].is_unsigned =
true;
40 MYSQL_BIND* output_bind = (MYSQL_BIND *)calloc(4,
sizeof(MYSQL_BIND));
41 output_bind[0].buffer_type = MYSQL_TYPE_LONG;
42 output_bind[0].buffer = &output_rank;
43 output_bind[0].is_unsigned =
false;
44 output_bind[1].buffer_type = MYSQL_TYPE_LONG;
45 output_bind[1].buffer = &output_profileid;
46 output_bind[1].is_unsigned =
false;
47 output_bind[2].buffer_type = MYSQL_TYPE_VAR_STRING;
48 output_bind[2].buffer = &output_uniquenick;
49 output_bind[2].buffer_length = VARCHAR_LEN(32);
50 output_bind[3].buffer_type = MYSQL_TYPE_LONG;
51 output_bind[3].buffer = &output_value;
52 output_bind[3].is_unsigned =
true;
55 MYSQL_STMT* statement;
58 !this->
_init(&statement) ||
59 !this->
_prepare(statement, query, input_bind) ||
60 !this->
_execute(statement, output_bind)
73 int status = mysql_stmt_fetch(statement);
75 if (status == 1 || status == MYSQL_NO_DATA)
80 player.SetProfileId(output_profileid);
81 player.SetUniquenick(output_uniquenick);
85 player.SetScore(
static_cast<int32_t
>(output_value));
89 auto it = Battlefield::PlayerStats::SetterMap.find(type);
90 if (it != Battlefield::PlayerStats::SetterMap.end()) {
91 (player.*(it->second))(output_value);
95 rank_players.insert(std::make_pair(output_rank, player));
99 mysql_stmt_free_result(statement);
100 mysql_stmt_close(statement);
109 std::lock_guard<std::mutex> guard(this->
_mutex);
111 std::string query =
"";
112 query +=
"SELECT `rp`.* ";
114 query +=
" `Leaderboard_" + type +
"` AS `rp` ";
117 query +=
" `profileid`, ";
118 query +=
" `rank` AS `start_rank` ";
120 query +=
" `Leaderboard_" + type +
"` ";
122 query +=
" `profileid` = ? ";
123 query +=
") AS `start` ON rp.rank >= CASE WHEN start.start_rank <= 4 THEN 1 ELSE start.start_rank - 4 END ";
126 query +=
" `profileid`, ";
127 query +=
" `rank` AS `end_rank` ";
129 query +=
" `Leaderboard_" + type +
"` ";
131 query +=
" `profileid` = ? ";
132 query +=
") AS `end` ON rp.rank <= CASE WHEN end.end_rank <= 4 THEN 10 ELSE end.end_rank + 5 END ";
133 query +=
"ORDER BY ";
134 query +=
" `rank` ASC, ";
135 query +=
" `" + type +
"` DESC";
137 int input_profileid = profileid;
140 int output_profileid;
141 char output_uniquenick[VARCHAR_LEN(32)];
142 uint32_t output_value;
145 MYSQL_BIND* input_bind = (MYSQL_BIND *)calloc(2,
sizeof(MYSQL_BIND));
146 input_bind[0].buffer_type = MYSQL_TYPE_LONG;
147 input_bind[0].buffer = &input_profileid;
148 input_bind[0].is_unsigned =
false;
149 input_bind[1].buffer_type = MYSQL_TYPE_LONG;
150 input_bind[1].buffer = &input_profileid;
151 input_bind[1].is_unsigned =
false;
154 MYSQL_BIND* output_bind = (MYSQL_BIND *)calloc(4,
sizeof(MYSQL_BIND));
155 output_bind[0].buffer_type = MYSQL_TYPE_LONG;
156 output_bind[0].buffer = &output_rank;
157 output_bind[0].is_unsigned =
false;
158 output_bind[1].buffer_type = MYSQL_TYPE_LONG;
159 output_bind[1].buffer = &output_profileid;
160 output_bind[1].is_unsigned =
false;
161 output_bind[2].buffer_type = MYSQL_TYPE_VAR_STRING;
162 output_bind[2].buffer = &output_uniquenick;
163 output_bind[2].buffer_length = VARCHAR_LEN(32);
164 output_bind[3].buffer_type = MYSQL_TYPE_LONG;
165 output_bind[3].buffer = &output_value;
166 output_bind[3].is_unsigned =
true;
169 MYSQL_STMT* statement;
172 !this->
_init(&statement) ||
173 !this->
_prepare(statement, query, input_bind) ||
174 !this->
_execute(statement, output_bind)
187 int status = mysql_stmt_fetch(statement);
189 if (status == 1 || status == MYSQL_NO_DATA)
194 player.SetProfileId(output_profileid);
195 player.SetUniquenick(output_uniquenick);
199 player.SetScore(
static_cast<int32_t
>(output_value));
203 auto it = Battlefield::PlayerStats::SetterMap.find(type);
204 if (it != Battlefield::PlayerStats::SetterMap.end()) {
205 (player.*(it->second))(output_value);
209 rank_players.insert(std::make_pair(output_rank, player));
213 mysql_stmt_free_result(statement);
214 mysql_stmt_close(statement);
222 const std::vector<int>& friends)
224 std::lock_guard<std::mutex> guard(this->
_mutex);
226 std::string query =
"";
228 query +=
" ROW_NUMBER() OVER (";
229 query +=
" ORDER BY ";
230 query +=
" `" + type +
"` DESC ";
231 query +=
" ) AS `rank`, ";
232 query +=
" Players.profileid AS `profileid`, ";
233 query +=
" Players.uniquenick AS `uniquenick`, ";
234 query +=
" PlayerStats." + type +
" AS '" + type +
"' ";
236 query +=
" `Players`, ";
237 query +=
" `PlayerStats` ";
239 query +=
" Players.profileid = PlayerStats.profileid ";
241 query +=
" Players.profileid IN (" + Util::ToString(friends) +
") ";
242 query +=
"ORDER BY ";
243 query +=
" `rank` ASC, ";
244 query +=
" `" + type +
"` DESC ";
245 query +=
"LIMIT 10;";
248 int output_profileid;
249 char output_uniquenick[VARCHAR_LEN(32)];
250 uint32_t output_value;
253 MYSQL_BIND* output_bind = (MYSQL_BIND *)calloc(4,
sizeof(MYSQL_BIND));
254 output_bind[0].buffer_type = MYSQL_TYPE_LONG;
255 output_bind[0].buffer = &output_rank;
256 output_bind[0].is_unsigned =
false;
257 output_bind[1].buffer_type = MYSQL_TYPE_LONG;
258 output_bind[1].buffer = &output_profileid;
259 output_bind[1].is_unsigned =
false;
260 output_bind[2].buffer_type = MYSQL_TYPE_VAR_STRING;
261 output_bind[2].buffer = &output_uniquenick;
262 output_bind[2].buffer_length = VARCHAR_LEN(32);
263 output_bind[3].buffer_type = MYSQL_TYPE_LONG;
264 output_bind[3].buffer = &output_value;
265 output_bind[3].is_unsigned =
true;
268 MYSQL_STMT* statement;
270 !this->
_init(&statement) ||
271 !this->
_prepare(statement, query) ||
272 !this->
_execute(statement, output_bind)
284 int status = mysql_stmt_fetch(statement);
286 if (status == 1 || status == MYSQL_NO_DATA)
291 player.SetProfileId(output_profileid);
292 player.SetUniquenick(output_uniquenick);
296 player.SetScore(
static_cast<int32_t
>(output_value));
300 auto it = Battlefield::PlayerStats::SetterMap.find(type);
301 if (it != Battlefield::PlayerStats::SetterMap.end()) {
302 (player.*(it->second))(output_value);
306 rank_players.insert(std::make_pair(output_rank, player));
310 mysql_stmt_free_result(statement);
311 mysql_stmt_close(statement);
Represents a player with extended statistics.
bool queryLeaderboardTypeByFriends(Battlefield::RankPlayers &rank_players, const std::string &type, const std::vector< int > &friends)
Queries the leaderboard rank of players by player stat type filtered by friends.
bool _prepare(MYSQL_STMT *statement, const std::string &query)
Prepares a MySQL statement with a query.
bool _init(MYSQL_STMT **statement)
Initializes a MySQL statement object.
bool queryLeaderboardTypeByProfileid(Battlefield::RankPlayers &rank_players, const std::string &type, int profileid)
Queries the leaderboard rank of players by player stat type with a profile ID in the middle.
bool _execute(MYSQL_STMT *statement)
Executes a prepared MySQL statement.
bool queryLeaderboardType(Battlefield::RankPlayers &rank_players, const std::string &type, uint32_t limit=10, uint32_t offset=0)
Queries the leaderboard rank of players by player stat type.
std::mutex _mutex
Mutex for thread-safe access to the database connection.