Commit 989be69d260632e1884ad955f554861eda3a3405
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
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 |