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