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