Commit c1ff6e0d9fccdebf4441148d32a2af05d963965f

Authored by Pedro L Coutin
1 parent 3647bea769
Exists in master

Dying works! But stuff is still really buggy. :(

Showing 3 changed files with 18 additions and 32 deletions Inline Diff

client/main.c View file @ c1ff6e0
/* 1 1 /*
* Client for the Maze of Torment game. 2 2 * Client for the Maze of Torment game.
*/ 3 3 */
4 4
#include <stdio.h> 5 5 #include <stdio.h>
#include <stdlib.h> 6 6 #include <stdlib.h>
#include <stddef.h> 7 7 #include <stddef.h>
#include <SDL2/SDL.h> 8 8 #include <SDL2/SDL.h>
#include <SDL2/SDL_image.h> 9 9 #include <SDL2/SDL_image.h>
#include <SDL2/SDL_net.h> 10 10 #include <SDL2/SDL_net.h>
11 11
#include "../common/mot_maze.h" 12 12 #include "../common/mot_maze.h"
#include "entities/entities.h" 13 13 #include "entities/entities.h"
#include "mot.h" 14 14 #include "mot.h"
#include "net.h" 15 15 #include "net.h"
16 16
int 17 17 int
main(int argc, char *argv[]) 18 18 main(int argc, char *argv[])
{ 19 19 {
SDL_Window *window; 20 20 SDL_Window *window;
CLC_CONFIG config; 21 21 CLC_CONFIG config;
Uint8 *kbdstate; 22 22 Uint8 *kbdstate;
SDL_Event e; 23 23 SDL_Event e;
PLAYER *me; 24 24 PLAYER *me;
PLAYER *player; 25 25 PLAYER *player;
Uint32 time; 26 26 Uint32 time;
IPaddress srv_ip; 27 27 IPaddress srv_ip;
TCPsocket srv_sock; 28 28 TCPsocket srv_sock;
Uint16 magic; 29 29 Uint16 magic;
int i; 30 30 int i;
SDLNet_SocketSet srv_sset; 31 31 SDLNet_SocketSet srv_sset;
char myname[PNAME_SIZE]; 32 32 char myname[PNAME_SIZE];
unsigned char myno; 33 33 unsigned char myno;
34 34
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS) == -1) 35 35 if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS) == -1)
{ 36 36 {
fprintf(stderr, "SDL_Init: %s\n", SDL_GetError()); 37 37 fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
exit(EXIT_FAILURE); 38 38 exit(EXIT_FAILURE);
} 39 39 }
40 40
if (SDLNet_Init() == -1) 41 41 if (SDLNet_Init() == -1)
{ 42 42 {
fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError()); 43 43 fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 44 44 exit(EXIT_FAILURE);
} 45 45 }
46 46
parsecfg(&config); 47 47 parsecfg(&config);
48 48
/* 49 49 /*
* Get player name. 50 50 * Get player name.
*/ 51 51 */
printf("Wow such name: "); 52 52 printf("Wow such name: ");
fgets(myname, PNAME_SIZE, stdin); 53 53 fgets(myname, PNAME_SIZE, stdin);
54 54
for (i = 0; i < PNAME_SIZE; i++) 55 55 for (i = 0; i < PNAME_SIZE; i++)
{ 56 56 {
if (myname[i] == '\n') 57 57 if (myname[i] == '\n')
{ 58 58 {
myname[i] = '\0'; 59 59 myname[i] = '\0';
break; 60 60 break;
} 61 61 }
} 62 62 }
63 63
64 64
/* 65 65 /*
* Connect to server! 66 66 * Connect to server!
*/ 67 67 */
if (SDLNet_ResolveHost(&srv_ip, config.defaultsrv, 68 68 if (SDLNet_ResolveHost(&srv_ip, config.defaultsrv,
atoi(config.defaultport))) 69 69 atoi(config.defaultport)))
{ 70 70 {
fprintf(stderr, "SDLNet_ResolveHost: %s\n", SDLNet_GetError()); 71 71 fprintf(stderr, "SDLNet_ResolveHost: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 72 72 exit(EXIT_FAILURE);
} 73 73 }
74 74
75 75
/* 76 76 /*
* Bind socket! 77 77 * Bind socket!
*/ 78 78 */
if (!(srv_sock = SDLNet_TCP_Open(&srv_ip))) 79 79 if (!(srv_sock = SDLNet_TCP_Open(&srv_ip)))
{ 80 80 {
fprintf(stderr, "SDLNet_TCP_Open: %s\n", SDLNet_GetError()); 81 81 fprintf(stderr, "SDLNet_TCP_Open: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 82 82 exit(EXIT_FAILURE);
} 83 83 }
84 84
85 85
/* 86 86 /*
* Add (a single) server socket to srv_sset for cheap hack for checking 87 87 * Add (a single) server socket to srv_sset for cheap hack for checking
* the server socket's state. 88 88 * the server socket's state.
*/ 89 89 */
srv_sset = SDLNet_AllocSocketSet(1); 90 90 srv_sset = SDLNet_AllocSocketSet(1);
91 91
if (!srv_sset) 92 92 if (!srv_sset)
{ 93 93 {
printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError()); 94 94 printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 95 95 exit(EXIT_FAILURE);
} 96 96 }
97 97
SDLNet_TCP_AddSocket(srv_sset, srv_sock); 98 98 SDLNet_TCP_AddSocket(srv_sset, srv_sock);
99 99
100 100
/* 101 101 /*
* Get maze, add connecting players to buffer and wait until the game 102 102 * Get maze, add connecting players to buffer and wait until the game
* begins. 103 103 * begins.
*/ 104 104 */
105 105
getmaze(srv_sock); 106 106 getmaze(srv_sock);
107 107
window = SDL_CreateWindow( 108 108 window = SDL_CreateWindow(
"MAZE OF TORMENT", 109 109 "MAZE OF TORMENT",
SDL_WINDOWPOS_UNDEFINED, 110 110 SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 111 111 SDL_WINDOWPOS_UNDEFINED,
config.win_width, 112 112 config.win_width,
config.win_height, 113 113 config.win_height,
config.win_flags 114 114 config.win_flags
); 115 115 );
116 116
SDL_GetWindowSize(window, &config.win_width, &config.win_height); 117 117 SDL_GetWindowSize(window, &config.win_width, &config.win_height);
118 118
if (window == NULL) 119 119 if (window == NULL)
{ 120 120 {
fprintf(stderr, "Could not create window: %s\n", 121 121 fprintf(stderr, "Could not create window: %s\n",
SDL_GetError()); 122 122 SDL_GetError());
exit(EXIT_FAILURE); 123 123 exit(EXIT_FAILURE);
} 124 124 }
125 125
renderer = SDL_CreateRenderer(window, -1, config.renderflags); 126 126 renderer = SDL_CreateRenderer(window, -1, config.renderflags);
127 127
hsprite = loadPic("img/predator.gif"); 128 128 hsprite = loadPic("img/predator.gif");
psprite = loadPic("img/prey.gif"); 129 129 psprite = loadPic("img/prey.gif");
black = loadPic("img/black.gif"); 130 130 black = loadPic("img/black.gif");
131 131
/* 132 132 /*
* Initialize maze, and send player name. 133 133 * Initialize maze, and send player name.
*/ 134 134 */
MAZE.X = (config.win_width - MAZE.w * 16) / 2; 135 135 MAZE.X = (config.win_width - MAZE.w * 16) / 2;
MAZE.Y = (config.win_height - MAZE.h * 16) / 2; 136 136 MAZE.Y = (config.win_height - MAZE.h * 16) / 2;
137 137
SDLNet_TCP_Send(srv_sock, myname, PNAME_SIZE); 138 138 SDLNet_TCP_Send(srv_sock, myname, PNAME_SIZE);
139 139
140 140
/* 141 141 /*
* Initialize maze and get the LOCAL player, then the REMOTE players. 142 142 * Initialize maze and get the LOCAL player, then the REMOTE players.
*/ 143 143 */
144 144
SDLNet_TCP_Recv(srv_sock, &myno, 1); 145 145 SDLNet_TCP_Recv(srv_sock, &myno, 1);
player = calloc(1, sizeof(PLAYER)); 146 146 player = calloc(1, sizeof(PLAYER));
147 147
if (!((magic = getshort(srv_sock)) == ADD_PLAYER)) 148 148 if (!((magic = getshort(srv_sock)) == ADD_PLAYER))
{ 149 149 {
printf("server not sending players\n!"); 150 150 printf("server not sending players\n!");
exit(EXIT_FAILURE); 151 151 exit(EXIT_FAILURE);
} 152 152 }
153 153
unsigned char hunter = addp(player, srv_sock); 154 154 unsigned char hunter = addp(player, srv_sock);
155 155
choose_hunter(player, hunter); 156 156 choose_hunter(player, hunter);
me = choose_player(player, myno); 157 157 me = choose_player(player, myno);
158 158
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255); 159 159 SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
draw_maze(MAZE.X, MAZE.Y); 160 160 draw_maze(MAZE.X, MAZE.Y);
161 161
PLAYER *temp; 162 162 PLAYER *temp;
163 163
for (temp = player->next; temp != NULL; temp = temp->next) 164 164 for (temp = player->next; temp != NULL; temp = temp->next)
{ 165 165 {
printf("drew player %d\n", temp->playerno); 166 166 printf("drew player %d\n", temp->playerno);
drawPlayer(temp); 167 167 drawPlayer(temp);
} 168 168 }
169 169
printf("starting game!!\n"); 170 170 printf("starting game!!\n");
/* 171 171 /*
* Game loop! 172 172 * Game loop!
*/ 173 173 */
174 174
for (;;) 175 175 for (;;)
{ 176 176 {
time = SDL_GetTicks(); 177 177 time = SDL_GetTicks();
178 178
/* 179 179 /*
* Poll the network in each frame. Because. 180 180 * Poll the network in each frame. Because.
*/ 181 181 */
182 182
int numready = SDLNet_CheckSockets(srv_sset, 0); 183 183 int numready = SDLNet_CheckSockets(srv_sset, 0);
184 184
if (numready == -1) 185 185 if (numready == -1)
{ 186 186 {
printf("SDLNet_CheckSockets: %s\n", SDLNet_GetError()); 187 187 printf("SDLNet_CheckSockets: %s\n", SDLNet_GetError());
perror("SDLNet_CheckSockets"); 188 188 perror("SDLNet_CheckSockets");
} 189 189 }
else if (numready) 190 190 else if (numready)
{ 191 191 {
unsigned char packet, hunter; 192 192 unsigned char packet;
unsigned char pnum, movx, movy; 193 193 unsigned char pnum, movx, movy;
194 194
printf("srv socket is ready!!\n"); 195 195 printf("srv socket is ready!!\n");
196 196
if (SDLNet_TCP_Recv(srv_sock, &packet, 2) == 2) 197 197 if (SDLNet_TCP_Recv(srv_sock, &packet, 2) == 2)
{ 198 198 {
switch (SDLNet_Read16(&packet)) 199 199 switch (SDLNet_Read16(&packet))
{ 200 200 {
case PLAYER_MOV: 201 201 case PLAYER_MOV:
puts("PLAYER_MOV"); 202 202 puts("PLAYER_MOV");
pnum = getshort(srv_sock); 203 203 pnum = getshort(srv_sock);
movx = getshort(srv_sock); 204 204 movx = getshort(srv_sock);
movy = getshort(srv_sock); 205 205 movy = getshort(srv_sock);
206 206
printf("player %d moved to (%d,%d)\n", 207 207 printf("player %d moved to (%d,%d)\n",
pnum, movx, movy); 208 208 pnum, movx, movy);
movePlayer(choose_player(player,pnum), movx, movy); 209 209 movePlayer(choose_player(player,pnum), movx, movy);
break; 210 210 break;
211 211
case PLAYER_WIN: 212 212 case PLAYER_WIN:
puts("PLAYER_WIN"); 213 213 puts("PLAYER_WIN");
break; 214 214 break;
215 215
case PLAYER_DC: 216 216 case PLAYER_DC:
puts("PLAYER_DC"); 217 217 puts("PLAYER_DC");
pnum = getshort(srv_sock); 218 218 pnum = getshort(srv_sock);
printf("Player %d disconnected!!\n", pnum); 219 219 printf("Player %d disconnected!!\n", pnum);
removep(choose_player(player,pnum)); 220 220 removep(choose_player(player,pnum));
break; 221 221 break;
222 222
case PLAYER_DIE: 223 223 case PLAYER_DIE:
puts("PLAYER_DIE"); 224 224 puts("PLAYER_DIE");
pnum = getshort(srv_sock); 225 225 pnum = getshort(srv_sock);
226 226
if (pnum == myno) 227 227 if (pnum == myno)
{ 228 228 {
puts("YOU ARE DEAD\nGAME OVER"); 229 229 puts("YOU ARE DEAD\nGAME OVER");
goto exit; 230 230 goto exit;
} 231 231 }
printf("Player %d deaded!!!!!\n", pnum); 232 232 printf("Player %d deaded!!!!!\n", pnum);
removep(choose_player(player,pnum)); 233 233 removep(choose_player(player, pnum));
break; 234 234 break;
235 235
case ADD_PLAYER: 236
printf("ADD_PLAYER\n"); 237
hunter = addp(player,srv_sock); 238
choose_hunter(player,hunter); 239
me = choose_player(player,myno); 240
draw_maze(MAZE.X, MAZE.Y); 241
242
server/server.c View file @ c1ff6e0
#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 short 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 justMoved->x = x;
328 justMoved->y = y;
329
/* 327 330 /*
* If the player that just moved is a hunter, and it 328 331 * If the player that just moved is a hunter, and it
* just stepped on a regular player, kill the (regular) 329 332 * just stepped on a regular player, kill the (regular)
* player! 330 333 * player!
*/ 331 334 */
if (justMoved->type && 332 335 if (justMoved->type &&
(coll = check_collision(pset, justMoved)) != NULL) 333 336 (coll = check_collision(pset, justMoved)) != NULL)
{ 334 337 {
int dead = coll->fd; 335 338 int dead = coll->fd;
336 339
printf("%s died, socket %d dropped.\n", coll->name, dead); 337 340 printf("%s died, socket %d dropped.\n", coll->name, dead);
broadcast_disconnect(pset, dead, 1); 338 341 broadcast_disconnect(pset, dead, 1);
close(dead); 339 342 close(dead);
FD_CLR(dead, &master); 340 343 FD_CLR(dead, &master);
} 341 344 }
342 345
/* 343 346 /*
* Avoid sending the data to the current client and 344 347 * Avoid sending the data to the current client and
* server. 345 348 * server.
*/ 346 349 */
if (j != ssockfd 347 350 if (j != ssockfd
&& j != i 348 351 && j != i
&& sendMov(j, movPnum, x, y) == -1) 349 352 && sendMov(j, movPnum, x, y) == -1)
{ 350 353 {
perror("send"); 351 354 perror("send");
} 352 355 }
} 353 356 }
} 354 357 }
355 358
} 356 359 }
} 357 360 }
} 358 361 }
359 362
360 363
/* 361 364 /*
* Free things (sockets, addrinfo, player data, maze) and exit. 362 365 * Free things (sockets, addrinfo, player data, maze) and exit.
*/ 363 366 */
close(ssockfd); 364 367 close(ssockfd);
close(csockfd); 365 368 close(csockfd);
freeaddrinfo(srvinfo); 366 369 freeaddrinfo(srvinfo);
free(MAZE.data); 367 370 free(MAZE.data);
368 371
return 0; 369 372 return 0;
} 370 373 }
371 374
void 372 375 void
handle_connecting_player(int newfd, Player_set *pset) 373 376 handle_connecting_player(int newfd, Player_set *pset)
{ 374 377 {
char *pname; 375 378 char *pname;
unsigned char pnum; 376 379 unsigned char pnum;
unsigned short magic; 377 380 unsigned short magic;
unsigned int u; 378 381 unsigned int u;
379 382
/* 380 383 /*
* When a player first connects, send maze magic, data width, size. 381 384 * When a player first connects, send maze magic, data width, size.
* Then send the maze itself. Then await confirmation. 382 385 * Then send the maze itself. Then await confirmation.
*/ 383 386 */
384 387
add_player(pset); 385 388 add_player(pset);
magic = htons(MAZE_MAGIC); 386 389 magic = htons(MAZE_MAGIC);
sendall(newfd, (char *) &magic, sizeof(magic)); 387 390 sendall(newfd, (char *) &magic, sizeof(magic));
388 391
/* Maze width */ 389 392 /* Maze width */
u = htonl(MAZE.w); 390 393 u = htonl(MAZE.w);
sendall(newfd, (char *) &u, sizeof(u)); 391 394 sendall(newfd, (char *) &u, sizeof(u));
392 395
u = htonl(MAZE.size); 393 396 u = htonl(MAZE.size);
sendall(newfd, (char *) &u, sizeof(u)); 394 397 sendall(newfd, (char *) &u, sizeof(u));
395 398
sendall(newfd, (char *) MAZE.data, MAZE.size); 396 399 sendall(newfd, (char *) MAZE.data, MAZE.size);
397 400
if (recv(newfd, &magic, sizeof(magic), 0) != sizeof(magic) 398 401 if (recv(newfd, &magic, sizeof(magic), 0) != sizeof(magic)
|| ntohs(magic) != MAZE_MAGIC) 399 402 || ntohs(magic) != MAZE_MAGIC)
{ 400 403 {
fprintf(stderr, "Failed to get client confirmation\n"); 401 404 fprintf(stderr, "Failed to get client confirmation\n");
exit(1); 402 405 exit(1);
} 403 406 }
404 407
pname = malloc(PNAMELEN); 405 408 pname = malloc(PNAMELEN);
recvall(newfd, pname, PNAMELEN); 406 409 recvall(newfd, pname, PNAMELEN);
printf("%s connected !!!\n", pname); 407 410 printf("%s connected !!!\n", pname);
408 411
sendall(newfd, (char *) &pset->last->playerno, sizeof(pnum)); 409 412 sendall(newfd, (char *) &pset->last->playerno, sizeof(pnum));
410 413
pset->last->name = pname; 411 414 pset->last->name = pname;
pset->last->x = -1; 412 415 pset->last->x = -1;
pset->last->y = -1; 413 416 pset->last->y = -1;
pset->last->fd = newfd; 414 417 pset->last->fd = newfd;
printf("new file descriptor: %d (%d)\n", pset->last->fd,newfd); 415 418 printf("new file descriptor: %d (%d)\n", pset->last->fd,newfd);
} 416 419 }
417 420
static void 418 421 static void
send_dc(Player *p, int pno_removed, unsigned short sig) 419 422 send_dc(Player *p, int pno_removed, unsigned short sig)
{ 420 423 {
sendshort(p->fd, sig); 421 424 sendshort(p->fd, sig);
sendshort(p->fd, pno_removed); 422 425 sendshort(p->fd, pno_removed);
} 423 426 }
424 427
/* 425 428 /*
* Remove player with file descriptor fd from the list, and broadcast its 426 429 * Remove player with file descriptor fd from the list, and broadcast its
* disconnecting. 427 430 * disconnecting.
*/ 428 431 */
void 429 432 void
broadcast_disconnect(Player_set *pset, int fd, int death) 430 433 broadcast_disconnect(Player_set *pset, int fd, int death)
{ 431 434 {
Player *to_remove = player_byfd(pset, fd); 432 435 Player *to_remove = player_byfd(pset, fd);
int remove_pno = to_remove->playerno; 433 436 int remove_pno = to_remove->playerno;
rm_player(pset, to_remove); 434 437 rm_player(pset, to_remove);
pset_map(pset, &send_dc, remove_pno, death ? PLAYER_DIE : PLAYER_DC); 435 438 pset_map(pset, &send_dc, remove_pno, death ? PLAYER_DIE : PLAYER_DC);
} 436 439 }
437 440
/* 438 441 /*
* Check if some player in `pset' has the same x, y as `node'. Return the 439 442 * 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 443 * first player that is colliding, or NULL if there are no collisions.
*/ 441 444 */
Player * 442 445 Player *
check_collision(Player_set *pset, Player *node) 443 446 check_collision(Player_set *pset, Player *node)
{ 444 447 {
Player *temp; 445 448 Player *temp;
446 449
for (temp = pset->first; temp != NULL; temp = temp->next) 447 450 for (temp = pset->first; temp != NULL; temp = temp->next)
{ 448 451 {
if (temp != node && temp->x == node->x && temp->y == node->y) 449 452 if (temp != node && temp->x == node->x && temp->y == node->y)
return temp; 450 453 return temp;
} 451 454 }
return NULL; 452 455 return NULL;
} 453 456 }
454 457
455 458
void 456 459 void
set_positions(Player_set *pset) 457 460 set_positions(Player_set *pset)
server/server.h View file @ c1ff6e0
#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);
54 54
55 55