source: network-game/server/server.cpp@ 1a1aebd

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

Capitalized the filenames in common/*

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[2488852]1#include <cstdlib>
[371ce29]2#include <cstdio>
[e3535b3]3#include <unistd.h>
[2488852]4#include <string>
[e3535b3]5#include <iostream>
[2488852]6#include <vector>
7#include <algorithm>
[e3535b3]8
[371ce29]9#include <fcntl.h>
10#include <assert.h>
11
[73f75c1]12#include <sys/socket.h>
[371ce29]13#include <netdb.h>
[73f75c1]14#include <netinet/in.h>
15#include <arpa/inet.h>
16
[e3535b3]17#include <openssl/bio.h>
18#include <openssl/ssl.h>
19#include <openssl/err.h>
20
[b53c6b3]21#include "../common/Compiler.h"
22#include "../common/Message.h"
23
[8e540f4]24#include "Player.h"
[36082e8]25#include "DataAccess.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
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
[8e540f4]51Player *findPlayerByAddr(vector<Player> &vec, const sockaddr_in &addr)
[73f75c1]52{
[8e540f4]53 vector<Player>::iterator it;
[73f75c1]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
[371ce29]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
[e3535b3]73int main(int argc, char *argv[])
74{
75 int sock, length, n;
76 struct sockaddr_in server;
[cbc595d]77 struct sockaddr_in from; // holds the info about the connected client
[e084950]78 NETWORK_MSG clientMsg, serverMsg;
[8e540f4]79 vector<Player> vctPlayers;
[e084950]80
81 srand(time(NULL));
[cbc595d]82 int num = (rand() % 1000) + 1;
[e084950]83
84 cout << "num: " << num << endl;
[e3535b3]85
86 SSL_load_error_strings();
87 ERR_load_BIO_strings();
88 OpenSSL_add_all_algorithms();
89
90 if (argc < 2) {
[73f75c1]91 cerr << "ERROR, no port provided" << endl;
92 exit(1);
[e3535b3]93 }
[41ad8ed]94
[371ce29]95 sock = socket(AF_INET, SOCK_DGRAM, 0);
[e3535b3]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]));
[2488852]101 server.sin_addr.s_addr=INADDR_ANY;
102 if ( bind(sock, (struct sockaddr *)&server, length) < 0 )
[e084950]103 error("binding");
[73f75c1]104
[371ce29]105 set_nonblock(sock);
106
[cb1f288]107 while (true) {
[371ce29]108
109 usleep(5000);
110
[e084950]111 n = receiveMessage(&clientMsg, sock, &from);
[8e540f4]112
[371ce29]113 if (n >= 0) {
114 cout << "Got a message" << endl;
[8e540f4]115
[371ce29]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 }
[8e540f4]124
125 }
[371ce29]126
[8e540f4]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{
[41ad8ed]132 DataAccess da;
133
[8e540f4]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:
[d2b411a]144 {
[8e540f4]145 string username(clientMsg.buffer);
146 string password(strchr(clientMsg.buffer, '\0')+1);
[d2b411a]147
[8e540f4]148 cout << "username: " << username << endl;
149 cout << "password: " << password << endl;
[d2b411a]150
[41ad8ed]151 da.insertPlayer(username, password);
152
153 strcpy(serverMsg.buffer, "Registration successful");
[8e540f4]154
155 serverMsg.type = MSG_TYPE_REGISTER;
[d2b411a]156
[8e540f4]157 break;
158 }
159 case MSG_TYPE_LOGIN:
160 {
161 string username(clientMsg.buffer);
[41ad8ed]162 string password(strchr(clientMsg.buffer, '\0')+1);
[8e540f4]163 cout << "Player logging in: " << username << endl;
164
[41ad8ed]165 Player* p = da.getPlayer(username);
[d2b411a]166
[41ad8ed]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
[8e540f4]176 {
[59061f6]177 Player newP(username, "");
178 newP.setAddr(from);
179
180 vctPlayers.push_back(newP);
[8e540f4]181 strcpy(serverMsg.buffer, "I'm thinking of a number between 1 and 1000. Guess what it is.");
[07028b9]182 }
183
[8e540f4]184 serverMsg.type = MSG_TYPE_LOGIN;
[41ad8ed]185
186 delete(p);
[07028b9]187
[8e540f4]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);
[633f42a]196
[8e540f4]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.");
[07028b9]200 }
[8e540f4]201 else if( p->addr.sin_addr.s_addr != from.sin_addr.s_addr ||
202 p->addr.sin_port != from.sin_port )
[07028b9]203 {
[8e540f4]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.");
[2488852]205 }
[8e540f4]206 else
[2488852]207 {
[8e540f4]208 vctPlayers.erase((vector<Player>::iterator)p);
[41ad8ed]209 strcpy(serverMsg.buffer, "You have successfully logged out.");
[8e540f4]210 }
[07028b9]211
[8e540f4]212 break;
213 }
214 case MSG_TYPE_CHAT:
215 {
216 Player *p = findPlayerByAddr(vctPlayers, from);
[07028b9]217
[8e540f4]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.");
[2488852]221 }
[8e540f4]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;
[e084950]243 }
[8e540f4]244 default:
245 {
246 strcpy(serverMsg.buffer, "Server error occured. Report this please.");
[e084950]247
[8e540f4]248 serverMsg.type = MSG_TYPE_CHAT;
[e084950]249
[8e540f4]250 break;
251 }
[e3535b3]252 }
253}
Note: See TracBrowser for help on using the repository browser.