source: network-game/server/server.cpp@ 36082e8

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

Moved the database code to a new class

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