BF2MC-Matchmaker
player_friend.cpp
1 #include <iostream>
2 #include <mysql/mysql.h>
3 
4 #include <settings.h>
5 #include <logger.h>
6 #include <util.h>
7 
8 #include <database.h>
9 
11 {
12  std::lock_guard<std::mutex> guard(this->_mutex); // database lock
13 
14  std::string query = "";
15  query += "SELECT ";
16  query += " `profileid`, `target_profileid` ";
17  query += "FROM ";
18  query += " `PlayerFriends` ";
19  query += "WHERE ";
20  query += " `profileid` = ? ";
21  query += "OR ";
22  query += " `target_profileid` = ?";
23 
24  int input_profileid = player.GetProfileId();
25 
26  int output_profileid;
27  int output_target_profileid;
28 
29  // Allocate input binds
30  MYSQL_BIND* input_bind = (MYSQL_BIND *)calloc(2, sizeof(MYSQL_BIND));
31  input_bind[0].buffer_type = MYSQL_TYPE_LONG;
32  input_bind[0].buffer = &input_profileid;
33  input_bind[0].is_unsigned = false;
34  input_bind[1].buffer_type = MYSQL_TYPE_LONG;
35  input_bind[1].buffer = &input_profileid;
36  input_bind[1].is_unsigned = false;
37 
38  // Allocate output binds
39  MYSQL_BIND* output_bind = (MYSQL_BIND *)calloc(2, sizeof(MYSQL_BIND));
40  output_bind[0].buffer_type = MYSQL_TYPE_LONG;
41  output_bind[0].buffer = &output_profileid;
42  output_bind[0].is_unsigned = false;
43  output_bind[1].buffer_type = MYSQL_TYPE_LONG;
44  output_bind[1].buffer = &output_target_profileid;
45  output_bind[1].is_unsigned = false;
46 
47  // Prepare and execute with binds
48  MYSQL_STMT* statement;
49 
50  if(
51  !this->_init(&statement) ||
52  !this->_prepare(statement, query, input_bind) ||
53  !this->_execute(statement, output_bind)
54  )
55  {
56  // Cleanup
57  free(input_bind);
58  free(output_bind);
59 
60  return false;
61  }
62 
63  while(true)
64  {
65  int status = mysql_stmt_fetch(statement);
66 
67  if (status == 1 || status == MYSQL_NO_DATA)
68  break;
69 
70  int friend_profileid = (output_profileid == input_profileid) ? output_target_profileid : output_profileid;
71 
72  player.AddFriend(friend_profileid);
73  }
74 
75  // Cleanup
76  mysql_stmt_free_result(statement);
77  mysql_stmt_close(statement);
78  free(input_bind);
79  free(output_bind);
80 
81  return true;
82 }
83 
84 bool Database::insertPlayerFriend(const Battlefield::Player& player, const Battlefield::Player& target_player)
85 {
86  std::lock_guard<std::mutex> guard(this->_mutex); // database lock
87 
88  std::string query = "";
89  query += "INSERT INTO `PlayerFriends` ";
90  query += " (`profileid`, `target_profileid`) ";
91  query += "VALUES ";
92  query += " (?, ?)";
93 
94  int input_profileid = player.GetProfileId();
95  int input_target_profileid = target_player.GetProfileId();
96 
97  // Allocate input binds
98  MYSQL_BIND* input_bind = (MYSQL_BIND *)calloc(2, sizeof(MYSQL_BIND));
99  input_bind[0].buffer_type = MYSQL_TYPE_LONG;
100  input_bind[0].buffer = &input_profileid;
101  input_bind[0].is_unsigned = false;
102  input_bind[1].buffer_type = MYSQL_TYPE_LONG;
103  input_bind[1].buffer = &input_target_profileid;
104  input_bind[1].is_unsigned = false;
105 
106  // Prepare and execute with binds
107  MYSQL_STMT* statement;
108 
109  if(
110  !this->_init(&statement) ||
111  !this->_prepare(statement, query, input_bind) ||
112  !this->_execute(statement)
113  )
114  {
115  // Cleanup
116  free(input_bind);
117 
118  return false;
119  }
120 
121  // Cleanup
122  mysql_stmt_free_result(statement);
123  mysql_stmt_close(statement);
124  free(input_bind);
125 
126  return true;
127 }
128 
130 {
131  std::lock_guard<std::mutex> guard(this->_mutex); // database lock
132 
133  std::string query = "";
134  query += "DELETE FROM ";
135  query += " `PlayerFriends` ";
136  query += "WHERE ";
137  query += " (`profileid` = ? AND `target_profileid` = ?) ";
138  query += "OR ";
139  query += " (`target_profileid` = ? AND `profileid` = ?)";
140 
141  int input_profileid = player.GetProfileId();
142  int input_target_profileid = target_player.GetProfileId();
143 
144  // Allocate input binds
145  MYSQL_BIND* input_bind = (MYSQL_BIND *)calloc(4, 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_target_profileid;
151  input_bind[1].is_unsigned = false;
152  input_bind[2].buffer_type = MYSQL_TYPE_LONG;
153  input_bind[2].buffer = &input_profileid;
154  input_bind[2].is_unsigned = false;
155  input_bind[3].buffer_type = MYSQL_TYPE_LONG;
156  input_bind[3].buffer = &input_target_profileid;
157  input_bind[3].is_unsigned = false;
158 
159  // Prepare and execute with binds
160  MYSQL_STMT* statement;
161 
162  if(
163  !this->_init(&statement) ||
164  !this->_prepare(statement, query, input_bind) ||
165  !this->_execute(statement)
166  )
167  {
168  // Cleanup
169  free(input_bind);
170 
171  return false;
172  }
173 
174  // Cleanup
175  mysql_stmt_free_result(statement);
176  mysql_stmt_close(statement);
177  free(input_bind);
178 
179  return true;
180 }
Represents a player with extended statistics.
Definition: player.h:38
bool _prepare(MYSQL_STMT *statement, const std::string &query)
Prepares a MySQL statement with a query.
Definition: database.cpp:59
bool _init(MYSQL_STMT **statement)
Initializes a MySQL statement object.
Definition: database.cpp:45
bool insertPlayerFriend(const Battlefield::Player &player, const Battlefield::Player &target_player)
Inserts a friendship relation between two players into the database.
bool queryPlayerFriendsByProfileId(Battlefield::Player &player)
Queries a player's friends by their profile ID.
bool _execute(MYSQL_STMT *statement)
Executes a prepared MySQL statement.
Definition: database.cpp:94
bool removePlayerFriend(const Battlefield::Player &player, const Battlefield::Player &target_player)
Removes a friendship relation between two players from the database.
std::mutex _mutex
Mutex for thread-safe access to the database connection.
Definition: database.h:42