Commit 3647bea769d5f7d13af7ee97046bbdae9bfecdad

Authored by Pedro L Coutin
1 parent 9f59b128f3
Exists in master

Fixed?

Showing 3 changed files with 17 additions and 17 deletions Inline Diff

server/server.c View file @ 3647bea
#include <sys/types.h> 1 1 #include <sys/types.h>
#include <sys/socket.h> 2 2 #include <sys/socket.h>
#include <arpa/inet.h> 3 3 #include <arpa/inet.h>
#include <netinet/in.h> 4 4 #include <netinet/in.h>
#include <stdio.h> 5 5 #include <stdio.h>
#include <stdlib.h> 6 6 #include <stdlib.h>
#include <string.h> 7 7 #include <string.h>
#include <netdb.h> 8 8 #include <netdb.h>
#include <errno.h> 9 9 #include <errno.h>
#include <unistd.h> 10 10 #include <unistd.h>
#include <time.h> 11 11 #include <time.h>
#include "../common/mot_maze.h" 12 12 #include "../common/mot_maze.h"
#include "server.h" 13 13 #include "server.h"
14 14
void * 15 15 void *
get_in_addr(struct sockaddr *sa) 16 16 get_in_addr(struct sockaddr *sa)
{ 17 17 {
if (sa->sa_family == AF_INET) 18 18 if (sa->sa_family == AF_INET)
{ 19 19 {
return &(((struct sockaddr_in*)sa)->sin_addr); 20 20 return &(((struct sockaddr_in*)sa)->sin_addr);
} 21 21 }
22 22
return &(((struct sockaddr_in6*)sa)->sin6_addr); 23 23 return &(((struct sockaddr_in6*)sa)->sin6_addr);
} 24 24 }
25 25
26 26
size_t 27 27 size_t
sendall(int s, char *buf, size_t len) 28 28 sendall(int s, char *buf, size_t len)
{ 29 29 {
int total = 0; // how many bytes we've sent 30 30 int total = 0; // how many bytes we've sent
int bytesleft = len; // how many we have left to send 31 31 int bytesleft = len; // how many we have left to send
int n; 32 32 int n;
33 33
while (total < len) 34 34 while (total < len)
{ 35 35 {
n = send(s, buf+total, bytesleft, 0); 36 36 n = send(s, buf+total, bytesleft, 0);
37 37
if (n == -1) 38 38 if (n == -1)
{ 39 39 {
perror("sendall"); 40 40 perror("sendall");
return total; 41 41 return total;
} 42 42 }
43 43
total += n; 44 44 total += n;
bytesleft -= n; 45 45 bytesleft -= n;
} 46 46 }
return total; 47 47 return total;
} 48 48 }
49 49
50 50
size_t 51 51 size_t
recvall(int s, char *buf, size_t len) 52 52 recvall(int s, char *buf, size_t len)
{ 53 53 {
int total = 0; 54 54 int total = 0;
int bytesleft = len; 55 55 int bytesleft = len;
int n; 56 56 int n;
57 57
while (total < len) 58 58 while (total < len)
{ 59 59 {
if ((n = recv(s, buf, bytesleft, 0)) == -1) 60 60 if ((n = recv(s, buf, bytesleft, 0)) == -1)
{ 61 61 {
perror("recvall"); 62 62 perror("recvall");
return total; 63 63 return total;
} 64 64 }
total += n; 65 65 total += n;
bytesleft -= n; 66 66 bytesleft -= n;
} 67 67 }
return total; 68 68 return total;
} 69 69 }
70 70
71 71
short 72 72 short
getshort(int sock) 73 73 getshort(int sock)
{ 74 74 {
short ret; 75 75 short ret;
recvall(sock, (char *) &ret, sizeof(short)); 76 76 recvall(sock, (char *) &ret, sizeof(short));
77 77
return ntohs(ret); 78 78 return ntohs(ret);
} 79 79 }
80 80
/* 81 81 /*
* Return: 0 on success 82 82 * Return: 0 on success
* 1 on failure 83 83 * 1 on failure
*/ 84 84 */
size_t 85 85 size_t
sendshort(int sock, short s) 86 86 sendshort(int sock, short s)
{ 87 87 {
s = htons(s); 88 88 s = htons(s);
return sendall(sock, (char *) &s, sizeof(s)) != sizeof(s); 89 89 return sendall(sock, (char *) &s, sizeof(s)) != sizeof(s);
} 90 90 }
91 91
int 92 92 int
main(int argc, char *argv[]) 93 93 main(int argc, char *argv[])
{ 94 94 {
int ssockfd, csockfd, err;; 95 95 int ssockfd, csockfd, err;;
unsigned int magic, x, y; 96 96 unsigned short magic, x, y;
unsigned int u; 97 97 unsigned int u;
struct addrinfo hints, *srvinfo, *p; 98 98 struct addrinfo hints, *srvinfo, *p;
struct sockaddr_storage caddr; 99 99 struct sockaddr_storage caddr;
socklen_t addr_size; 100 100 socklen_t addr_size;
size_t len, bytes_sent; 101 101 size_t len, bytes_sent;
Player_set *pset; 102 102 Player_set *pset;
103 103
int i, j; 104 104 int i, j;
105 105
/* For handling multiple clients using select() */ 106 106 /* For handling multiple clients using select() */
107 107
fd_set master; 108 108 fd_set master;
fd_set read_fds; /* File descriptors with readable data */ 109 109 fd_set read_fds; /* File descriptors with readable data */
int fdmax; /* Highest file descriptor in the master set */ 110 110 int fdmax; /* Highest file descriptor in the master set */
int newfd; /* File descriptor for handling incoming connections */ 111 111 int newfd; /* File descriptor for handling incoming connections */
char buf[256]; 112 112 char buf[256];
int nbytes; 113 113 int nbytes;
char remoteIP[INET6_ADDRSTRLEN]; 114 114 char remoteIP[INET6_ADDRSTRLEN];
115 115
int players_connected = 0; 116 116 int players_connected = 0;
time_t launchtime = 0; 117 117 time_t launchtime = 0;
unsigned char game_started = 0; 118 118 unsigned char game_started = 0;
119 119
/* Should be moved to config file/cli arg ALONG WITH hostname/port */ 120 120 /* Should be moved to config file/cli arg ALONG WITH hostname/port */
int min_players = 2; 121 121 int min_players = 2;
time_t time_thresh = 2; 122 122 time_t time_thresh = 2;
123 123
FD_ZERO(&master); /* Empty the master set */ 124 124 FD_ZERO(&master); /* Empty the master set */
FD_ZERO(&read_fds); /* Empty the readfds set */ 125 125 FD_ZERO(&read_fds); /* Empty the readfds set */
pset = calloc(1, sizeof(Player_set)); 126 126 pset = calloc(1, sizeof(Player_set));
127 127
genmaze(20, 20); 128 128 genmaze(20, 20);
memset(&hints, 0, sizeof(hints)); 129 129 memset(&hints, 0, sizeof(hints));
130 130
/* Currently using TCP. */ 131 131 /* Currently using TCP. */
hints.ai_family = AF_UNSPEC; 132 132 hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_PASSIVE; 133 133 hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM; 134 134 hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP; 135 135 hints.ai_protocol = IPPROTO_TCP;
136 136
if ((err = getaddrinfo(MOTSRV_ADDR, MOTSRV_PORT, &hints, &srvinfo))) 137 137 if ((err = getaddrinfo(MOTSRV_ADDR, MOTSRV_PORT, &hints, &srvinfo)))
{ 138 138 {
fprintf(stderr, "Failed to get address: %s\n", gai_strerror(err)); 139 139 fprintf(stderr, "Failed to get address: %s\n", gai_strerror(err));
return 10; 140 140 return 10;
} 141 141 }
142 142
/* 143 143 /*
* Allocate socket file descriptor with address information acquired 144 144 * Allocate socket file descriptor with address information acquired
* from getaddrinfo. 145 145 * from getaddrinfo.
*/ 146 146 */
147 147
if (ssockfd == -1) 148 148 if (ssockfd == -1)
{ 149 149 {
perror("Failed to allocate server socket descriptor."); 150 150 perror("Failed to allocate server socket descriptor.");
return 7; 151 151 return 7;
} 152 152 }
153 153
for (p = srvinfo; p != NULL; p = p->ai_next) 154 154 for (p = srvinfo; p != NULL; p = p->ai_next)
{ 155 155 {
ssockfd = socket( p->ai_family, p->ai_socktype, p->ai_protocol); 156 156 ssockfd = socket( p->ai_family, p->ai_socktype, p->ai_protocol);
157 157
if( ssockfd < 0 ) 158 158 if( ssockfd < 0 )
{ 159 159 {
continue; 160 160 continue;
} 161 161 }
162 162
/* 163 163 /*
* If system thinks the socket is on use but it isn't, fix it... 164 164 * If system thinks the socket is on use but it isn't, fix it...
*/ 165 165 */
setsockopt(ssockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int)); 166 166 setsockopt(ssockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int));
167 167
/* 168 168 /*
* Bind socket to port. 169 169 * Bind socket to port.
*/ 170 170 */
if (bind(ssockfd, p->ai_addr, p->ai_addrlen) < 0) 171 171 if (bind(ssockfd, p->ai_addr, p->ai_addrlen) < 0)
{ 172 172 {
close(ssockfd); 173 173 close(ssockfd);
continue; 174 174 continue;
} 175 175 }
176 176
break; 177 177 break;
} 178 178 }
179 179
180 180
/* 181 181 /*
* If p reached NULL, it means we didn't bind at all. 182 182 * If p reached NULL, it means we didn't bind at all.
*/ 183 183 */
184 184
if (p == NULL) 185 185 if (p == NULL)
{ 186 186 {
fprintf( stderr, "failed to bind ssockfd\n" ); 187 187 fprintf( stderr, "failed to bind ssockfd\n" );
return 2; 188 188 return 2;
} 189 189 }
190 190
freeaddrinfo(srvinfo); 191 191 freeaddrinfo(srvinfo);
192 192
/* 193 193 /*
* Start listening on server socket descriptor. 194 194 * Start listening on server socket descriptor.
*/ 195 195 */
196 196
if (listen(ssockfd, BACKLOG ) == -1) 197 197 if (listen(ssockfd, BACKLOG ) == -1)
{ 198 198 {
perror("Server can't listen."); 199 199 perror("Server can't listen.");
return 3; 200 200 return 3;
} 201 201 }
202 202
/* 203 203 /*
* Add ssockfd to master set of sockets. 204 204 * Add ssockfd to master set of sockets.
*/ 205 205 */
FD_SET(ssockfd, &master); 206 206 FD_SET(ssockfd, &master);
207 207
/* 208 208 /*
* Since ssockfd is currently the only socket in master, 209 209 * Since ssockfd is currently the only socket in master,
* it's the highest descriptor. 210 210 * it's the highest descriptor.
*/ 211 211 */
fdmax = ssockfd; 212 212 fdmax = ssockfd;
213 213
214 214
while (1) 215 215 while (1)
{ 216 216 {
read_fds = master; 217 217 read_fds = master;
218 218
if (select(fdmax + 1, &read_fds, NULL, NULL, NULL ) == -1) 219 219 if (select(fdmax + 1, &read_fds, NULL, NULL, NULL ) == -1)
{ 220 220 {
perror("select"); 221 221 perror("select");
return 4; 222 222 return 4;
} 223 223 }
224 224
/* 225 225 /*
* Now read_fds has only those sockets that have readable data to 226 226 * Now read_fds has only those sockets that have readable data to
* show. 227 227 * show.
* Run through all the sockets to find data to read. 228 228 * Run through all the sockets to find data to read.
*/ 229 229 */
230 230
for (i = 0; i <= fdmax; i++) 231 231 for (i = 0; i <= fdmax; i++)
{ 232 232 {
if (!FD_ISSET(i, &read_fds)) 233 233 if (!FD_ISSET(i, &read_fds))
{ 234 234 {
continue; 235 235 continue;
} 236 236 }
237 237
/* If we're here, i has data to show */ 238 238 /* If we're here, i has data to show */
if (i == ssockfd) 239 239 if (i == ssockfd)
{ 240 240 {
/* Handle new connections. */ 241 241 /* Handle new connections. */
242 242
addr_size = sizeof caddr; 243 243 addr_size = sizeof caddr;
newfd = accept(ssockfd, 244 244 newfd = accept(ssockfd,
(struct sockaddr *) &caddr, &addr_size); 245 245 (struct sockaddr *) &caddr, &addr_size);
246 246
if (newfd == -1) 247 247 if (newfd == -1)
{ 248 248 {
perror("accept"); 249 249 perror("accept");
continue; 250 250 continue;
} 251 251 }
252 252
/* Add the new socket descriptor to master. */ 253 253 /* Add the new socket descriptor to master. */
FD_SET(newfd, &master); 254 254 FD_SET(newfd, &master);
255 255
if (newfd > fdmax) 256 256 if (newfd > fdmax)
{ 257 257 {
fdmax = newfd; 258 258 fdmax = newfd;
} 259 259 }
printf("server: new connection from %s on socket %d\n", 260 260 printf("server: new connection from %s on socket %d\n",
inet_ntop(caddr.ss_family, 261 261 inet_ntop(caddr.ss_family,
get_in_addr((struct sockaddr*)&caddr), 262 262 get_in_addr((struct sockaddr*)&caddr),
remoteIP, INET6_ADDRSTRLEN), newfd ); 263 263 remoteIP, INET6_ADDRSTRLEN), newfd );
264 264
if (game_started) 265 265 if (game_started)
{ 266 266 {
magic = htons(SRV_BUSY); 267 267 magic = htons(SRV_BUSY);
sendshort(newfd, magic); 268 268 sendshort(newfd, magic);
close(newfd); 269 269 close(newfd);
FD_CLR(newfd, &master); 270 270 FD_CLR(newfd, &master);
continue; 271 271 continue;
} 272 272 }
273 273
printf("checking if game started!!\n"); 274 274 printf("checking if game started!!\n");
275 275
if (!launchtime) launchtime = time(NULL); 276 276 if (!launchtime) launchtime = time(NULL);
277 277
players_connected++; 278 278 players_connected++;
handle_connecting_player(newfd, pset); 279 279 handle_connecting_player(newfd, pset);
280 280
printf("new connection handled!!\n"); 281 281 printf("new connection handled!!\n");
if (time(NULL) - launchtime >= time_thresh && 282 282 if (time(NULL) - launchtime >= time_thresh &&
players_connected >= min_players) 283 283 players_connected >= min_players)
{ 284 284 {
printf("game started!!\n"); 285 285 printf("game started!!\n");
begin_game(pset); 286 286 begin_game(pset);
game_started = 1; 287 287 game_started = 1;
} 288 288 }
} 289 289 }
else 290 290 else
{ 291 291 {
/* Handle data from a client. (ONLY A SHORT/magic no) */ 292 292 /* Handle data from a client. (ONLY A SHORT/magic no) */
293 293
if ((nbytes = recv(i, &magic, sizeof magic, 0 )) <= 0) 294 294 if ((nbytes = recv(i, &magic, sizeof magic, 0 )) <= 0)
{ 295 295 {
if (nbytes < 0) 296 296 if (nbytes < 0)
{ 297 297 {
perror("recv"); 298 298 perror("recv");
} 299 299 }
300 300
printf("server: socket %d hung up\n", i); 301 301 printf("server: socket %d hung up\n", i);
broadcast_disconnect(pset, i, 0); 302 302 broadcast_disconnect(pset, i, 0);
close(i); 303 303 close(i);
FD_CLR(i, &master); 304 304 FD_CLR(i, &master);
305 305
continue; 306 306 continue;
} 307 307 }
308 308
switch (htons(magic)) 309 309 switch (htons(magic))
{ 310 310 {
case PLAYER_MOV: 311 311 case PLAYER_MOV:
x = getshort(i); 312 312 x = getshort(i);
y = getshort(i); 313 313 y = getshort(i);
printf("player with socket %d moved to %d, %d\n", 314 314 printf("player with socket %d moved to %d, %d\n",
i, x, y); 315 315 i, x, y);
break; 316 316 break;
} 317 317 }
318 318
for (j = 0; j <= fdmax; j++) 319 319 for (j = 0; j <= fdmax; j++)
{ 320 320 {
if (FD_ISSET(j, &master)) 321 321 if (FD_ISSET(j, &master))
{ 322 322 {
Player *justMoved = player_byfd(pset, i); 323 323 Player *justMoved = player_byfd(pset, i);
Player *coll; 324 324 Player *coll;
int movPnum = justMoved->playerno; 325 325 int movPnum = justMoved->playerno;
326 326
/* 327 327 /*
* If the player that just moved is a hunter, and it 328 328 * If the player that just moved is a hunter, and it
* just stepped on a regular player, kill the (regular) 329 329 * just stepped on a regular player, kill the (regular)
* player! 330 330 * player!
*/ 331 331 */
if (justMoved->type && 332 332 if (justMoved->type &&
(coll = check_collision(pset, justMoved)) != NULL) 333 333 (coll = check_collision(pset, justMoved)) != NULL)
{ 334 334 {
int dead = coll->fd; 335 335 int dead = coll->fd;
336 336
printf("%s died, socket %d dropped.\n", coll->name, dead); 337 337 printf("%s died, socket %d dropped.\n", coll->name, dead);
broadcast_disconnect(pset, dead, 1); 338 338 broadcast_disconnect(pset, dead, 1);
close(dead); 339 339 close(dead);
FD_CLR(dead, &master); 340 340 FD_CLR(dead, &master);
} 341 341 }
342 342
/* 343 343 /*
* Avoid sending the data to the current client and 344 344 * Avoid sending the data to the current client and
* server. 345 345 * server.
*/ 346 346 */
if (j != ssockfd 347 347 if (j != ssockfd
&& j != i 348 348 && j != i
&& sendMov(j, movPnum, x, y) == -1) 349 349 && sendMov(j, movPnum, x, y) == -1)
{ 350 350 {
perror("send"); 351 351 perror("send");
} 352 352 }
} 353 353 }
} 354 354 }
355 355
} 356 356 }
} 357 357 }
} 358 358 }
359 359
360 360
/* 361 361 /*
* Free things (sockets, addrinfo, player data, maze) and exit. 362 362 * Free things (sockets, addrinfo, player data, maze) and exit.
*/ 363 363 */
close(ssockfd); 364 364 close(ssockfd);
close(csockfd); 365 365 close(csockfd);
freeaddrinfo(srvinfo); 366 366 freeaddrinfo(srvinfo);
free(MAZE.data); 367 367 free(MAZE.data);
368 368
return 0; 369 369 return 0;
} 370 370 }
371 371
void 372 372 void
handle_connecting_player(int newfd, Player_set *pset) 373 373 handle_connecting_player(int newfd, Player_set *pset)
{ 374 374 {
char *pname; 375 375 char *pname;
unsigned char pnum; 376 376 unsigned char pnum;
unsigned int magic; 377 377 unsigned short magic;
unsigned int u; 378 378 unsigned int u;
379 379
/* 380 380 /*
* When a player first connects, send maze magic, data width, size. 381 381 * When a player first connects, send maze magic, data width, size.
* Then send the maze itself. Then await confirmation. 382 382 * Then send the maze itself. Then await confirmation.
*/ 383 383 */
384 384
add_player(pset); 385 385 add_player(pset);
magic = htons(MAZE_MAGIC); 386 386 magic = htons(MAZE_MAGIC);
sendall(newfd, (char *) &magic, sizeof(magic)); 387 387 sendall(newfd, (char *) &magic, sizeof(magic));
388 388
/* Maze width */ 389 389 /* Maze width */
u = htonl(MAZE.w); 390 390 u = htonl(MAZE.w);
sendall(newfd, (char *) &u, sizeof(u)); 391 391 sendall(newfd, (char *) &u, sizeof(u));
392 392
u = htonl(MAZE.size); 393 393 u = htonl(MAZE.size);
sendall(newfd, (char *) &u, sizeof(u)); 394 394 sendall(newfd, (char *) &u, sizeof(u));
395 395
sendall(newfd, (char *) MAZE.data, MAZE.size); 396 396 sendall(newfd, (char *) MAZE.data, MAZE.size);
397 397
if (recv(newfd, &magic, sizeof(magic), 0) != sizeof(magic) 398 398 if (recv(newfd, &magic, sizeof(magic), 0) != sizeof(magic)
|| ntohs(magic) != MAZE_MAGIC) 399 399 || ntohs(magic) != MAZE_MAGIC)
{ 400 400 {
fprintf(stderr, "Failed to get client confirmation\n"); 401 401 fprintf(stderr, "Failed to get client confirmation\n");
exit(1); 402 402 exit(1);
} 403 403 }
404 404
pname = malloc(PNAMELEN); 405 405 pname = malloc(PNAMELEN);
recvall(newfd, pname, PNAMELEN); 406 406 recvall(newfd, pname, PNAMELEN);
printf("%s connected !!!\n", pname); 407 407 printf("%s connected !!!\n", pname);
408 408
sendall(newfd, (char *) &pset->last->playerno, sizeof(pnum)); 409 409 sendall(newfd, (char *) &pset->last->playerno, sizeof(pnum));
410 410
pset->last->name = pname; 411 411 pset->last->name = pname;
pset->last->x = -1; 412 412 pset->last->x = -1;
pset->last->y = -1; 413 413 pset->last->y = -1;
pset->last->fd = newfd; 414 414 pset->last->fd = newfd;
printf("new file descriptor: %d (%d)\n", pset->last->fd,newfd); 415 415 printf("new file descriptor: %d (%d)\n", pset->last->fd,newfd);
} 416 416 }
417 417
static void 418 418 static void
send_dc(Player *p, int pno_removed, unsigned int sig) 419 419 send_dc(Player *p, int pno_removed, unsigned short sig)
{ 420 420 {
sendshort(p->fd, sig); 421 421 sendshort(p->fd, sig);
sendshort(p->fd, pno_removed); 422 422 sendshort(p->fd, pno_removed);
} 423 423 }
424 424
/* 425 425 /*
* Remove player with file descriptor fd from the list, and broadcast its 426 426 * Remove player with file descriptor fd from the list, and broadcast its
* disconnecting. 427 427 * disconnecting.
*/ 428 428 */
void 429 429 void
broadcast_disconnect(Player_set *pset, int fd, int death) 430 430 broadcast_disconnect(Player_set *pset, int fd, int death)
{ 431 431 {
Player *to_remove = player_byfd(pset, fd); 432 432 Player *to_remove = player_byfd(pset, fd);
int remove_pno = to_remove->playerno; 433 433 int remove_pno = to_remove->playerno;
rm_player(pset, to_remove); 434 434 rm_player(pset, to_remove);
pset_map(pset, &send_dc, remove_pno, death ? PLAYER_DIE : PLAYER_DC); 435 435 pset_map(pset, &send_dc, remove_pno, death ? PLAYER_DIE : PLAYER_DC);
} 436 436 }
437 437
/* 438 438 /*
* Check if some player in `pset' has the same x, y as `node'. Return the 439 439 * Check if some player in `pset' has the same x, y as `node'. Return the
* first player that is colliding, or NULL if there are no collisions. 440 440 * first player that is colliding, or NULL if there are no collisions.
*/ 441 441 */
Player * 442 442 Player *
check_collision(Player_set *pset, Player *node) 443 443 check_collision(Player_set *pset, Player *node)
{ 444 444 {
Player *temp; 445 445 Player *temp;
446 446
for (temp = pset->first; temp != NULL; temp = temp->next) 447 447 for (temp = pset->first; temp != NULL; temp = temp->next)
{ 448 448 {
if (temp != node && temp->x == node->x && temp->y == node->y) 449 449 if (temp != node && temp->x == node->x && temp->y == node->y)
return temp; 450 450 return temp;
} 451 451 }
return NULL; 452 452 return NULL;
} 453 453 }
454 454
455 455
void 456 456 void
set_positions(Player_set *pset) 457 457 set_positions(Player_set *pset)
{ 458 458 {
Player *temp; 459 459 Player *temp;
for (temp = pset->first; temp != NULL; temp = temp->next) 460 460 for (temp = pset->first; temp != NULL; temp = temp->next)
{ 461 461 {
server/server.h View file @ 3647bea
#ifndef _MOTSRV_H_ 1 1 #ifndef _MOTSRV_H_
#define _MOTSRV_H_ 2 2 #define _MOTSRV_H_
3 3
#define MOTSRV_ADDR "127.0.0.1" 4 4 #define MOTSRV_ADDR "127.0.0.1"
#define MOTSRV_PORT "6666" 5 5 #define MOTSRV_PORT "6666"
#define BACKLOG 8 6 6 #define BACKLOG 8
7 7
#define PNAMELEN 32 8 8 #define PNAMELEN 32
#define MAX_PLAYERNUM 32 9 9 #define MAX_PLAYERNUM 32
10 10
#define MAZE_MAGIC 0x6D7A 11 11 #define MAZE_MAGIC 0x6D7A
#define ADD_PLAYER 0x4E45 12 12 #define ADD_PLAYER 0x4E45
#define HUNTER 0x4855 13 13 #define HUNTER 0x4855
#define ILLEGAL_MOV 0xF000 14 14 #define ILLEGAL_MOV 0xF000
#define PLAYER_MOV 0x4D4F 15 15 #define PLAYER_MOV 0x4D4F
#define PLAYER_DC 0x4443 16 16 #define PLAYER_DC 0x4443
#define PLAYER_DIE 0x4B4F 17 17 #define PLAYER_DIE 0x4B4F
#define PLAYER_WIN 0x5749 18 18 #define PLAYER_WIN 0x5749
#define SRV_BUSY 0xEEEE 19 19 #define SRV_BUSY 0xEEEE
20 20
#define _MOT_SERVER 21 21 #define _MOT_SERVER
22 22
/* Player linked list stuff */ 23 23 /* Player linked list stuff */
24 24
typedef struct _player Player; 25 25 typedef struct _player Player;
typedef struct _player_set Player_set; 26 26 typedef struct _player_set Player_set;
27 27
struct _player 28 28 struct _player
{ 29 29 {
char *name; 30 30 char *name;
short x, y; 31 31 short x, y;
32 32
int fd; 33 33 int fd;
unsigned char playerno; 34 34 unsigned char playerno;
unsigned char type; // 0 is prey, 1 is predator 35 35 unsigned char type; // 0 is prey, 1 is predator
unsigned char dead; 36 36 unsigned char dead;
37 37
Player *next; 38 38 Player *next;
Player *prev; 39 39 Player *prev;
}; 40 40 };
41 41
struct _player_set 42 42 struct _player_set
{ 43 43 {
Player *first; 44 44 Player *first;
Player *last; 45 45 Player *last;
Player *cur; 46 46 Player *cur;
int last_pno; 47 47 int last_pno;
}; 48 48 };
49 49
void begin_game(Player_set *pset); 50 50 void begin_game(Player_set *pset);
int sendMov(int psock, short int movepno, int x, int y); 51 51 int sendMov(int psock, short int movepno, int x, int y);
void broadcast_disconnect(Player_set *pset, int fd, int death); 52 52 void broadcast_disconnect(Player_set *pset, int fd, int death);
Player *check_collision(Player_set *pset, Player *node); 53 53 Player *check_collision(Player_set *pset, Player *node);
server/srv_player.c View file @ 3647bea
/* 1 1 /*
* VERY FAST VERY OPTIMIZED BRUTE FORCE LINEAR SEARCH LINKED LIST ALONG 2 2 * VERY FAST VERY OPTIMIZED BRUTE FORCE LINEAR SEARCH LINKED LIST ALONG
* WITH select() FOR AMAZING BLAZING FAST DATACENTER GRADE ENTERPRISE 3 3 * WITH select() FOR AMAZING BLAZING FAST DATACENTER GRADE ENTERPRISE
* SERVER PERFORMANCE 4 4 * SERVER PERFORMANCE
*/ 5 5 */
6 6
#include <stdlib.h> 7 7 #include <stdlib.h>
#include "server.h" 8 8 #include "server.h"
9 9
Player_set * 10 10 Player_set *
init_pset() 11 11 init_pset()
{ 12 12 {
return calloc(1, sizeof(Player_set)); 13 13 return calloc(1, sizeof(Player_set));
} 14 14 }
15 15
void 16 16 void
free_pset(Player_set *p) 17 17 free_pset(Player_set *p)
{ 18 18 {
/* 19 19 /*
* Scan through the entire linked list and free each element of each 20 20 * Scan through the entire linked list and free each element of each
* struct, then free p. 21 21 * struct, then free p.
*/ 22 22 */
while (p->first != NULL) 23 23 while (p->first != NULL)
{ 24 24 {
rm_player(p, p->first); 25 25 rm_player(p, p->first);
} 26 26 }
27 27
free(p); 28 28 free(p);
} 29 29 }
30 30
/* 31 31 /*
* Add a player at the end of the linked list. Make the current Player 32 32 * Add a player at the end of the linked list. Make the current Player
* element in the set point to this new player. 33 33 * element in the set point to this new player.
*/ 34 34 */
void 35 35 void
add_player(Player_set *set) 36 36 add_player(Player_set *set)
{ 37 37 {
if (set->first == NULL) 38 38 if (set->first == NULL)
{ 39 39 {
/* Player elements should be initialized to all zeroes. */ 40 40 /* Player elements should be initialized to all zeroes. */
set->first = calloc(1, sizeof(Player)); 41 41 set->first = calloc(1, sizeof(Player));
set->cur = set->last = set->first; 42 42 set->cur = set->last = set->first;
} 43 43 }
else 44 44 else
{ 45 45 {
set->last->next = calloc(1, sizeof(Player)); 46 46 set->last->next = calloc(1, sizeof(Player));
set->cur = set->last = set->last->next; 47 47 set->cur = set->last = set->last->next;
} 48 48 }
set->last->playerno = ++(set->last_pno); 49 49 set->last->playerno = ++(set->last_pno);
} 50 50 }
51 51
void 52 52 void
rm_player(Player_set *set, Player *p) 53 53 rm_player(Player_set *set, Player *p)
{ 54 54 {
if (p->prev != NULL) 55 55 if (p->prev != NULL)
{ 56 56 {
p->prev->next = p->next; 57 57 p->prev->next = p->next;
} 58 58 }
59 59
if (p->next != NULL) 60 60 if (p->next != NULL)
{ 61 61 {
p->next->prev = p->prev; 62 62 p->next->prev = p->prev;
} 63 63 }
64 64
if (set->first == p) 65 65 if (set->first == p)
{ 66 66 {
set->first = p->next; 67 67 set->first = p->next;
} 68 68 }
69 69
if (set->last == p) 70 70 if (set->last == p)
{ 71 71 {
set->last = p->prev; 72 72 set->last = p->prev;
} 73 73 }
74 74
free(p->name); 75 75 free(p->name);
free(p); 76 76 free(p);
} 77 77 }
78 78
/* 79 79 /*
* Glorious optimized enterprise-level search algorithm. 80 80 * Glorious optimized enterprise-level search algorithm.
*/ 81 81 */
Player * 82 82 Player *
player_byfd(Player_set *s, int fd) 83 83 player_byfd(Player_set *s, int fd)
{ 84 84 {
Player *this = s->first; 85 85 Player *this = s->first;
86 86
while (this != NULL) 87 87 while (this != NULL)
{ 88 88 {
if (this->fd == fd) 89 89 if (this->fd == fd)
{ 90 90 {
return this; 91 91 return this;
} 92 92 }
this = this->next; 93 93 this = this->next;
} 94 94 }
return NULL; 95 95 return NULL;
} 96 96 }
97 97
/* 98 98 /*
* blazing fast seeking algorithm 99 99 * blazing fast seeking algorithm
*/ 100 100 */
Player * 101 101 Player *
player_byindex(Player_set *s, int index) 102 102 player_byindex(Player_set *s, int index)
{ 103 103 {
Player *this = s->first; 104 104 Player *this = s->first;
int counter = 0; 105 105 int counter = 0;
while (this != NULL) 106 106 while (this != NULL)
{ 107 107 {
if (counter++ == index) 108 108 if (counter++ == index)
{ 109 109 {
return this; 110 110 return this;
} 111 111 }
this = this->next; 112 112 this = this->next;
} 113 113 }
return NULL; 114 114 return NULL;
} 115 115 }