Commit 989be69d260632e1884ad955f554861eda3a3405

Authored by Pedro L Coutin
Exists in master

merging rohan into main 1

Showing 7 changed files Inline Diff

client/Makefile View file @ 989be69
CC= clang 1 1 CC= clang
CFLAGS= -Wall -O2 -c -I/usr/local/include 2 2 CFLAGS= -Wall -O0 -g -c -I/usr/local/include
LDFLAGS= -L/usr/local/lib -lGL -lSDL2 -lSDL2_image -lSDL2_net 3 3 LDFLAGS= -L/usr/local/lib -lGL -lSDL2 -lSDL2_image -lSDL2_net
4 4
OBJFILES= main.o cfg.o maze.o picture.o player.o ini.o net.o 5 5 OBJFILES= main.o cfg.o maze.o picture.o player.o ini.o net.o
6 6
all: mot 7 7 all: mot
8 8
mot: ${OBJFILES} 9 9 mot: ${OBJFILES}
${CC} ${LDFLAGS} -o mot ${OBJFILES} 10 10 ${CC} ${LDFLAGS} -o mot ${OBJFILES}
11 11
main.o: main.c 12 12 main.o: main.c
${CC} ${CFLAGS} main.c 13 13 ${CC} ${CFLAGS} main.c
14 14
cfg.o: cfg.c 15 15 cfg.o: cfg.c
${CC} ${CFLAGS} cfg.c 16 16 ${CC} ${CFLAGS} cfg.c
17 17
maze.o: entities/maze.c 18 18 maze.o: entities/maze.c
${CC} ${CFLAGS} entities/maze.c 19 19 ${CC} ${CFLAGS} entities/maze.c
20 20
ini.o: ../common/inih/ini.c 21 21 ini.o: ../common/inih/ini.c
cd ../common/inih; cc -Os -o ../../client/ini.o -c ini.c 22 22 cd ../common/inih; cc -Os -o ../../client/ini.o -c ini.c
23 23
player.o: entities/player.c 24 24 player.o: entities/player.c
client/entities/entities.h View file @ 989be69
#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 @ 989be69
#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 @ 989be69
/* 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
101
do 102
{ 103
cur_player = calloc(1,sizeof(PLAYER)); 104
init_player(srv_sock,cur_player); 105
add_player(node,cur_player); 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
int 130 17 int
main(int argc, char *argv[]) 131 18 main(int argc, char *argv[])
{ 132 19 {
SDL_Window *window; 133 20 SDL_Window *window;
CLC_CONFIG config; 134 21 CLC_CONFIG config;
Uint8 *kbdstate; 135 22 Uint8 *kbdstate;
SDL_Event e; 136 23 SDL_Event e;
PLAYER *me; 137 24 PLAYER *me;
PLAYER *player; 138 25 PLAYER *player;
Uint32 time; 139 26 Uint32 time;
IPaddress srv_ip; 140 27 IPaddress srv_ip;
TCPsocket srv_sock; 141 28 TCPsocket srv_sock;
Uint16 magic; 142 29 Uint16 magic;
int i; 143 30 int i;
SDLNet_SocketSet srv_sset; 144 31 SDLNet_SocketSet srv_sset;
char myname[PNAME_SIZE]; 145 32 char myname[PNAME_SIZE];
unsigned char myno; 146 33 unsigned char myno;
147 34
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS) == -1) 148 35 if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS) == -1)
{ 149 36 {
fprintf(stderr, "SDL_Init: %s\n", SDL_GetError()); 150 37 fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
exit(EXIT_FAILURE); 151 38 exit(EXIT_FAILURE);
} 152 39 }
153 40
if (SDLNet_Init() == -1) 154 41 if (SDLNet_Init() == -1)
{ 155 42 {
fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError()); 156 43 fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 157 44 exit(EXIT_FAILURE);
} 158 45 }
159 46
parsecfg(&config); 160 47 parsecfg(&config);
161 48
/* 162 49 /*
* Get player name. 163 50 * Get player name.
*/ 164 51 */
printf("Wow such name: "); 165 52 printf("Wow such name: ");
fgets(myname, PNAME_SIZE, stdin); 166 53 fgets(myname, PNAME_SIZE, stdin);
167 54
for (i = 0; i < PNAME_SIZE; i++) 168 55 for (i = 0; i < PNAME_SIZE; i++)
{ 169 56 {
if (myname[i] == '\n') 170 57 if (myname[i] == '\n')
{ 171 58 {
myname[i] = '\0'; 172 59 myname[i] = '\0';
break; 173 60 break;
} 174 61 }
} 175 62 }
176 63
177 64
/* 178 65 /*
* Connect to server! 179 66 * Connect to server!
*/ 180 67 */
if (SDLNet_ResolveHost(&srv_ip, config.defaultsrv, 181 68 if (SDLNet_ResolveHost(&srv_ip, config.defaultsrv,
atoi(config.defaultport))) 182 69 atoi(config.defaultport)))
{ 183 70 {
fprintf(stderr, "SDLNet_ResolveHost: %s\n", SDLNet_GetError()); 184 71 fprintf(stderr, "SDLNet_ResolveHost: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 185 72 exit(EXIT_FAILURE);
} 186 73 }
187 74
188 75
/* 189 76 /*
* Bind socket! 190 77 * Bind socket!
*/ 191 78 */
if (!(srv_sock = SDLNet_TCP_Open(&srv_ip))) 192 79 if (!(srv_sock = SDLNet_TCP_Open(&srv_ip)))
{ 193 80 {
fprintf(stderr, "SDLNet_TCP_Open: %s\n", SDLNet_GetError()); 194 81 fprintf(stderr, "SDLNet_TCP_Open: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 195 82 exit(EXIT_FAILURE);
} 196 83 }
197 84
198 85
/* 199 86 /*
* Add (a single) server socket to srv_sset for cheap hack for checking 200 87 * Add (a single) server socket to srv_sset for cheap hack for checking
* the server socket's state. 201 88 * the server socket's state.
*/ 202 89 */
srv_sset = SDLNet_AllocSocketSet(1); 203 90 srv_sset = SDLNet_AllocSocketSet(1);
204 91
if (!srv_sset) 205 92 if (!srv_sset)
{ 206 93 {
printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError()); 207 94 printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError());
exit(EXIT_FAILURE); 208 95 exit(EXIT_FAILURE);
} 209 96 }
210 97
SDLNet_TCP_AddSocket(srv_sset, srv_sock); 211 98 SDLNet_TCP_AddSocket(srv_sset, srv_sock);
212 99
213 100
/* 214 101 /*
* Get maze, add connecting players to buffer and wait until the game 215 102 * Get maze, add connecting players to buffer and wait until the game
* begins. 216 103 * begins.
*/ 217 104 */
218 105
getmaze(srv_sock); 219 106 getmaze(srv_sock);
220 107
window = SDL_CreateWindow( 221 108 window = SDL_CreateWindow(
"MAZE OF TORMENT", 222 109 "MAZE OF TORMENT",
SDL_WINDOWPOS_UNDEFINED, 223 110 SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 224 111 SDL_WINDOWPOS_UNDEFINED,
config.win_width, 225 112 config.win_width,
config.win_height, 226 113 config.win_height,
config.win_flags 227 114 config.win_flags
); 228 115 );
229 116
SDL_GetWindowSize(window, &config.win_width, &config.win_height); 230 117 SDL_GetWindowSize(window, &config.win_width, &config.win_height);
231 118
if (window == NULL) 232 119 if (window == NULL)
{ 233 120 {
fprintf(stderr, "Could not create window: %s\n", 234 121 fprintf(stderr, "Could not create window: %s\n",
SDL_GetError()); 235 122 SDL_GetError());
exit(EXIT_FAILURE); 236 123 exit(EXIT_FAILURE);
} 237 124 }
238 125
renderer = SDL_CreateRenderer(window, -1, config.renderflags); 239 126 renderer = SDL_CreateRenderer(window, -1, config.renderflags);
240 127
hsprite = loadPic("img/predator.gif"); 241 128 hsprite = loadPic("img/predator.gif");
psprite = loadPic("img/prey.gif"); 242 129 psprite = loadPic("img/prey.gif");
black = loadPic("img/black.gif"); 243 130 black = loadPic("img/black.gif");
244 131
/* 245 132 /*
* Initialize maze, and send player name. 246 133 * Initialize maze, and send player name.
*/ 247 134 */
MAZE.X = (config.win_width - MAZE.w * 16) / 2; 248 135 MAZE.X = (config.win_width - MAZE.w * 16) / 2;
MAZE.Y = (config.win_height - MAZE.h * 16) / 2; 249 136 MAZE.Y = (config.win_height - MAZE.h * 16) / 2;
250 137
SDLNet_TCP_Send(srv_sock, myname, PNAME_SIZE); 251 138 SDLNet_TCP_Send(srv_sock, myname, PNAME_SIZE);
252 139
253 140
/* 254 141 /*
* Initialize maze and get the LOCAL player, then the REMOTE players. 255 142 * Initialize maze and get the LOCAL player, then the REMOTE players.
*/ 256 143 */
257 144
SDLNet_TCP_Recv(srv_sock, &myno, 1); 258 145 SDLNet_TCP_Recv(srv_sock, &myno, 1);
player = calloc(1, sizeof(PLAYER)); 259 146 player = calloc(1, sizeof(PLAYER));
draw_maze(MAZE.X, MAZE.Y); 260
261 147
262 148 if (!((magic = getshort(srv_sock)) == ADD_PLAYER))
if(!((magic = getshort(srv_sock)) == ADD_PLAYER)) 263
{ 264 149 {
printf("server not sending players\n!"); 265 150 printf("server not sending players\n!");
exit(EXIT_FAILURE); 266 151 exit(EXIT_FAILURE);
} 267 152 }
153
unsigned char hunter = addp(player,srv_sock); 268 154 unsigned char hunter = addp(player,srv_sock);
155
choose_hunter(player,hunter); 269 156 choose_hunter(player,hunter);
me = choose_player(player,myno); 270 157 me = choose_player(player,myno);
158
159 SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
draw_maze(MAZE.X, MAZE.Y); 271 160 draw_maze(MAZE.X, MAZE.Y);
161
PLAYER *temp; 272 162 PLAYER *temp;
163
for (temp = player->next; temp != NULL; temp = temp->next) 273 164 for (temp = player->next; temp != NULL; temp = temp->next)
{ 274 165 {
printf("drew player %d\n", temp->playerno); 275 166 printf("drew player %d\n", temp->playerno);
drawPlayer(temp); 276 167 drawPlayer(temp);
} 277 168 }
278 169
printf("starting game!!\n"); 279 170 printf("starting game!!\n");
/* 280 171 /*
* Game loop! 281 172 * Game loop!
*/ 282 173 */
283 174
for (;;) 284 175 for (;;)
{ 285 176 {
time = SDL_GetTicks(); 286 177 time = SDL_GetTicks();
287 178
/* 288 179 /*
* Poll the network in each frame. Because. 289 180 * Poll the network in each frame. Because.
*/ 290 181 */
291 182
int numready = SDLNet_CheckSockets(srv_sset, 0); 292 183 int numready = SDLNet_CheckSockets(srv_sset, 0);
293 184
if (numready == -1) 294 185 if (numready == -1)
{ 295 186 {
printf("SDLNet_CheckSockets: %s\n", SDLNet_GetError()); 296 187 printf("SDLNet_CheckSockets: %s\n", SDLNet_GetError());
perror("SDLNet_CheckSockets"); 297 188 perror("SDLNet_CheckSockets");
} 298 189 }
else if (numready) 299 190 else if (numready)
{ 300 191 {
unsigned char packet, hunter; 301 192 unsigned char packet, hunter;
unsigned char pnum, movx, movy; 302 193 unsigned char pnum, movx, movy;
printf("srv socket is ready!!\n"); 303 194 printf("srv socket is ready!!\n");
if (SDLNet_TCP_Recv(srv_sock, &packet, 2) == 2) 304 195 if (SDLNet_TCP_Recv(srv_sock, &packet, 2) == 2)
{ 305 196 {
switch (SDLNet_Read16(&packet)) 306 197 switch (SDLNet_Read16(&packet))
{ 307 198 {
case PLAYER_MOV: 308 199 case PLAYER_MOV:
puts("PLAYER_MOV"); 309 200 puts("PLAYER_MOV");
pnum = getshort(srv_sock); 310 201 pnum = getshort(srv_sock);
movx = getshort(srv_sock); 311 202 movx = getshort(srv_sock);
movy = getshort(srv_sock); 312 203 movy = getshort(srv_sock);
313 204
printf("player %d moved to (%d,%d)\n", 314 205 printf("player %d moved to (%d,%d)\n",
pnum, movx, movy); 315 206 pnum, movx, movy);
movePlayer(choose_player(player,pnum), movx, movy); 316 207 movePlayer(choose_player(player,pnum), movx, movy);
break; 317 208 break;
case PLAYER_WIN: 318 209 case PLAYER_WIN:
puts("PLAYER_WIN"); 319 210 puts("PLAYER_WIN");
break; 320 211 break;
case PLAYER_DC: 321 212 case PLAYER_DC:
puts("PLAYER_DC"); 322 213 puts("PLAYER_DC");
pnum = getshort(srv_sock); 323 214 pnum = getshort(srv_sock);
printf("Player %d disconnected!!\n", pnum); 324 215 printf("Player %d disconnected!!\n", pnum);
removep(choose_player(player,pnum)); 325 216 removep(choose_player(player,pnum));
break; 326 217 break;
case ADD_PLAYER: 327 218 case ADD_PLAYER:
printf("ADD_PLAYER\n"); 328 219 printf("ADD_PLAYER\n");
hunter = addp(player,srv_sock); 329 220 hunter = addp(player,srv_sock);
choose_hunter(player,hunter); 330 221 choose_hunter(player,hunter);
me = choose_player(player,myno); 331 222 me = choose_player(player,myno);
draw_maze(MAZE.X, MAZE.Y); 332 223 draw_maze(MAZE.X, MAZE.Y);
client/maze.dat View file @ 989be69

No preview for this file type

server/server.c View file @ 989be69
#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 @ 989be69
#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