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
RevLine 
[e084950]1#include "../common/compiler.h"
2
[2488852]3#include <cstdlib>
[371ce29]4#include <cstdio>
[e3535b3]5#include <unistd.h>
[2488852]6#include <string>
[e3535b3]7#include <iostream>
[2488852]8#include <vector>
9#include <algorithm>
[e3535b3]10
[371ce29]11#include <fcntl.h>
12#include <assert.h>
13
[73f75c1]14#include <sys/socket.h>
[371ce29]15#include <netdb.h>
[73f75c1]16#include <netinet/in.h>
17#include <arpa/inet.h>
18
[e3535b3]19#include <openssl/bio.h>
20#include <openssl/ssl.h>
21#include <openssl/err.h>
22
[8e540f4]23#include "Player.h"
[36082e8]24#include "DataAccess.h"
[2488852]25#include "../common/message.h"
[d2b411a]26
[e3535b3]27using namespace std;
28
[8e540f4]29void processMessage(const NETWORK_MSG &clientMsg, const struct sockaddr_in &from, vector<Player> &vctPlayers, int &num, NETWORK_MSG &serverMsg);
30
[73f75c1]31// this should probably go somewhere in the common folder
[e3535b3]32void error(const char *msg)
33{
34 perror(msg);
35 exit(0);
36}
37
[8e540f4]38Player *findPlayerByName(vector<Player> &vec, string name)
[2488852]39{
[8e540f4]40 vector<Player>::iterator it;
[2488852]41
[41ad8ed]42 cout << "Entered findPlayerByName" << endl;
43
[2488852]44 for (it = vec.begin(); it != vec.end(); it++)
45 {
[41ad8ed]46 cout << "Comparing name" << endl;
[2488852]47 if ( it->name.compare(name) == 0 )
48 return &(*it);
49 }
50
[41ad8ed]51 cout << "About to return" << endl;
[2488852]52 return NULL;
53}
54
[8e540f4]55Player *findPlayerByAddr(vector<Player> &vec, const sockaddr_in &addr)
[73f75c1]56{
[8e540f4]57 vector<Player>::iterator it;
[73f75c1]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
[371ce29]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
[e3535b3]77int main(int argc, char *argv[])
78{
79 int sock, length, n;
80 struct sockaddr_in server;
[73f75c1]81 struct sockaddr_in from; // holds the info on the connected client
[e084950]82 NETWORK_MSG clientMsg, serverMsg;
[8e540f4]83 vector<Player> vctPlayers;
[e084950]84
85 srand(time(NULL));
[371ce29]86 int num = 500;
87 //int num = (rand() % 0) + 1;
[e084950]88
89 cout << "num: " << num << endl;
[e3535b3]90
91 SSL_load_error_strings();
92 ERR_load_BIO_strings();
93 OpenSSL_add_all_algorithms();
94
95 if (argc < 2) {
[73f75c1]96 cerr << "ERROR, no port provided" << endl;
97 exit(1);
[e3535b3]98 }
[41ad8ed]99
[371ce29]100 sock = socket(AF_INET, SOCK_DGRAM, 0);
[e3535b3]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]));
[2488852]106 server.sin_addr.s_addr=INADDR_ANY;
107 if ( bind(sock, (struct sockaddr *)&server, length) < 0 )
[e084950]108 error("binding");
[73f75c1]109
[371ce29]110 set_nonblock(sock);
111
[cb1f288]112 while (true) {
[371ce29]113
114 usleep(5000);
115
[e084950]116 n = receiveMessage(&clientMsg, sock, &from);
[8e540f4]117
[371ce29]118 if (n >= 0) {
119 cout << "Got a message" << endl;
[8e540f4]120
[371ce29]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 }
[8e540f4]129
130 }
[371ce29]131
[8e540f4]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{
[41ad8ed]137 DataAccess da;
138
[8e540f4]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:
[d2b411a]149 {
[8e540f4]150 string username(clientMsg.buffer);
151 string password(strchr(clientMsg.buffer, '\0')+1);
[d2b411a]152
[8e540f4]153 cout << "username: " << username << endl;
154 cout << "password: " << password << endl;
[d2b411a]155
[41ad8ed]156 da.insertPlayer(username, password);
157
158 strcpy(serverMsg.buffer, "Registration successful");
[8e540f4]159
160 serverMsg.type = MSG_TYPE_REGISTER;
[d2b411a]161
[8e540f4]162 break;
163 }
164 case MSG_TYPE_LOGIN:
165 {
166 string username(clientMsg.buffer);
[41ad8ed]167 string password(strchr(clientMsg.buffer, '\0')+1);
[8e540f4]168 cout << "Player logging in: " << username << endl;
169
[41ad8ed]170 Player* p = da.getPlayer(username);
[d2b411a]171
[41ad8ed]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
[8e540f4]186 {
[59061f6]187 Player newP(username, "");
188 newP.setAddr(from);
189
190 vctPlayers.push_back(newP);
[8e540f4]191 strcpy(serverMsg.buffer, "I'm thinking of a number between 1 and 1000. Guess what it is.");
[07028b9]192 }
193
[8e540f4]194 serverMsg.type = MSG_TYPE_LOGIN;
[41ad8ed]195
196 delete(p);
[07028b9]197
[8e540f4]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);
[633f42a]206
[8e540f4]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.");
[07028b9]210 }
[8e540f4]211 else if( p->addr.sin_addr.s_addr != from.sin_addr.s_addr ||
212 p->addr.sin_port != from.sin_port )
[07028b9]213 {
[8e540f4]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.");
[2488852]215 }
[8e540f4]216 else
[2488852]217 {
[8e540f4]218 vctPlayers.erase((vector<Player>::iterator)p);
[41ad8ed]219 strcpy(serverMsg.buffer, "You have successfully logged out.");
[8e540f4]220 }
[07028b9]221
[8e540f4]222 break;
223 }
224 case MSG_TYPE_CHAT:
225 {
226 Player *p = findPlayerByAddr(vctPlayers, from);
[07028b9]227
[8e540f4]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.");
[2488852]231 }
[8e540f4]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;
[e084950]253 }
[8e540f4]254 default:
255 {
256 strcpy(serverMsg.buffer, "Server error occured. Report this please.");
[e084950]257
[8e540f4]258 serverMsg.type = MSG_TYPE_CHAT;
[e084950]259
[8e540f4]260 break;
261 }
[e3535b3]262 }
263}
Note: See TracBrowser for help on using the repository browser.