2 #include <mysql/mysql.h>
12 uint32_t limit, uint32_t offset)
14 std::lock_guard<std::mutex> guard(this->
_mutex);
16 std::string query =
"";
18 query +=
" `rank`, `profileid`, `uniquenick`, `ratio`, `" + k +
"`, `" + s +
"` ";
20 query +=
" `Leaderboard_ratio_" + k +
"_" + s +
"` ";
22 query +=
" `rank` ASC, ";
23 query +=
" `ratio` DESC ";
24 query +=
"LIMIT ? OFFSET ?";
28 char output_uniquenick[VARCHAR_LEN(32)];
34 MYSQL_BIND* input_bind = (MYSQL_BIND *)calloc(2,
sizeof(MYSQL_BIND));
35 input_bind[0].buffer_type = MYSQL_TYPE_LONG;
36 input_bind[0].buffer = &limit;
37 input_bind[0].is_unsigned =
true;
38 input_bind[1].buffer_type = MYSQL_TYPE_LONG;
39 input_bind[1].buffer = &offset;
40 input_bind[1].is_unsigned =
true;
43 MYSQL_BIND* output_bind = (MYSQL_BIND *)calloc(6,
sizeof(MYSQL_BIND));
44 output_bind[0].buffer_type = MYSQL_TYPE_LONG;
45 output_bind[0].buffer = &output_rank;
46 output_bind[0].is_unsigned =
false;
47 output_bind[1].buffer_type = MYSQL_TYPE_LONG;
48 output_bind[1].buffer = &output_profileid;
49 output_bind[1].is_unsigned =
false;
50 output_bind[2].buffer_type = MYSQL_TYPE_VAR_STRING;
51 output_bind[2].buffer = &output_uniquenick;
52 output_bind[2].buffer_length = VARCHAR_LEN(32);
53 output_bind[3].buffer_type = MYSQL_TYPE_LONG;
54 output_bind[3].buffer = &output_ratio;
55 output_bind[3].is_unsigned =
false;
56 output_bind[4].buffer_type = MYSQL_TYPE_LONG;
57 output_bind[4].buffer = &output_k;
58 output_bind[4].is_unsigned =
true;
59 output_bind[5].buffer_type = MYSQL_TYPE_LONG;
60 output_bind[5].buffer = &output_s;
61 output_bind[5].is_unsigned =
true;
64 MYSQL_STMT* statement;
67 !this->
_init(&statement) ||
68 !this->
_prepare(statement, query, input_bind) ||
69 !this->
_execute(statement, output_bind)
82 int status = mysql_stmt_fetch(statement);
84 if (status == 1 || status == MYSQL_NO_DATA)
89 player.SetProfileId(output_profileid);
90 player.SetUniquenick(output_uniquenick);
92 auto it = Battlefield::PlayerStats::SetterMap.find(k);
93 if (it != Battlefield::PlayerStats::SetterMap.end()) {
94 (player.*(it->second))(output_k);
97 it = Battlefield::PlayerStats::SetterMap.find(s);
98 if (it != Battlefield::PlayerStats::SetterMap.end()) {
99 (player.*(it->second))(output_s);
102 rank_players.insert(std::make_pair(output_rank, player));
106 mysql_stmt_free_result(statement);
107 mysql_stmt_close(statement);
115 const std::string& s)
117 std::lock_guard<std::mutex> guard(this->
_mutex);
119 std::string query =
"";
120 query +=
"SELECT `rp`.* ";
122 query +=
" `Leaderboard_ratio_" + k +
"_" + s +
"` AS `rp` ";
125 query +=
" `profileid`, ";
126 query +=
" `rank` AS `start_rank` ";
128 query +=
" `Leaderboard_ratio_" + k +
"_" + s +
"` ";
130 query +=
" `profileid` = ? ";
131 query +=
") AS `start` ON rp.rank >= CASE WHEN start.start_rank <= 4 THEN 1 ELSE start.start_rank - 4 END ";
134 query +=
" `profileid`, ";
135 query +=
" `rank` AS `end_rank` ";
137 query +=
" `Leaderboard_ratio_" + k +
"_" + s +
"` ";
139 query +=
" `profileid` = ? ";
140 query +=
") AS `end` ON rp.rank <= CASE WHEN end.end_rank <= 4 THEN 10 ELSE end.end_rank + 5 END ";
141 query +=
"ORDER BY ";
142 query +=
" `rank` ASC, ";
143 query +=
" `ratio` DESC";
145 int input_profileid = profileid;
148 int output_profileid;
149 char output_uniquenick[VARCHAR_LEN(32)];
155 MYSQL_BIND* input_bind = (MYSQL_BIND *)calloc(2,
sizeof(MYSQL_BIND));
156 input_bind[0].buffer_type = MYSQL_TYPE_LONG;
157 input_bind[0].buffer = &input_profileid;
158 input_bind[0].is_unsigned =
false;
159 input_bind[1].buffer_type = MYSQL_TYPE_LONG;
160 input_bind[1].buffer = &input_profileid;
161 input_bind[1].is_unsigned =
false;
164 MYSQL_BIND* output_bind = (MYSQL_BIND *)calloc(6,
sizeof(MYSQL_BIND));
165 output_bind[0].buffer_type = MYSQL_TYPE_LONG;
166 output_bind[0].buffer = &output_rank;
167 output_bind[0].is_unsigned =
false;
168 output_bind[1].buffer_type = MYSQL_TYPE_LONG;
169 output_bind[1].buffer = &output_profileid;
170 output_bind[1].is_unsigned =
false;
171 output_bind[2].buffer_type = MYSQL_TYPE_VAR_STRING;
172 output_bind[2].buffer = &output_uniquenick;
173 output_bind[2].buffer_length = VARCHAR_LEN(32);
174 output_bind[3].buffer_type = MYSQL_TYPE_LONG;
175 output_bind[3].buffer = &output_ratio;
176 output_bind[3].is_unsigned =
false;
177 output_bind[4].buffer_type = MYSQL_TYPE_LONG;
178 output_bind[4].buffer = &output_k;
179 output_bind[4].is_unsigned =
true;
180 output_bind[5].buffer_type = MYSQL_TYPE_LONG;
181 output_bind[5].buffer = &output_s;
182 output_bind[5].is_unsigned =
true;
185 MYSQL_STMT* statement;
188 !this->
_init(&statement) ||
189 !this->
_prepare(statement, query, input_bind) ||
190 !this->
_execute(statement, output_bind)
203 int status = mysql_stmt_fetch(statement);
205 if (status == 1 || status == MYSQL_NO_DATA)
210 player.SetProfileId(output_profileid);
211 player.SetUniquenick(output_uniquenick);
213 auto it = Battlefield::PlayerStats::SetterMap.find(k);
214 if (it != Battlefield::PlayerStats::SetterMap.end()) {
215 (player.*(it->second))(output_k);
218 it = Battlefield::PlayerStats::SetterMap.find(s);
219 if (it != Battlefield::PlayerStats::SetterMap.end()) {
220 (player.*(it->second))(output_s);
223 rank_players.insert(std::make_pair(output_rank, player));
227 mysql_stmt_free_result(statement);
228 mysql_stmt_close(statement);
236 const std::string& k,
const std::string& s)
238 std::lock_guard<std::mutex> guard(this->
_mutex);
240 std::string query =
"";
242 query +=
" ROW_NUMBER() OVER (";
243 query +=
" ORDER BY ";
244 query +=
" PlayerStats." + k +
" / PlayerStats." + s +
" DESC ";
245 query +=
" ) AS `rank`, ";
246 query +=
" Players.profileid AS `profileid`, ";
247 query +=
" Players.uniquenick AS `uniquenick`, ";
248 query +=
" PlayerStats." + k +
" / PlayerStats." + s +
" AS `ratio`, ";
249 query +=
" PlayerStats." + k +
" AS `" + k +
"`, ";
250 query +=
" PlayerStats." + s +
" AS `" + s +
"` ";
252 query +=
" `Players`, ";
253 query +=
" `PlayerStats` ";
255 query +=
" Players.profileid = PlayerStats.profileid AND ";
256 query +=
" PlayerStats." + k +
" != 0 AND ";
257 query +=
" PlayerStats." + s +
" != 0 ";
259 query +=
" Players.profileid IN (" + Util::ToString(friends) +
") ";
260 query +=
"ORDER BY ";
261 query +=
" `rank` ASC, ";
262 query +=
" `ratio` DESC ";
263 query +=
"LIMIT 10;";
266 int output_profileid;
267 char output_uniquenick[VARCHAR_LEN(32)];
273 MYSQL_BIND* output_bind = (MYSQL_BIND *)calloc(6,
sizeof(MYSQL_BIND));
274 output_bind[0].buffer_type = MYSQL_TYPE_LONG;
275 output_bind[0].buffer = &output_rank;
276 output_bind[0].is_unsigned =
false;
277 output_bind[1].buffer_type = MYSQL_TYPE_LONG;
278 output_bind[1].buffer = &output_profileid;
279 output_bind[1].is_unsigned =
false;
280 output_bind[2].buffer_type = MYSQL_TYPE_VAR_STRING;
281 output_bind[2].buffer = &output_uniquenick;
282 output_bind[2].buffer_length = VARCHAR_LEN(32);
283 output_bind[3].buffer_type = MYSQL_TYPE_LONG;
284 output_bind[3].buffer = &output_ratio;
285 output_bind[3].is_unsigned =
false;
286 output_bind[4].buffer_type = MYSQL_TYPE_LONG;
287 output_bind[4].buffer = &output_k;
288 output_bind[4].is_unsigned =
true;
289 output_bind[5].buffer_type = MYSQL_TYPE_LONG;
290 output_bind[5].buffer = &output_s;
291 output_bind[5].is_unsigned =
true;
294 MYSQL_STMT* statement;
297 !this->
_init(&statement) ||
298 !this->
_prepare(statement, query) ||
299 !this->
_execute(statement, output_bind)
311 int status = mysql_stmt_fetch(statement);
313 if (status == 1 || status == MYSQL_NO_DATA)
318 player.SetProfileId(output_profileid);
319 player.SetUniquenick(output_uniquenick);
321 auto it = Battlefield::PlayerStats::SetterMap.find(k);
322 if (it != Battlefield::PlayerStats::SetterMap.end()) {
323 (player.*(it->second))(output_k);
326 it = Battlefield::PlayerStats::SetterMap.find(s);
327 if (it != Battlefield::PlayerStats::SetterMap.end()) {
328 (player.*(it->second))(output_s);
331 rank_players.insert(std::make_pair(output_rank, player));
335 mysql_stmt_free_result(statement);
336 mysql_stmt_close(statement);
Represents a player with extended statistics.
bool queryLeaderboardRatioByFriends(Battlefield::RankPlayers &rank_players, const std::vector< int > &friends, const std::string &k, const std::string &s)
Queries the leaderboard rank of players by kills-to-spawns ratio filtered by friends.
bool _prepare(MYSQL_STMT *statement, const std::string &query)
Prepares a MySQL statement with a query.
bool queryLeaderboardRatioByProfileid(Battlefield::RankPlayers &rank_players, int profileid, const std::string &k, const std::string &s)
Queries the leaderboard rank of players by kills-to-spawns ratio with a specified profile ID.
bool queryLeaderboardRatio(Battlefield::RankPlayers &rank_players, const std::string &k, const std::string &s, uint32_t limit=10, uint32_t offset=0)
Queries the leaderboard rank of players by kills-to-spawns ratio.
bool _init(MYSQL_STMT **statement)
Initializes a MySQL statement object.
bool _execute(MYSQL_STMT *statement)
Executes a prepared MySQL statement.
std::mutex _mutex
Mutex for thread-safe access to the database connection.