source: network-game/server/DataAccess.cpp@ a9a1295

Last change on this file since a9a1295 was 426fb84, checked in by Dmitry Portnoy <dmp1488@…>, 10 years ago

Save the actual time a game ends to the databse and send it to the client as part of a player's game history

  • Property mode set to 100644
File size: 8.0 KB
Line 
1#include "DataAccess.h"
2
3#include <iostream>
4#include <sstream>
5#include <cstdlib>
6#include <crypt.h>
7
8#include "LuaLoader.h"
9
10using namespace std;
11
12DataAccess::DataAccess()
13{
14 LuaLoader luaLoader;
15
16 string database, username, password;
17
18 if (luaLoader.runScript("db_settings.lua")) {
19 cout << "Loading settings" << endl;
20
21 database = luaLoader.getValue("database");
22 username = luaLoader.getValue("username");
23 password = luaLoader.getValue("password");
24
25 cout << database << endl;
26 cout << username << endl;
27 cout << password << endl;
28 } else {
29 cout << "Failed to load settings from lua script" << endl;
30 }
31
32 mysql_init(&mysql);
33 connection = mysql_real_connect(&mysql, "localhost", "pythonAdmin", "pyMaster09*", "pythondb", 0, 0, 0);
34
35 if (connection == NULL) {
36 cout << mysql_error(&mysql) << endl;
37 }else
38 cout << "Connection successful" << endl;
39}
40
41DataAccess::~DataAccess()
42{
43 mysql_close(connection);
44 mysql_close(&mysql);
45}
46
47int DataAccess::insertPlayer(string username, string password, Player::PlayerClass playerClass)
48{
49 ostringstream oss;
50
51 string salt = "$1$";
52 int random;
53 char chr;
54 for(int i=0; i<8; i++)
55 {
56 random = rand() % 62;
57 if (random < 26)
58 chr = (char)('a'+random);
59 else if (random < 52)
60 chr = (char)('A'+random-26);
61 else
62 chr = (char)('0'+random-52);
63 salt += chr;
64 }
65 salt += '$';
66
67 string encrypted(crypt(password.c_str(), salt.c_str()));
68
69 oss << "'" << username << "', '" << encrypted << "', " << playerClass;
70
71 return insert("users", "name, password, class", oss.str());
72}
73
74int DataAccess::updatePlayer(Player* p)
75{
76 ostringstream values, where;
77
78 values << "level=" << p->level << ", experience=" << p->experience << ", honor=" << p->honor << ", wins=" << p->wins << ", losses=" << p->losses << "";
79
80 where << "id=" << p->getId() << "";
81
82 return update("users", values.str(), where.str());
83}
84
85Player *DataAccess::getPlayer(string username)
86{
87 MYSQL_RES *result;
88 MYSQL_ROW row;
89 Player *p;
90 ostringstream oss;
91
92 oss << "name='" << username << "'";
93
94 result = select("users", oss.str().c_str());
95
96 cout << "Got result" << endl;
97
98 if (result == NULL) {
99 cout << "Error occured" << endl;
100 cout << mysql_error(connection) << endl;
101 return NULL;
102 }
103
104 if ( ( row = mysql_fetch_row(result)) != NULL ) {
105 cout << "Creating a new player" << endl;
106 p = new Player(string(row[1]), string(row[2]));
107 p->setId(atoi(row[0]));
108 if (row[3] == NULL) {
109 p->setClass(Player::CLASS_NONE);
110 cout << "Class from db was NULL" << endl;
111 }else {
112 p->setClass((Player::PlayerClass)atoi(row[3]));
113 cout << "Class from db: " << atoi(row[3]) << endl;
114 }
115 p->level = atoi(row[4]);
116 p->experience = atoi(row[5]);
117 p->honor = atoi(row[6]);
118 p->wins = atoi(row[7]);
119 p->losses = atoi(row[8]);
120 cout << "Player class: " << p->playerClass << endl;
121 cout << "level: " << p->level << endl;
122 cout << "experience: " << p->experience << endl;
123 cout << "honor: " << p->honor << endl;
124 cout << "wins: " << p->wins << endl;
125 cout << "losses: " << p->losses << endl;
126 cout << "Loaded player from db" << endl;
127 }else {
128 cout << "Returned no results for some reason" << endl;
129 p = NULL;
130 }
131
132 mysql_free_result(result);
133
134 return p;
135}
136
137bool DataAccess::verifyPassword(string password, string encrypted)
138{
139 string test(crypt(password.c_str(), encrypted.c_str()));
140
141 return encrypted.compare(test) == 0;
142}
143
144int* DataAccess::getPlayerRecord(int playerId) {
145 MYSQL_RES *result;
146 MYSQL_ROW row;
147 ostringstream oss;
148 int* record = new int[5];
149
150 oss << "id=" << playerId;
151 result = select("users", oss.str());
152
153 if ( ( row = mysql_fetch_row(result)) != NULL ) {
154 cout << "Retrieved player record successfully" << endl;
155 record[0] = atoi(row[4]); // level
156 record[1] = atoi(row[5]); // experience
157 record[2] = atoi(row[6]); // honor
158 record[3] = atoi(row[7]); // wins
159 record[4] = atoi(row[8]); // losses
160 cout << "record[0]:" << record[0] << endl;
161 cout << "record[1]:" << record[1] << endl;
162 cout << "record[2]:" << record[2] << endl;
163 cout << "record[3]:" << record[3] << endl;
164 cout << "record[4]:" << record[4] << endl;
165 }
166
167 if (result == NULL) {
168 cout << mysql_error(connection) << endl;
169 return NULL;
170 }
171
172 mysql_free_result(result);
173
174 return record;
175}
176
177int** DataAccess::getPlayerGameHistory(int playerId, unsigned int& numGames)
178{
179 // each array is the score for one game
180 // the columns are result, team, blue score, red score, and time the game ended
181 // for result 0 is defeat and 1 is victory
182 // for team, 1 is blue and 2 is red
183
184 MYSQL_RES *result;
185 MYSQL_ROW row;
186 ostringstream oss;
187
188 int** gameHistory;
189
190 oss << "user_id=" << playerId;
191 result = select("gameHistory", oss.str());
192
193 numGames = mysql_num_rows(result);
194 gameHistory = (int**)malloc(sizeof(int*)*numGames);
195 cout << "Result has " << numGames << " rows" << endl;
196
197 int i=0;
198 while ( ( row = mysql_fetch_row(result)) != NULL ) {
199 gameHistory[i] = new int[5];
200
201 int userTeam = atoi(row[2]);
202 int blueScore = atoi(row[3]);
203 int redScore = atoi(row[4]);
204 time_t timeFinished = atoi(row[5]);
205 int gameResult = -1;
206
207 if (blueScore == 3) {
208 if (userTeam == 1)
209 gameResult = 1;
210 else
211 gameResult = 0;
212 }else if (redScore == 3) {
213 if (userTeam == 2)
214 gameResult = 1;
215 else
216 gameResult = 0;
217 }else {
218 cout << "Recorded game has no team with 3 points" << endl;
219 }
220
221 gameHistory[i][0] = gameResult;
222 gameHistory[i][1] = userTeam;
223 gameHistory[i][2] = blueScore;
224 gameHistory[i][3] = redScore;
225 gameHistory[i][4] = timeFinished;
226
227 i++;
228 }
229
230 if (result == NULL) {
231 cout << mysql_error(connection) << endl;
232 return NULL;
233 }
234
235 mysql_free_result(result);
236
237 return gameHistory;
238}
239
240int DataAccess::saveGameHistory(int playerId, int team, int blueScore, int redScore, time_t timeFinished)
241{
242 ostringstream oss;
243
244 cout << "Saving game to db" << endl;
245 oss << playerId << ", " << team << ", " << blueScore << ", " << redScore << ", " << timeFinished;
246
247 return insert("gameHistory", "user_id, user_team, blue_score, red_score, time_finished", oss.str());
248}
249
250int DataAccess::insert(string table, string columns, string values)
251{
252 int query_state;
253 ostringstream oss;
254
255 if (connection == NULL) {
256 cout << "Error: non database connection exists" << endl;
257 return -1;
258 }
259
260 oss << "INSERT into " << table << " (" << columns << ") VALUES (" << values << ")";
261 cout << "query: " << oss.str() << endl;
262
263 query_state = mysql_query(connection, oss.str().c_str());
264
265 if (query_state != 0) {
266 cout << mysql_error(connection) << endl;
267 return -1;
268 }
269
270 return 0;
271}
272
273int DataAccess::update(string table, string values, string where)
274{
275 int query_state;
276 ostringstream oss;
277
278 if (connection == NULL) {
279 cout << "Error: no database connection exists" << endl;
280 return -1;
281 }
282
283 oss << "UPDATE " << table << " SET " << values << " WHERE " << where;
284 cout << "query: " << oss.str() << endl;
285
286 query_state = mysql_query(connection, oss.str().c_str());
287
288
289 if (query_state != 0) {
290 cout << mysql_error(connection) << endl;
291 return -1;
292 }
293
294 return 0;
295}
296
297MYSQL_RES *DataAccess::select(string table, string filter)
298{
299 int query_state;
300 ostringstream oss;
301
302 if (connection == NULL) {
303 cout << "Error: non database connection exists" << endl;
304 return NULL;
305 }
306
307 oss << "SELECT * FROM " << table;
308 if (!filter.empty())
309 oss << " WHERE " << filter;
310 cout << "executing select query: " << oss.str() << endl;
311
312 query_state = mysql_query(connection, oss.str().c_str());
313
314 if (query_state != 0) {
315 cout << mysql_error(connection) << endl;
316 return NULL;
317 }
318
319 return mysql_store_result(connection);
320}
Note: See TracBrowser for help on using the repository browser.