source: network-game/server/server.cpp@ 41ad8ed

Last change on this file since 41ad8ed was 41ad8ed, checked in by dportnoy <dmp1488@…>, 12 years ago

The server properly handles registration messages

  • Property mode set to 100644
File size: 6.9 KB
Line 
1#include "../common/compiler.h"
2
3#include <cstdlib>
4#include <cstdio>
5#include <unistd.h>
6#include <string>
7#include <iostream>
8#include <vector>
9#include <algorithm>
10
11#include <fcntl.h>
12#include <assert.h>
13
14#include <sys/socket.h>
15#include <netdb.h>
16#include <netinet/in.h>
17#include <arpa/inet.h>
18
19#include <openssl/bio.h>
20#include <openssl/ssl.h>
21#include <openssl/err.h>
22
23#include "Player.h"
24#include "DataAccess.h"
25#include "../common/message.h"
26
27using namespace std;
28
29void processMessage(const NETWORK_MSG &clientMsg, const struct sockaddr_in &from, vector<Player> &vctPlayers, int &num, NETWORK_MSG &serverMsg);
30
31// this should probably go somewhere in the common folder
32void error(const char *msg)
33{
34 perror(msg);
35 exit(0);
36}
37
38Player *findPlayerByName(vector<Player> &vec, string name)
39{
40 vector<Player>::iterator it;
41
42 cout << "Entered findPlayerByName" << endl;
43
44 for (it = vec.begin(); it != vec.end(); it++)
45 {
46 cout << "Comparing name" << endl;
47 if ( it->name.compare(name) == 0 )
48 return &(*it);
49 }
50
51 cout << "About to return" << endl;
52 return NULL;
53}
54
55Player *findPlayerByAddr(vector<Player> &vec, const sockaddr_in &addr)
56{
57 vector<Player>::iterator it;
58
59 for (it = vec.begin(); it != vec.end(); it++)
60 {
61 if ( it->addr.sin_addr.s_addr == addr.sin_addr.s_addr &&
62 it->addr.sin_port == addr.sin_port )
63 return &(*it);
64 }
65
66 return NULL;
67}
68
69void set_nonblock(int sock)
70{
71 int flags;
72 flags = fcntl(sock, F_GETFL,0);
73 assert(flags != -1);
74 fcntl(sock, F_SETFL, flags | O_NONBLOCK);
75}
76
77int main(int argc, char *argv[])
78{
79 int sock, length, n;
80 struct sockaddr_in server;
81 struct sockaddr_in from; // holds the info on the connected client
82 NETWORK_MSG clientMsg, serverMsg;
83 vector<Player> vctPlayers;
84
85 srand(time(NULL));
86 int num = 500;
87 //int num = (rand() % 0) + 1;
88
89 cout << "num: " << num << endl;
90
91 SSL_load_error_strings();
92 ERR_load_BIO_strings();
93 OpenSSL_add_all_algorithms();
94
95 if (argc < 2) {
96 cerr << "ERROR, no port provided" << endl;
97 exit(1);
98 }
99
100 sock = socket(AF_INET, SOCK_DGRAM, 0);
101 if (sock < 0) error("Opening socket");
102 length = sizeof(server);
103 bzero(&server,length);
104 server.sin_family=AF_INET;
105 server.sin_port=htons(atoi(argv[1]));
106 server.sin_addr.s_addr=INADDR_ANY;
107 if ( bind(sock, (struct sockaddr *)&server, length) < 0 )
108 error("binding");
109
110 set_nonblock(sock);
111
112 while (true) {
113
114 usleep(5000);
115
116 n = receiveMessage(&clientMsg, sock, &from);
117
118 if (n >= 0) {
119 cout << "Got a message" << endl;
120
121 processMessage(clientMsg, from, vctPlayers, num, serverMsg);
122
123 cout << "msg: " << serverMsg.buffer << endl;
124
125 n = sendMessage(&serverMsg, sock, &from);
126 if (n < 0)
127 error("sendMessage");
128 }
129
130 }
131
132 return 0;
133}
134
135void processMessage(const NETWORK_MSG &clientMsg, const struct sockaddr_in &from, vector<Player> &vctPlayers, int &num, NETWORK_MSG &serverMsg)
136{
137 DataAccess da;
138
139 cout << "ip address: " << inet_ntoa(from.sin_addr) << endl;
140 cout << "port: " << from.sin_port << endl;
141 cout << "MSG: type: " << clientMsg.type << endl;
142 cout << "MSG contents: " << clientMsg.buffer << endl;
143
144 // Check that if an invalid message is sent, the client will correctly
145 // receive and display the response. Maybe make a special error msg type
146 switch(clientMsg.type)
147 {
148 case MSG_TYPE_REGISTER:
149 {
150 string username(clientMsg.buffer);
151 string password(strchr(clientMsg.buffer, '\0')+1);
152
153 cout << "username: " << username << endl;
154 cout << "password: " << password << endl;
155
156 da.insertPlayer(username, password);
157
158 strcpy(serverMsg.buffer, "Registration successful");
159
160 serverMsg.type = MSG_TYPE_REGISTER;
161
162 break;
163 }
164 case MSG_TYPE_LOGIN:
165 {
166 string username(clientMsg.buffer);
167 string password(strchr(clientMsg.buffer, '\0')+1);
168 cout << "Player logging in: " << username << endl;
169
170 Player* p = da.getPlayer(username);
171
172 if (p == NULL || p->password != password)
173 {
174 if (p != NULL)
175 {
176 cout << "p->password: " << p->password << endl;
177 cout << "password: " << password << endl;
178 }
179 strcpy(serverMsg.buffer, "Incorrect username or password");
180 }
181 else if(findPlayerByName(vctPlayers, username) != NULL)
182 {
183 strcpy(serverMsg.buffer, "Player has already logged in.");
184 }
185 else
186 {
187 Player newP(username, "");
188 newP.setAddr(from);
189
190 vctPlayers.push_back(newP);
191 strcpy(serverMsg.buffer, "I'm thinking of a number between 1 and 1000. Guess what it is.");
192 }
193
194 serverMsg.type = MSG_TYPE_LOGIN;
195
196 delete(p);
197
198 break;
199 }
200 case MSG_TYPE_LOGOUT:
201 {
202 string name(clientMsg.buffer);
203 cout << "Player logging out: " << name << endl;
204
205 Player *p = findPlayerByName(vctPlayers, name);
206
207 if (p == NULL)
208 {
209 strcpy(serverMsg.buffer, "That player is not logged in. This is either a bug, or you're trying to hack the server.");
210 }
211 else if( p->addr.sin_addr.s_addr != from.sin_addr.s_addr ||
212 p->addr.sin_port != from.sin_port )
213 {
214 strcpy(serverMsg.buffer, "That player is logged in using a differemt connection. This is either a bug, or you're trying to hack the server.");
215 }
216 else
217 {
218 vctPlayers.erase((vector<Player>::iterator)p);
219 strcpy(serverMsg.buffer, "You have successfully logged out.");
220 }
221
222 break;
223 }
224 case MSG_TYPE_CHAT:
225 {
226 Player *p = findPlayerByAddr(vctPlayers, from);
227
228 if (p == NULL)
229 {
230 strcpy(serverMsg.buffer, "No player is logged in using this connection. This is either a bug, or you're trying to hack the server.");
231 }
232 else
233 {
234 int guess = atoi(clientMsg.buffer);
235
236 cout << "guess: " << guess << endl;
237
238 if (guess < 1 || guess > 1000) {
239 strcpy(serverMsg.buffer, "You must guess a number between 1 and 1000");
240 }else if(guess > num)
241 strcpy(serverMsg.buffer, "The number I'm thinking of is less than that.");
242 else if(guess < num)
243 strcpy(serverMsg.buffer, "The number I'm thinking of is greater than that.");
244 else if(guess == num) {
245 strcpy(serverMsg.buffer, "Congratulations! I will now think of a new number.");
246 num = (rand() % 1000) + 1;
247 }
248 }
249
250 serverMsg.type = MSG_TYPE_CHAT;
251
252 break;
253 }
254 default:
255 {
256 strcpy(serverMsg.buffer, "Server error occured. Report this please.");
257
258 serverMsg.type = MSG_TYPE_CHAT;
259
260 break;
261 }
262 }
263}
Note: See TracBrowser for help on using the repository browser.