source: network-game/server/server.cpp@ 2318fff

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

Created findPlayerByAddr and added some more checks on the client name and address when receiving a message

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