source: network-game/server/server.cpp@ cbc595d

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

Changed a few minor things on the server

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