source: network-game/server/server.cpp@ 59061f6

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

Added new data access methods to save and retrieve player data

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