Commit a2eea9f4bf1611283cfdb5bf5d31f6ea437fe07d

Authored by Pedro L Coutin
1 parent 92db0f083c
Exists in master and in 1 other branch rohan

Refactored some of the code in the client and added a few comments.

Also, removed the code to accept players if the player count ever goes
below the minimum -- if we ever are to accept additional players after the
game has started, it should probably be up to the maximum number of
players. Or infinity, since we have linked lists stored in the heap, but
checking calloc for errors? :p

Showing 5 changed files with 182 additions and 151 deletions Inline Diff

client/entities/entities.h View file @ a2eea9f
#ifndef _MOT_ENTITIES_H 1 1 #ifndef _MOT_ENTITIES_H
#define _MOT_ENTITIES_H 2 2 #define _MOT_ENTITIES_H
3 3
typedef struct _mot_picture PICTURE; 4 4 typedef struct _mot_picture PICTURE;
typedef struct _mot_player PLAYER; 5 5 typedef struct _mot_player PLAYER;
6 6
struct _mot_picture 7 7 struct _mot_picture
{ 8 8 {
SDL_Texture *texture; 9 9 SDL_Texture *texture;
SDL_Rect rect; 10 10 SDL_Rect rect;
}; 11 11 };
12 12
struct _mot_player 13 13 struct _mot_player
{ 14 14 {
char *name; 15 15 char *name;
PICTURE *sprite; 16 16 PICTURE *sprite;
17 17
short x, y; // location in maze tiles 18 18 short x, y; // location in maze tiles
19 19
unsigned char type; // 0 is prey, 1 is predator 20 20 unsigned char type; // 0 is prey, 1 is predator
unsigned char playerno; 21 21 unsigned char playerno;
unsigned char dead; 22 22 unsigned char dead;
23 23
PLAYER *next; 24 24 PLAYER *next;
PLAYER *prev; 25 25 PLAYER *prev;
26 26
}; 27 27 };
28 28
void init_player(TCPsocket sock, PLAYER *player); 29 29 void init_player(TCPsocket sock, PLAYER *player);
30 30
void drawPlayer(PLAYER *); 31 31 void drawPlayer(PLAYER *);
32 32
void local_player_update(TCPsocket sock, PLAYER *, PLAYER *, const Uint8 *); 33 33 void local_player_update(TCPsocket sock, PLAYER *, PLAYER *, const Uint8 *);
34 34
35 /*
36 * Move the player `p' TO a specified x, y location (assigns, doesn't
37 * translate).
38 */
void movePlayer(PLAYER *p, short newx, short newy); 35 39 void movePlayer(PLAYER *p, short newx, short newy);
36 40
41 /*
42 * Reset the maze cell that the player is on...
43 */
void clearPlayer(PLAYER *); 37 44 void clearPlayer(PLAYER *);
38 45
46 /*
47 * Return the player with pnode `pnum' from the player linked list
48 * starting with `node'.
49 */
50 PLAYER *choose_player(PLAYER *node, unsigned char pnum);
51
52 /*
53 * Free the player `temp' after linking the two players next to `temp'
54 * together. Also erases it from the screen.
55 */
56 void removep(PLAYER *temp);
57
58 /*
59 * On the linked list starting with `node', find the player with pnode
60 * `hpno', and set it to be of hunter type.
61 */
62 void choose_hunter(PLAYER *node, unsigned char hpno);
63
64 /*
65 * Add an initialized player "object" to the player linked list containing
66 * `node'.
67 */
client/entities/player.c View file @ a2eea9f
#include <SDL2/SDL.h> 1 1 #include <SDL2/SDL.h>
#include <SDL2/SDL_net.h> 2 2 #include <SDL2/SDL_net.h>
#include "../../common/mot_maze.h" 3 3 #include "../../common/mot_maze.h"
#include "entities.h" 4 4 #include "entities.h"
#include "../mot.h" 5 5 #include "../mot.h"
#include "../net.h" 6 6 #include "../net.h"
7 7
void 8 8 void
init_player(TCPsocket sock, PLAYER *player) 9 9 init_player(TCPsocket sock, PLAYER *player)
{ 10 10 {
short loc; 11 11 short loc;
char *pname; 12 12 char *pname;
13 13
SDLNet_TCP_Recv(sock, &player->playerno, sizeof(unsigned char)); 14 14 SDLNet_TCP_Recv(sock, &player->playerno, sizeof(unsigned char));
15 15
SDLNet_TCP_Recv(sock, &loc, sizeof(loc)); 16 16 SDLNet_TCP_Recv(sock, &loc, sizeof(loc));
player->x = SDLNet_Read16(&loc); 17 17 player->x = SDLNet_Read16(&loc);
18 18
SDLNet_TCP_Recv(sock, &loc, sizeof(loc)); 19 19 SDLNet_TCP_Recv(sock, &loc, sizeof(loc));
player->y = SDLNet_Read16(&loc); 20 20 player->y = SDLNet_Read16(&loc);
21 21
pname = malloc(PNAME_SIZE); 22 22 pname = malloc(PNAME_SIZE);
SDLNet_TCP_Recv(sock, pname, PNAME_SIZE); 23 23 SDLNet_TCP_Recv(sock, pname, PNAME_SIZE);
24 24
player->name = pname; 25 25 player->name = pname;
26 26
/* default type is 0 */ 27 27 /* default type is 0 */
player->type = 0; 28 28 player->type = 0;
29 29
#ifdef _DEBUG 30 30 #ifdef _DEBUG
printf("Got %s (%d)", pname, player->playerno); 31 31 printf("Got %s (%d)", pname, player->playerno);
#endif 32 32 #endif
33 33
player->sprite = &psprite; 34 34 player->sprite = &psprite;
player->dead = 0; 35 35 player->dead = 0;
} 36 36 }
37 37
/* 38 38 /*
* Checks array of PLAYER structs to see if one contains the location 39 39 * Checks array of PLAYER structs to see if one contains the location
* given... 40 40 * given...
* O(n) 41 41 * O(n)
*/ 42 42 */
PLAYER * 43 43 PLAYER *
playerAt(PLAYER *players, short x, short y, PLAYER *me) 44 44 playerAt(PLAYER *players, short x, short y, PLAYER *me)
{ 45 45 {
int i; 46 46 int i;
for (i = 0; players[i].sprite != NULL; i++) 47 47 for (i = 0; players[i].sprite != NULL; i++)
{ 48 48 {
if (players[i].x == x && players[i].y == y && players + i != me) 49 49 if (players[i].x == x && players[i].y == y && players + i != me)
{ 50 50 {
return &players[i]; 51 51 return &players[i];
} 52 52 }
} 53 53 }
return NULL; 54 54 return NULL;
} 55 55 }
56 56
/* 57 57 /*
* Update the user of this client (not the remote players). 58 58 * Update the user of this client (not the remote players).
* reimplement later by asking the server if we can move and then moving? 59 59 * reimplement later by asking the server if we can move and then moving?
* also use higher level functions to move by one cell somewhere 60 60 * also use higher level functions to move by one cell somewhere
* i mean what 61 61 * i mean what
*/ 62 62 */
void 63 63 void
local_player_update(TCPsocket sock, PLAYER *me, PLAYER *remote, 64 64 local_player_update(TCPsocket sock, PLAYER *me, PLAYER *remote,
const Uint8 *kbdstate) 65 65 const Uint8 *kbdstate)
{ 66 66 {
short myx = me->x, 67 67 short myx = me->x,
myy = me->y; 68 68 myy = me->y;
69 69
/* Update based on walls... */ 70 70 /* Update based on walls... */
if (kbdstate[SDL_SCANCODE_DOWN] && !mazetile(me->x + 1, me->y + 2)) 71 71 if (kbdstate[SDL_SCANCODE_DOWN] && !mazetile(me->x + 1, me->y + 2))
{ 72 72 {
clearPlayer(me); 73 73 clearPlayer(me);
me->y += 2; 74 74 me->y += 2;
} 75 75 }
else if (kbdstate[SDL_SCANCODE_UP] && !mazetile(me->x + 1, me->y)) 76 76 else if (kbdstate[SDL_SCANCODE_UP] && !mazetile(me->x + 1, me->y))
{ 77 77 {
clearPlayer(me); 78 78 clearPlayer(me);
me->y -= 2; 79 79 me->y -= 2;
} 80 80 }
else if (kbdstate[SDL_SCANCODE_RIGHT] && !mazetile(me->x + 2, me->y + 1)) 81 81 else if (kbdstate[SDL_SCANCODE_RIGHT] && !mazetile(me->x + 2, me->y + 1))
{ 82 82 {
clearPlayer(me); 83 83 clearPlayer(me);
me->x += 2; 84 84 me->x += 2;
} 85 85 }
else if (kbdstate[SDL_SCANCODE_LEFT] && !mazetile(me->x, me->y + 1)) 86 86 else if (kbdstate[SDL_SCANCODE_LEFT] && !mazetile(me->x, me->y + 1))
{ 87 87 {
clearPlayer(me); 88 88 clearPlayer(me);
me->x -= 2; 89 89 me->x -= 2;
} 90 90 }
else 91 91 else
{ 92 92 {
return; 93 93 return;
} 94 94 }
95 95
PLAYER *dunce; 96 96 PLAYER *dunce;
97 97
if ((dunce = playerAt(remote, me->x, me->y, me)) != NULL) 98 98 if ((dunce = playerAt(remote, me->x, me->y, me)) != NULL)
{ 99 99 {
/* Not a hunter */ 100 100 /* Not a hunter */
if (!me->type) 101 101 if (!me->type)
{ 102 102 {
/* Reset/don't move */ 103 103 /* Reset/don't move */
me->x = myx; 104 104 me->x = myx;
me->y = myy; 105 105 me->y = myy;
} /* Hunter */ 106 106 } /* Hunter */
else 107 107 else
{ 108 108 {
/* Kill the other player and take its spot :( */ 109 109 /* Kill the other player and take its spot :( */
clearPlayer(dunce); 110 110 clearPlayer(dunce);
dunce->dead = 1; 111 111 dunce->dead = 1;
dunce->x = -5; 112 112 dunce->x = -5;
dunce->y = -5; 113 113 dunce->y = -5;
} 114 114 }
} 115 115 }
116 116
sendshort(sock, PLAYER_MOV); 117 117 sendshort(sock, PLAYER_MOV);
sendshort(sock, me->x); 118 118 sendshort(sock, me->x);
sendshort(sock, me->y); 119 119 sendshort(sock, me->y);
120 120
drawPlayer(me); 121 121 drawPlayer(me);
} 122 122 }
123 123
124 /*
125 * Move the player `p' TO a specified x, y location (assigns, doesn't
126 * translate).
127 */
void 124 128 void
movePlayer(PLAYER *p, short newx, short newy) 125 129 movePlayer(PLAYER *p, short newx, short newy)
{ 126 130 {
clearPlayer(p); 127 131 clearPlayer(p);
p->x = newx; 128 132 p->x = newx;
p->y = newy; 129 133 p->y = newy;
clearPlayer(p); 130 134 clearPlayer(p);
drawPlayer(p); 131 135 drawPlayer(p);
} 132 136 }
133 137
void 134 138 void
drawPlayer(PLAYER *player) 135 139 drawPlayer(PLAYER *player)
{ 136 140 {
printf("inside drawplayer()!!\n"); 137 141 printf("inside drawplayer()!!\n");
if (player->dead) 138 142 if (player->dead)
{ 139 143 {
return; 140 144 return;
} 141 145 }
player->sprite->rect.x = MAZE.X + player->x * TILE_WIDTH + 10; 142 146 player->sprite->rect.x = MAZE.X + player->x * TILE_WIDTH + 10;
player->sprite->rect.y = MAZE.Y + player->y * TILE_HEIGHT + 10; 143 147 player->sprite->rect.y = MAZE.Y + player->y * TILE_HEIGHT + 10;
printf("changed player sprite!!\n"); 144 148 printf("changed player sprite!!\n");
SDL_RenderCopy(renderer, 145 149 SDL_RenderCopy(renderer,
player->sprite->texture, 146 150 player->sprite->texture,
NULL, &(player->sprite->rect)); 147 151 NULL, &(player->sprite->rect));
printf("exiting drawplayer()!!\n"); 148 152 printf("exiting drawplayer()!!\n");
} 149 153 }
150 154
/* 151 155 /*
* Reset the maze cell that the player is on... 152 156 * Reset the maze cell that the player is on...
*/ 153 157 */
void 154 158 void
clearPlayer(PLAYER *player) 155 159 clearPlayer(PLAYER *player)
{ 156 160 {
player->sprite->rect.x = MAZE.X + player->x * TILE_WIDTH + 10; 157 161 player->sprite->rect.x = MAZE.X + player->x * TILE_WIDTH + 10;
player->sprite->rect.y = MAZE.Y + player->y * TILE_HEIGHT + 10; 158 162 player->sprite->rect.y = MAZE.Y + player->y * TILE_HEIGHT + 10;
SDL_RenderCopy(renderer, 159 163 SDL_RenderCopy(renderer,
black.texture, 160 164 black.texture,
NULL, &player->sprite->rect); 161 165 NULL, &player->sprite->rect);
166 }
167
168 /*
169 * Return the player with pnode `pnum' from the player linked list
170 * starting with `node'.
171 */
172 PLAYER *
173 choose_player(PLAYER *node, unsigned char pnum)
174 {
175 PLAYER *temp;
176 for (temp = node->next; temp != NULL; temp = temp->next)
177 {
178 printf("temp->playerno = %d, pnum = %d\n", temp->playerno, pnum);
179 if (temp->playerno == pnum)
180 {
181 break;
182 }
183 }
184 return temp;
185 }
186
187 /*
188 * Free the player `temp' after linking the two players next to `temp'
189 * together. Also erases it from the screen.
190 */
191 //potential bug: hunter eats someone, then someone disconnects. they both
192 //have the same location, so they both disappear?
193 void
194 removep(PLAYER *temp)
195 {
196 if (temp == NULL)
197 {
198 printf("Can't remove NULL player!!\n");
199 return;
200 }
201 if (temp->prev == NULL)
202 {
203 if (temp->next != NULL)
204 {
205 temp->next->prev = NULL;
206 }
207 }
208 else
209 {
210 if (temp->next == NULL)
211 {
212 temp->prev->next = NULL;
213 }
214 else
215 {
216 temp->prev->next = temp->next;
217 temp->next->prev = temp->prev;
218 }
219 }
220 clearPlayer(temp);
221 free(temp);
222 }
223
224 /*
225 * Blindly iterate through the player linked list starting from `node' to
226 * find the player with pnode `hpno', and set it to be of hunter type.
227 */
228 void
229 choose_hunter(PLAYER *node, unsigned char hpno)
230 {
231 PLAYER *temp;
232
233 for (temp = node; temp != NULL; temp = temp->next)
234 {
235 if (temp->playerno == hpno)
236 {
237 temp->type = 1;
238 temp->sprite = &hsprite;
239 return;
240 }
241 }
242 }
243
244 /*
245 * Add an initialized player "object" to the player linked list containing
246 * `node'.
247 */
248 void
249 add_player(PLAYER *node, PLAYER *newp)
250 {
251 PLAYER *temp;
252
253 for (temp = node; temp->next != NULL; temp = temp->next)
254 {
255 printf("cycle: temp->next->playerno: %d\n",temp->next->playerno);
256 }
257
258 for (temp = node; temp->next != NULL; temp = temp->next);
259
260 temp->next = newp;
261 newp->prev = temp;
262 newp->next = NULL;
263 }
264
265 /*
266 * Keep receiving players from the server until it's done and it chooses a
267 * hunter, adding them to the player linked list containing `node'.
268 */
269 unsigned char
270 addp(PLAYER *node, TCPsocket srv_sock)
271 {
272 Uint16 magic;
273 PLAYER *cur_player = NULL;
274
275 do
276 {
277 cur_player = calloc(1, sizeof(PLAYER));
278 init_player(srv_sock, cur_player);
279 add_player(node, cur_player);
280
281 printf("Player %s (%d) connected, at (%d, %d)\n", cur_player->name,
client/main.c View file @ a2eea9f
/* 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
17
PLAYER* 18
choose_player(PLAYER* node, unsigned char pnum) 19
{ 20
PLAYER *temp; 21
for(temp = node->next; temp != NULL; temp = temp->next) 22
{ 23
printf("temp->playerno = %d, pnum = %d\n",temp->playerno,pnum); 24
if(temp->playerno == pnum) 25
{ 26
break; 27
} 28
} 29
return temp; 30
} 31
32
void 33
removep(PLAYER* temp) 34
{ 35
if(temp == NULL) 36
{ 37
printf("Can't remove NULL player!!\n"); 38
return; 39
} 40
if (temp->prev == NULL) 41
{ 42
if (temp->next != NULL) 43
{ 44
temp->next->prev = NULL; 45
} 46
} 47
else 48
{ 49
if (temp->next == NULL) 50
{ 51
temp->prev->next = NULL; 52
} 53
else 54
{ 55
temp->prev->next = temp->next; 56
temp->next->prev = temp->prev; 57
} 58
} 59
clearPlayer(temp); 60
free(temp); 61
} 62
63
void 64
choose_hunter(PLAYER *node, unsigned char hpno) 65
{ 66
PLAYER *temp; 67
68
for (temp = node; temp != NULL; temp = temp->next) 69
{ 70
if (temp->playerno == hpno) 71
{ 72
temp->type = 1; 73
temp->sprite = &hsprite; 74
return; 75
} 76
} 77
} 78
79
80
void 81
add_player(PLAYER *node, PLAYER *newp) 82
{ 83
PLAYER *temp; 84
for(temp = node; temp->next != NULL; temp = temp->next) 85
{ 86
printf("cycle: temp->next->playerno: %d\n",temp->next->playerno); 87
} 88
for (temp = node; temp->next != NULL; temp = temp->next); 89
90
temp->next = newp; 91
newp->prev = temp; 92
newp->next = NULL; 93
} 94
95
unsigned char 96
addp(PLAYER *node,TCPsocket srv_sock) 97
{ 98
Uint16 magic; 99
PLAYER *cur_player = NULL; 100
do 101
{ 102
cur_player = calloc(1,sizeof(PLAYER)); 103
init_player(srv_sock,cur_player); 104
add_player(node,cur_player); 105
106
printf("Player %s (%d) connected, at (%d, %d)\n", cur_player->name, 107
cur_player->playerno, cur_player->x, cur_player->y); 108
109
} while ((magic = getshort(srv_sock)) == ADD_PLAYER); 110
111
printf("players added\n"); 112
113
if (magic == HUNTER) 114
{ 115
unsigned char hunter; 116
117
SDLNet_TCP_Recv(srv_sock, &hunter, 1); 118
return hunter; 119
} 120
else 121
{ 122
fprintf(stderr, "Bad magic number %X from server\n", magic); 123
exit(EXIT_FAILURE); 124
} 125
126
127
} 128
129
130
int 131 17 int
main(int argc, char *argv[]) 132 18 main(int argc, char *argv[])
{ 133 19 {
SDL_Window *window; 134 20 SDL_Window *window;
CLC_CONFIG config; 135 21 CLC_CONFIG config;
Uint8 *kbdstate; 136 22 Uint8 *kbdstate;
SDL_Event e; 137 23 SDL_Event e;
PLAYER *me; 138 24 PLAYER *me;
PLAYER *player; 139 25 PLAYER *player;
Uint32 time; 140 26 Uint32 time;
IPaddress srv_ip; 141 27 IPaddress srv_ip;
TCPsocket srv_sock; 142 28 TCPsocket srv_sock;
Uint16 magic; 143 29 Uint16 magic;
int i; 144 30 int i;
SDLNet_SocketSet srv_sset; 145 31 SDLNet_SocketSet srv_sset;
char myname[PNAME_SIZE]; 146 32 char myname[PNAME_SIZE];
unsigned char myno; 147 33 unsigned char myno;
148 34
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS) == -1) 149 35 if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS) == -1)
{ 150 36 {
fprintf(stderr, "SDL_Init: %s\n", SDL_GetError()); 151 37 fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
exit(EXIT_FAILURE); 152 38 exit(EXIT_FAILURE);
} 153 39 }
154 40
if (SDLNet_Init() == -1) 155 41 if (SDLNet_Init() == -1)
{ 156 42 {
fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError()); 157 43 fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 158 44 exit(EXIT_FAILURE);
} 159 45 }
160 46
parsecfg(&config); 161 47 parsecfg(&config);
162 48
/* 163 49 /*
* Get player name. 164 50 * Get player name.
*/ 165 51 */
printf("Wow such name: "); 166 52 printf("Wow such name: ");
fgets(myname, PNAME_SIZE, stdin); 167 53 fgets(myname, PNAME_SIZE, stdin);
168 54
for (i = 0; i < PNAME_SIZE; i++) 169 55 for (i = 0; i < PNAME_SIZE; i++)
{ 170 56 {
if (myname[i] == '\n') 171 57 if (myname[i] == '\n')
{ 172 58 {
myname[i] = '\0'; 173 59 myname[i] = '\0';
break; 174 60 break;
} 175 61 }
} 176 62 }
177 63
178 64
/* 179 65 /*
* Connect to server! 180 66 * Connect to server!
*/ 181 67 */
if (SDLNet_ResolveHost(&srv_ip, config.defaultsrv, 182 68 if (SDLNet_ResolveHost(&srv_ip, config.defaultsrv,
atoi(config.defaultport))) 183 69 atoi(config.defaultport)))
{ 184 70 {
fprintf(stderr, "SDLNet_ResolveHost: %s\n", SDLNet_GetError()); 185 71 fprintf(stderr, "SDLNet_ResolveHost: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 186 72 exit(EXIT_FAILURE);
} 187 73 }
188 74
189 75
/* 190 76 /*
* Bind socket! 191 77 * Bind socket!
*/ 192 78 */
if (!(srv_sock = SDLNet_TCP_Open(&srv_ip))) 193 79 if (!(srv_sock = SDLNet_TCP_Open(&srv_ip)))
{ 194 80 {
fprintf(stderr, "SDLNet_TCP_Open: %s\n", SDLNet_GetError()); 195 81 fprintf(stderr, "SDLNet_TCP_Open: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 196 82 exit(EXIT_FAILURE);
} 197 83 }
198 84
199 85
/* 200 86 /*
* Add (a single) server socket to srv_sset for cheap hack for checking 201 87 * Add (a single) server socket to srv_sset for cheap hack for checking
* the server socket's state. 202 88 * the server socket's state.
*/ 203 89 */
srv_sset = SDLNet_AllocSocketSet(1); 204 90 srv_sset = SDLNet_AllocSocketSet(1);
205 91
if (!srv_sset) 206 92 if (!srv_sset)
{ 207 93 {
printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError()); 208 94 printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 209 95 exit(EXIT_FAILURE);
} 210 96 }
211 97
SDLNet_TCP_AddSocket(srv_sset, srv_sock); 212 98 SDLNet_TCP_AddSocket(srv_sset, srv_sock);
213 99
214 100
/* 215 101 /*
* Get maze, add connecting players to buffer and wait until the game 216 102 * Get maze, add connecting players to buffer and wait until the game
* begins. 217 103 * begins.
*/ 218 104 */
219 105
getmaze(srv_sock); 220 106 getmaze(srv_sock);
221 107
window = SDL_CreateWindow( 222 108 window = SDL_CreateWindow(
"MAZE OF TORMENT", 223 109 "MAZE OF TORMENT",
SDL_WINDOWPOS_UNDEFINED, 224 110 SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 225 111 SDL_WINDOWPOS_UNDEFINED,
config.win_width, 226 112 config.win_width,
config.win_height, 227 113 config.win_height,
config.win_flags 228 114 config.win_flags
); 229 115 );
230 116
SDL_GetWindowSize(window, &config.win_width, &config.win_height); 231 117 SDL_GetWindowSize(window, &config.win_width, &config.win_height);
232 118
if (window == NULL) 233 119 if (window == NULL)
{ 234 120 {
fprintf(stderr, "Could not create window: %s\n", 235 121 fprintf(stderr, "Could not create window: %s\n",
SDL_GetError()); 236 122 SDL_GetError());
exit(EXIT_FAILURE); 237 123 exit(EXIT_FAILURE);
} 238 124 }
239 125
renderer = SDL_CreateRenderer(window, -1, config.renderflags); 240 126 renderer = SDL_CreateRenderer(window, -1, config.renderflags);
241 127
hsprite = loadPic("img/predator.gif"); 242 128 hsprite = loadPic("img/predator.gif");
psprite = loadPic("img/prey.gif"); 243 129 psprite = loadPic("img/prey.gif");
black = loadPic("img/black.gif"); 244 130 black = loadPic("img/black.gif");
245 131
/* 246 132 /*
* Initialize maze, and send player name. 247 133 * Initialize maze, and send player name.
*/ 248 134 */
MAZE.X = (config.win_width - MAZE.w * 16) / 2; 249 135 MAZE.X = (config.win_width - MAZE.w * 16) / 2;
MAZE.Y = (config.win_height - MAZE.h * 16) / 2; 250 136 MAZE.Y = (config.win_height - MAZE.h * 16) / 2;
251 137
SDLNet_TCP_Send(srv_sock, myname, PNAME_SIZE); 252 138 SDLNet_TCP_Send(srv_sock, myname, PNAME_SIZE);
253 139
254 140
/* 255 141 /*
* Initialize maze and get the LOCAL player, then the REMOTE players. 256 142 * Initialize maze and get the LOCAL player, then the REMOTE players.
*/ 257 143 */
258 144
SDLNet_TCP_Recv(srv_sock, &myno, 1); 259 145 SDLNet_TCP_Recv(srv_sock, &myno, 1);
player = calloc(1, sizeof(PLAYER)); 260 146 player = calloc(1, sizeof(PLAYER));
261 147
if (!((magic = getshort(srv_sock)) == ADD_PLAYER)) 262 148 if (!((magic = getshort(srv_sock)) == ADD_PLAYER))
{ 263 149 {
printf("server not sending players\n!"); 264 150 printf("server not sending players\n!");
exit(EXIT_FAILURE); 265 151 exit(EXIT_FAILURE);
} 266 152 }
267 153
unsigned char hunter = addp(player,srv_sock); 268 154 unsigned char hunter = addp(player,srv_sock);
269 155
choose_hunter(player,hunter); 270 156 choose_hunter(player,hunter);
me = choose_player(player,myno); 271 157 me = choose_player(player,myno);
272 158
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255); 273 159 SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
draw_maze(MAZE.X, MAZE.Y); 274 160 draw_maze(MAZE.X, MAZE.Y);
275 161
PLAYER *temp; 276 162 PLAYER *temp;
277 163
for (temp = player->next; temp != NULL; temp = temp->next) 278 164 for (temp = player->next; temp != NULL; temp = temp->next)
{ 279 165 {
printf("drew player %d\n", temp->playerno); 280 166 printf("drew player %d\n", temp->playerno);
drawPlayer(temp); 281 167 drawPlayer(temp);
} 282 168 }
283 169
printf("starting game!!\n"); 284 170 printf("starting game!!\n");
/* 285 171 /*
* Game loop! 286 172 * Game loop!
*/ 287 173 */
288 174
for (;;) 289 175 for (;;)
{ 290 176 {
time = SDL_GetTicks(); 291 177 time = SDL_GetTicks();
292 178
/* 293 179 /*
* Poll the network in each frame. Because. 294 180 * Poll the network in each frame. Because.
*/ 295 181 */
296 182
int numready = SDLNet_CheckSockets(srv_sset, 0); 297 183 int numready = SDLNet_CheckSockets(srv_sset, 0);
298 184
if (numready == -1) 299 185 if (numready == -1)
{ 300 186 {
printf("SDLNet_CheckSockets: %s\n", SDLNet_GetError()); 301 187 printf("SDLNet_CheckSockets: %s\n", SDLNet_GetError());
perror("SDLNet_CheckSockets"); 302 188 perror("SDLNet_CheckSockets");
} 303 189 }
else if (numready) 304 190 else if (numready)
{ 305 191 {
unsigned char packet, hunter; 306 192 unsigned char packet, hunter;
unsigned char pnum, movx, movy; 307 193 unsigned char pnum, movx, movy;
printf("srv socket is ready!!\n"); 308 194 printf("srv socket is ready!!\n");
if (SDLNet_TCP_Recv(srv_sock, &packet, 2) == 2) 309 195 if (SDLNet_TCP_Recv(srv_sock, &packet, 2) == 2)
{ 310 196 {
switch (SDLNet_Read16(&packet)) 311 197 switch (SDLNet_Read16(&packet))
{ 312 198 {
case PLAYER_MOV: 313 199 case PLAYER_MOV:
puts("PLAYER_MOV"); 314 200 puts("PLAYER_MOV");
pnum = getshort(srv_sock); 315 201 pnum = getshort(srv_sock);
movx = getshort(srv_sock); 316 202 movx = getshort(srv_sock);
movy = getshort(srv_sock); 317 203 movy = getshort(srv_sock);
318 204
printf("player %d moved to (%d,%d)\n", 319 205 printf("player %d moved to (%d,%d)\n",
pnum, movx, movy); 320 206 pnum, movx, movy);
movePlayer(choose_player(player,pnum), movx, movy); 321 207 movePlayer(choose_player(player,pnum), movx, movy);
break; 322 208 break;
case PLAYER_WIN: 323 209 case PLAYER_WIN:
puts("PLAYER_WIN"); 324 210 puts("PLAYER_WIN");
break; 325 211 break;
server/server.c View file @ a2eea9f
#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
15
void begin_game(Player_set *pset); 16
17
int sendMov(int psock, short int movepno, int x, int y); 18
19
void broadcast_disconnect(Player_set *pset, int fd); 20
21
void * 22 15 void *
get_in_addr(struct sockaddr *sa) 23 16 get_in_addr(struct sockaddr *sa)
{ 24 17 {
if (sa->sa_family == AF_INET) 25 18 if (sa->sa_family == AF_INET)
{ 26 19 {
return &(((struct sockaddr_in*)sa)->sin_addr); 27 20 return &(((struct sockaddr_in*)sa)->sin_addr);
} 28 21 }
29 22
return &(((struct sockaddr_in6*)sa)->sin6_addr); 30 23 return &(((struct sockaddr_in6*)sa)->sin6_addr);
} 31 24 }
32 25
33 26
size_t 34 27 size_t
sendall(int s, char *buf, size_t len) 35 28 sendall(int s, char *buf, size_t len)
{ 36 29 {
int total = 0; // how many bytes we've sent 37 30 int total = 0; // how many bytes we've sent
int bytesleft = len; // how many we have left to send 38 31 int bytesleft = len; // how many we have left to send
int n; 39 32 int n;
40 33
while(total < len) 41 34 while(total < len)
{ 42 35 {
n = send(s, buf+total, bytesleft, 0); 43 36 n = send(s, buf+total, bytesleft, 0);
44 37
if (n == -1) 45 38 if (n == -1)
{ 46 39 {
perror("sendall"); 47 40 perror("sendall");
return total; 48 41 return total;
} 49 42 }
50 43
total += n; 51 44 total += n;
bytesleft -= n; 52 45 bytesleft -= n;
} 53 46 }
return total; 54 47 return total;
} 55 48 }
56 49
57 50
size_t 58 51 size_t
recvall(int s, char *buf, size_t len) 59 52 recvall(int s, char *buf, size_t len)
{ 60 53 {
int total = 0; 61 54 int total = 0;
int bytesleft = len; 62 55 int bytesleft = len;
int n; 63 56 int n;
64 57
while (total < len) 65 58 while (total < len)
{ 66 59 {
if ((n = recv(s, buf, bytesleft, 0)) == -1) 67 60 if ((n = recv(s, buf, bytesleft, 0)) == -1)
{ 68 61 {
perror("recvall"); 69 62 perror("recvall");
return total; 70 63 return total;
} 71 64 }
total += n; 72 65 total += n;
bytesleft -= n; 73 66 bytesleft -= n;
} 74 67 }
return total; 75 68 return total;
} 76 69 }
77 70
78 71
short 79 72 short
getshort(int sock) 80 73 getshort(int sock)
{ 81 74 {
short ret; 82 75 short ret;
recvall(sock, (char *) &ret, sizeof(short)); 83 76 recvall(sock, (char *) &ret, sizeof(short));
84 77
return ntohs(ret); 85 78 return ntohs(ret);
} 86 79 }
87 80
size_t 88 81 size_t
sendshort(int sock, short s) 89 82 sendshort(int sock, short s)
{ 90 83 {
s = htons(s); 91 84 s = htons(s);
return send(sock, &s, sizeof(s), 0); 92 85 return send(sock, &s, sizeof(s), 0);
} 93 86 }
94 87
int 95 88 int
main(int argc, char *argv[]) 96 89 main(int argc, char *argv[])
{ 97 90 {
int ssockfd, csockfd, err;; 98 91 int ssockfd, csockfd, err;;
unsigned short magic, x, y; 99 92 unsigned short magic, x, y;
unsigned int u; 100 93 unsigned int u;
struct addrinfo hints, *srvinfo, *p; 101 94 struct addrinfo hints, *srvinfo, *p;
struct sockaddr_storage caddr; 102 95 struct sockaddr_storage caddr;
socklen_t addr_size; 103 96 socklen_t addr_size;
size_t len, bytes_sent; 104 97 size_t len, bytes_sent;
Player_set *pset; 105 98 Player_set *pset;
106 99
int i, j; 107 100 int i, j;
108 101
/* For handling multiple clients using select() */ 109 102 /* For handling multiple clients using select() */
110 103
fd_set master; 111 104 fd_set master;
fd_set read_fds; /* File descriptors with readable data */ 112 105 fd_set read_fds; /* File descriptors with readable data */
int fdmax; /* Highest file descriptor in the master set */ 113 106 int fdmax; /* Highest file descriptor in the master set */
int newfd; /* File descriptor for handling incoming connections */ 114 107 int newfd; /* File descriptor for handling incoming connections */
char buf[256]; 115 108 char buf[256];
int nbytes; 116 109 int nbytes;
char remoteIP[INET6_ADDRSTRLEN]; 117 110 char remoteIP[INET6_ADDRSTRLEN];
118 111
int players_connected = 0; 119 112 int players_connected = 0;
time_t launchtime = 0; 120 113 time_t launchtime = 0;
unsigned char game_started = 0; 121 114 unsigned char game_started = 0;
122 115
/* Should be moved to config file/cli arg ALONG WITH hostname/port */ 123 116 /* Should be moved to config file/cli arg ALONG WITH hostname/port */
int min_players = 2; 124 117 int min_players = 2;
time_t time_thresh = 2; 125 118 time_t time_thresh = 2;
126 119
FD_ZERO(&master); /* Empty the master set */ 127 120 FD_ZERO(&master); /* Empty the master set */
FD_ZERO(&read_fds); /* Empty the readfds set */ 128 121 FD_ZERO(&read_fds); /* Empty the readfds set */
pset = calloc(1, sizeof(Player_set)); 129 122 pset = calloc(1, sizeof(Player_set));
130 123
genmaze(20, 20); 131 124 genmaze(20, 20);
memset(&hints, 0, sizeof(hints)); 132 125 memset(&hints, 0, sizeof(hints));
133 126
/* Currently using TCP. */ 134 127 /* Currently using TCP. */
hints.ai_family = AF_UNSPEC; 135 128 hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_PASSIVE; 136 129 hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM; 137 130 hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP; 138 131 hints.ai_protocol = IPPROTO_TCP;
139 132
if ((err = getaddrinfo(MOTSRV_ADDR, MOTSRV_PORT, &hints, &srvinfo))) 140 133 if ((err = getaddrinfo(MOTSRV_ADDR, MOTSRV_PORT, &hints, &srvinfo)))
{ 141 134 {
fprintf(stderr, "Failed to get address: %s\n", gai_strerror(err)); 142 135 fprintf(stderr, "Failed to get address: %s\n", gai_strerror(err));
return 10; 143 136 return 10;
} 144 137 }
145 138
/* 146 139 /*
* Allocate socket file descriptor with address information acquired 147 140 * Allocate socket file descriptor with address information acquired
* from getaddrinfo. 148 141 * from getaddrinfo.
*/ 149 142 */
150 143
if (ssockfd == -1) 151 144 if (ssockfd == -1)
{ 152 145 {
perror("Failed to allocate server socket descriptor."); 153 146 perror("Failed to allocate server socket descriptor.");
return 7; 154 147 return 7;
} 155 148 }
156 149
for (p = srvinfo; p != NULL; p = p->ai_next) 157 150 for (p = srvinfo; p != NULL; p = p->ai_next)
{ 158 151 {
ssockfd = socket( p->ai_family, p->ai_socktype, p->ai_protocol); 159 152 ssockfd = socket( p->ai_family, p->ai_socktype, p->ai_protocol);
160 153
if( ssockfd < 0 ) 161 154 if( ssockfd < 0 )
{ 162 155 {
continue; 163 156 continue;
} 164 157 }
165 158
/* 166 159 /*
* If system thinks the socket is on use but it isn't, fix it... 167 160 * If system thinks the socket is on use but it isn't, fix it...
*/ 168 161 */
setsockopt(ssockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int)); 169 162 setsockopt(ssockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int));
170 163
/* 171 164 /*
* Bind socket to port. 172 165 * Bind socket to port.
*/ 173 166 */
if (bind(ssockfd, p->ai_addr, p->ai_addrlen) < 0) 174 167 if (bind(ssockfd, p->ai_addr, p->ai_addrlen) < 0)
{ 175 168 {
close(ssockfd); 176 169 close(ssockfd);
continue; 177 170 continue;
} 178 171 }
179 172
break; 180 173 break;
} 181 174 }
182 175
183 176
/* 184 177 /*
* If p reached NULL, it means we didn't bind at all. 185 178 * If p reached NULL, it means we didn't bind at all.
*/ 186 179 */
187 180
if (p == NULL) 188 181 if (p == NULL)
{ 189 182 {
fprintf( stderr, "failed to bind ssockfd\n" ); 190 183 fprintf( stderr, "failed to bind ssockfd\n" );
return 2; 191 184 return 2;
} 192 185 }
193 186
freeaddrinfo(srvinfo); 194 187 freeaddrinfo(srvinfo);
195 188
/* 196 189 /*
* Start listening on server socket descriptor. 197 190 * Start listening on server socket descriptor.
*/ 198 191 */
199 192
if (listen(ssockfd, BACKLOG ) == -1) 200 193 if (listen(ssockfd, BACKLOG ) == -1)
{ 201 194 {
perror("Server can't listen."); 202 195 perror("Server can't listen.");
return 3; 203 196 return 3;
} 204 197 }
205 198
/* 206 199 /*
* Add ssockfd to master set of sockets. 207 200 * Add ssockfd to master set of sockets.
*/ 208 201 */
FD_SET(ssockfd, &master); 209 202 FD_SET(ssockfd, &master);
210 203
/* 211 204 /*
* Since ssockfd is currently the only socket in master, 212 205 * Since ssockfd is currently the only socket in master,
* it's the highest descriptor. 213 206 * it's the highest descriptor.
*/ 214 207 */
fdmax = ssockfd; 215 208 fdmax = ssockfd;
216 209
217 210
while (1) 218 211 while (1)
{ 219 212 {
read_fds = master; 220 213 read_fds = master;
221 214
if (select(fdmax + 1, &read_fds, NULL, NULL, NULL ) == -1) 222 215 if (select(fdmax + 1, &read_fds, NULL, NULL, NULL ) == -1)
{ 223 216 {
perror("select"); 224 217 perror("select");
return 4; 225 218 return 4;
} 226 219 }
227 220
/* 228 221 /*
* Now read_fds has only those sockets that have readable data to 229 222 * Now read_fds has only those sockets that have readable data to
* show. 230 223 * show.
* Run through all the sockets to find data to read. 231 224 * Run through all the sockets to find data to read.
*/ 232 225 */
233 226
for (i = 0; i <= fdmax; i++) 234 227 for (i = 0; i <= fdmax; i++)
{ 235 228 {
if (!FD_ISSET(i, &read_fds)) 236 229 if (!FD_ISSET(i, &read_fds))
{ 237 230 {
continue; 238 231 continue;
} 239 232 }
240 233
/* If we're here, i has data to show */ 241 234 /* If we're here, i has data to show */
if (i == ssockfd) 242 235 if (i == ssockfd)
{ 243 236 {
/* Handle new connections. */ 244 237 /* Handle new connections. */
245 238
addr_size = sizeof caddr; 246 239 addr_size = sizeof caddr;
newfd = accept(ssockfd, 247 240 newfd = accept(ssockfd,
(struct sockaddr *) &caddr, &addr_size); 248 241 (struct sockaddr *) &caddr, &addr_size);
249 242
if (newfd == -1) 250 243 if (newfd == -1)
{ 251 244 {
perror("accept"); 252 245 perror("accept");
continue; 253 246 continue;
} 254 247 }
255 248
/* Add the new socket descriptor to master. */ 256 249 /* Add the new socket descriptor to master. */
FD_SET(newfd, &master); 257 250 FD_SET(newfd, &master);
258 251
if (newfd > fdmax) 259 252 if (newfd > fdmax)
{ 260 253 {
fdmax = newfd; 261 254 fdmax = newfd;
} 262 255 }
printf("server: new connection from %s on socket %d\n", 263 256 printf("server: new connection from %s on socket %d\n",
inet_ntop(caddr.ss_family, 264 257 inet_ntop(caddr.ss_family,
get_in_addr((struct sockaddr*)&caddr), 265 258 get_in_addr((struct sockaddr*)&caddr),
remoteIP, INET6_ADDRSTRLEN), newfd ); 266 259 remoteIP, INET6_ADDRSTRLEN), newfd );
267 260
if (game_started) 268 261 if (game_started)
{ 269 262 {
magic = htons(SRV_BUSY); 270 263 magic = htons(SRV_BUSY);
sendshort(newfd, magic); 271 264 sendshort(newfd, magic);
close(newfd); 272 265 close(newfd);
FD_CLR(newfd, &master); 273 266 FD_CLR(newfd, &master);
continue; 274 267 continue;
} 275 268 }
276 269
printf("checking if game started!!\n"); 277 270 printf("checking if game started!!\n");
278 271
if (!launchtime) launchtime = time(NULL); 279 272 if (!launchtime) launchtime = time(NULL);
280 273
players_connected++; 281 274 players_connected++;
handle_connecting_player(newfd, pset); 282 275 handle_connecting_player(newfd, pset);
283 276
printf("new connection handled!!\n"); 284 277 printf("new connection handled!!\n");
if (time(NULL) - launchtime >= time_thresh && 285 278 if (time(NULL) - launchtime >= time_thresh &&
players_connected >= min_players) 286 279 players_connected >= min_players)
{ 287 280 {
printf("game started!!\n"); 288 281 printf("game started!!\n");
begin_game(pset); 289 282 begin_game(pset);
game_started = 1; 290 283 game_started = 1;
} 291 284 }
} 292 285 }
else 293 286 else
{ 294 287 {
/* Handle data from a client. (ONLY A SHORT/magic no) */ 295 288 /* Handle data from a client. (ONLY A SHORT/magic no) */
296 289
if ((nbytes = recv(i, &magic, sizeof magic, 0 )) <= 0) 297 290 if ((nbytes = recv(i, &magic, sizeof magic, 0 )) <= 0)
{ 298 291 {
if (nbytes == 0) 299 292 if (nbytes == 0)
{ 300 293 {
printf("server: socket %d hung up\n", i); 301 294 printf("server: socket %d hung up\n", i);
broadcast_disconnect(pset, i); 302 295 broadcast_disconnect(pset, i);
if(--players_connected < min_players) 303
{ 304
printf("too few players, accepting more players now\n"); 305
306
/* DON'T HALT THE GAME, THOUGH */ 307
game_started = 0; 308
} 309
} 310 296 }
else 311 297 else
{ 312 298 {
perror("recv"); 313 299 perror("recv");
} 314 300 }
close(i); 315 301 close(i);
FD_CLR(i, &master); 316 302 FD_CLR(i, &master);
continue; 317 303 continue;
} 318 304 }
switch (htons(magic)) 319 305 switch (htons(magic))
{ 320 306 {
case PLAYER_MOV: 321 307 case PLAYER_MOV:
x = getshort(i); 322 308 x = getshort(i);
y = getshort(i); 323 309 y = getshort(i);
printf("player with socket %d moved to %d, %d\n", 324 310 printf("player with socket %d moved to %d, %d\n",
i, x, y); 325 311 i, x, y);
/* 326 312 /*
* now send it to everyone. non blocking TCP? 327 313 * now send it to everyone. non blocking TCP?
* broadcast function? 328 314 * broadcast function?
*/ 329 315 */
break; 330 316 break;
} 331 317 }
332 318
/* we got some data to read,son */ 333 319 /* we got some data to read,son */
334 320
for (j = 0; j <= fdmax; j++) 335 321 for (j = 0; j <= fdmax; j++)
{ 336 322 {
if (FD_ISSET(j, &master)) 337 323 if (FD_ISSET(j, &master))
{ 338 324 {
/* 339 325 /*
* don't send it to server and the client 340 326 * don't send it to server and the client
* who sent the data 341 327 * who sent the data
*/ 342 328 */
343 329
Player *justMoved = player_byfd(pset,i); 344 330 Player *justMoved = player_byfd(pset,i);
int movPnum = justMoved->playerno; 345 331 int movPnum = justMoved->playerno;
346 332
if (j != ssockfd 347 333 if (j != ssockfd
&& j != i 348 334 && j != i
&& sendMov(j,movPnum,x,y) == -1) 349 335 && sendMov(j,movPnum,x,y) == -1)
{ 350 336 {
perror("send"); 351 337 perror("send");
} 352 338 }
} 353 339 }
} 354 340 }
355 341
} 356 342 }
} 357 343 }
} 358 344 }
359 345
360 346
/* 361 347 /*
* Free things (sockets, addrinfo, player data, maze) and exit. 362 348 * Free things (sockets, addrinfo, player data, maze) and exit.
*/ 363 349 */
close(ssockfd); 364 350 close(ssockfd);
close(csockfd); 365 351 close(csockfd);
freeaddrinfo(srvinfo); 366 352 freeaddrinfo(srvinfo);
free(MAZE.data); 367 353 free(MAZE.data);
368 354
return 0; 369 355 return 0;
} 370 356 }
371 357
void 372 358 void
handle_connecting_player(int newfd, Player_set *pset) 373 359 handle_connecting_player(int newfd, Player_set *pset)
{ 374 360 {
char *pname; 375 361 char *pname;
unsigned char pnum; 376 362 unsigned char pnum;
unsigned short magic; 377 363 unsigned short magic;
unsigned int u; 378 364 unsigned int u;
379 365
/* 380 366 /*
* When a player first connects, send maze magic, data width, size. 381 367 * When a player first connects, send maze magic, data width, size.
* Then send the maze itself. Then await confirmation. 382 368 * Then send the maze itself. Then await confirmation.
*/ 383 369 */
384 370
add_player(pset); 385 371 add_player(pset);
magic = htons(MAZE_MAGIC); 386 372 magic = htons(MAZE_MAGIC);
sendall(newfd, (char *) &magic, sizeof(magic)); 387 373 sendall(newfd, (char *) &magic, sizeof(magic));
388 374
/* Maze width */ 389 375 /* Maze width */
u = htonl(MAZE.w); 390 376 u = htonl(MAZE.w);
sendall(newfd, (char *) &u, sizeof(u)); 391 377 sendall(newfd, (char *) &u, sizeof(u));
392 378
u = htonl(MAZE.size); 393 379 u = htonl(MAZE.size);
sendall(newfd, (char *) &u, sizeof(u)); 394 380 sendall(newfd, (char *) &u, sizeof(u));
395 381
sendall(newfd, (char *) MAZE.data, MAZE.size); 396 382 sendall(newfd, (char *) MAZE.data, MAZE.size);
397 383
if (recv(newfd, &magic, sizeof(magic), 0) != sizeof(magic) 398 384 if (recv(newfd, &magic, sizeof(magic), 0) != sizeof(magic)
|| ntohs(magic) != MAZE_MAGIC) 399 385 || ntohs(magic) != MAZE_MAGIC)
{ 400 386 {
fprintf(stderr, "Failed to get client confirmation\n"); 401 387 fprintf(stderr, "Failed to get client confirmation\n");
exit(1); 402 388 exit(1);
} 403 389 }
404 390
pname = malloc(PNAMELEN); 405 391 pname = malloc(PNAMELEN);
recvall(newfd, pname, PNAMELEN); 406 392 recvall(newfd, pname, PNAMELEN);
printf("%s connected !!!\n", pname); 407 393 printf("%s connected !!!\n", pname);
408 394
sendall(newfd, (char *) &pset->last->playerno, sizeof(pnum)); 409 395 sendall(newfd, (char *) &pset->last->playerno, sizeof(pnum));
410 396
pset->last->name = pname; 411 397 pset->last->name = pname;
pset->last->x = -1; 412 398 pset->last->x = -1;
pset->last->y = -1; 413 399 pset->last->y = -1;
pset->last->fd = newfd; 414 400 pset->last->fd = newfd;
printf("new file descriptor:%d and %d\n", pset->last->fd,newfd); 415 401 printf("new file descriptor:%d and %d\n", pset->last->fd,newfd);
} 416 402 }
417 403
static void 418 404 static void
send_dc(Player *p, int pno_removed) 419 405 send_dc(Player *p, int pno_removed)
{ 420 406 {
sendshort(p->fd, PLAYER_DC); 421 407 sendshort(p->fd, PLAYER_DC);
sendshort(p->fd, pno_removed); 422 408 sendshort(p->fd, pno_removed);
} 423 409 }
424 410
void 425 411 void
broadcast_disconnect(Player_set *pset, int fd) 426 412 broadcast_disconnect(Player_set *pset, int fd)
{ 427 413 {
Player *to_remove = player_byfd(pset, fd); 428 414 Player *to_remove = player_byfd(pset, fd);
int remove_pno = to_remove->playerno; 429 415 int remove_pno = to_remove->playerno;
rm_player(pset, to_remove); 430 416 rm_player(pset, to_remove);
pset_map(pset, &send_dc, remove_pno); 431 417 pset_map(pset, &send_dc, remove_pno);
} 432 418 }
433 419
int 434 420 int
check_collision(Player_set *pset, Player* node) 435 421 check_collision(Player_set *pset, Player* node)
{ 436 422 {
if (node == pset->first) 437 423 if (node == pset->first)
return 1; 438 424 return 1;
Player *temp; 439 425 Player *temp;
for(temp = pset->first; temp != NULL && temp != node; temp = temp->next) 440 426 for(temp = pset->first; temp != NULL && temp != node; temp = temp->next)
{ 441 427 {
if(temp->x == node->x && temp->y == node->y) 442 428 if(temp->x == node->x && temp->y == node->y)
return 0; 443 429 return 0;
} 444 430 }
return 1; 445 431 return 1;
} 446 432 }
447 433
448 434
void 449 435 void
set_positions(Player_set *pset) 450 436 set_positions(Player_set *pset)
{ 451 437 {
Player *temp; 452 438 Player *temp;
for(temp = pset->first; temp != NULL; temp = temp->next) 453 439 for(temp = pset->first; temp != NULL; temp = temp->next)
{ 454 440 {
do 455 441 do
{ 456 442 {
temp->x = mrand(0,19) * 2; 457 443 temp->x = mrand(0,19) * 2;
temp->y = mrand(0,19) * 2; 458 444 temp->y = mrand(0,19) * 2;
}while(!check_collision(pset,temp)); 459 445 }while(!check_collision(pset,temp));
server/server.h View file @ a2eea9f
#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
50 void begin_game(Player_set *pset);
51 int sendMov(int psock, short int movepno, int x, int y);
52 void broadcast_disconnect(Player_set *pset, int fd);
53