diff --git a/src/Makefile b/src/Makefile index 9a5d194..421c672 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1 +1,3 @@ -CFLAGS=-g -std=c99 -Wall -pedantic +CFLAGS=-g -std=gnu99 -Wall -pedantic + +server: server.o net.o diff --git a/src/net.c b/src/net.c index 3e57328..4caacb8 100644 --- a/src/net.c +++ b/src/net.c @@ -10,6 +10,9 @@ #include #include #include +#include + +#include "net.h" #define MAX_CLIENTS 2 #define SRV_FDS 1 @@ -18,10 +21,14 @@ int servsock; struct pollfd pollfds[SRV_FDS+MAX_CLIENTS]; int nclients = 0; +FILE *net_side[2]; + int errx(int eval, const char *fmt, ...) { va_list ap; + va_start(ap, fmt); vfprintf(stderr, fmt, ap); + va_end(ap); exit(eval); } @@ -31,22 +38,77 @@ net_server(int port) { serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons(port); - + + servsock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (servsock<0) - errx(1, "socket: %s", strerror(errno)); - if (bind(servsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) - errx(1, "bind port %d: %s", port, strerror(errno)); + errx(1, "socket: %s\n", strerror(errno)); + int r; + do r=bind(servsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); + while ((r<0) && (errno==EADDRINUSE)); + if (r < 0) + errx(1, "bind port %d: %s\n", port, strerror(errno)); if (listen(servsock, 10) < 0) - errx(1, "listen: %s", strerror(errno)); + errx(1, "listen: %s\n", strerror(errno)); +#if 1 + // FIXME Temporary startup. Use net_poll for this later: + printf("Waiting for connections...\n"); + for (int i=0; i<2; i++) { + struct sockaddr_in clientaddr; + int cfd; + socklen_t slen; + FILE *f; + cfd=accept(servsock, (struct sockaddr *)&clientaddr, &slen); + if (cfd<0) + errx(1, "accept: %s\n", strerror(errno)); + // FIXME log, shout, or something + printf("client log on...\n"); + f = fdopen(cfd, "r+"); + if (!f) + errx(1, "fdopen: %s\n", strerror(errno)); + setlinebuf(f); + fprintf(f, "Welcome!\n"); + if (i==0) + fprintf(f, "Waiting for another player...\n"); + fflush(f); + net_side[i]=f; + } + net_all_printf("Starting game\n"); +#else pollfds[0].fd=servsock; pollfds[0].events=POLLIN|POLLERR|POLLHUP; for (int i=SRV_FDS; i<(SRV_FDS+MAX_CLIENTS); i++) { pollfds[0].fd=-1; pollfds[0].events=0; } +#endif } +void +net_all_flush() { + for (int i=0; i<2; i++) + fflush(net_side[i]); +} + +void +net_all_printf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + for (int i=0; i<2; i++) + vfprintf(net_side[i], fmt, ap); + va_end(ap); +} + +void +net_side_printf(int side, const char *fmt, ...) { + va_list ap; + assert((side==0) || (side==1)); + va_start(ap, fmt); + vfprintf(net_side[side], fmt, ap); + va_end(ap); +} + + void net_poll() { diff --git a/src/server.c b/src/server.c index bcd2199..1e465fe 100644 --- a/src/server.c +++ b/src/server.c @@ -5,6 +5,8 @@ #include #include +#include "net.h" + #define NONE 0 #define PHARAO 1 #define DJHED 2 @@ -105,9 +107,9 @@ void print_piece_small(int piece, int side, int dir) { int index = (piece*4*2 + side*4 + dir) * 2; - printf("%c%c", - asciiart_small_pieces[index], - asciiart_small_pieces[index+1]); + net_all_printf("%c%c", + asciiart_small_pieces[index], + asciiart_small_pieces[index+1]); } int @@ -116,6 +118,9 @@ laser_at(int x, int y) return laser_pos[0] == x && laser_pos[1] == y; } + + +// FIXME rewrite this to format the board in a char *? void print_board_small() { @@ -126,59 +131,59 @@ print_board_small() vline = '|', hline = '-', xline = '+'; lline = '#'; - printf("%s(%c)\n", sideinfo[RED].name, sideinfo[RED].ch); + net_all_printf("%s(%c)\n", sideinfo[RED].name, sideinfo[RED].ch); // column numbers - printf(" %c", vline); + net_all_printf(" %c", vline); for (x = 0; x < BOARD_WIDTH; x++) { - printf(" %d%c", x, vline); + net_all_printf(" %d%c", x, vline); } - printf("\n"); + net_all_printf("\n"); // line - printf("%c%c%c", hline, hline, xline); + net_all_printf("%c%c%c", hline, hline, xline); for (x = 0; x < BOARD_WIDTH; x++) - printf("%c%c%c", + net_all_printf("%c%c%c", laser_at(x, -1) ? lline : hline, laser_at(x, -1) ? lline : hline, xline); - printf("%c%c\n", hline, hline); + net_all_printf("%c%c\n", hline, hline); for (y = 0; y < BOARD_HEIGHT; y++) { // row name - printf(" %c%c", 'A'+y, laser_at(-1,y) ? lline : vline); + net_all_printf(" %c%c", 'A'+y, laser_at(-1,y) ? lline : vline); // row for (x = 0; x < BOARD_WIDTH; x++) { if (laser_at(x, y)) - printf("%s", dead_piece); + net_all_printf("%s", dead_piece); else print_piece_small(board[x][y].piece, board[x][y].side, board[x][y].dir); - printf("%c", (x==BOARD_WIDTH-1 && laser_at(x+1, y)) ? lline : vline); + net_all_printf("%c", (x==BOARD_WIDTH-1 && laser_at(x+1, y)) ? lline : vline); } // row name - printf("%c\n", 'A'+y); + net_all_printf("%c\n", 'A'+y); // line - printf("%c%c%c", hline, hline, xline); + net_all_printf("%c%c%c", hline, hline, xline); for (x = 0; x < BOARD_WIDTH; x++) - printf("%c%c%c", + net_all_printf("%c%c%c", (y==BOARD_HEIGHT-1 && laser_at(x, y+1)) ? lline : hline, (y==BOARD_HEIGHT-1 && laser_at(x, y+1)) ? lline : hline, xline); - printf("%c%c\n", hline, hline); + net_all_printf("%c%c\n", hline, hline); } // column numbers - printf(" %c", vline); + net_all_printf(" %c", vline); for (x = 0; x < BOARD_WIDTH; x++) - printf(" %d%c", x, vline); - printf("\n"); + net_all_printf(" %d%c", x, vline); + net_all_printf("\n"); for (x = 0; x < (BOARD_WIDTH+2)*3-1-strlen(sideinfo[SILVER].name)-3; x++) - printf(" "); - printf("%s(%c)\n", sideinfo[SILVER].name, sideinfo[SILVER].ch); + net_all_printf(" "); + net_all_printf("%s(%c)\n", sideinfo[SILVER].name, sideinfo[SILVER].ch); } @@ -196,7 +201,7 @@ laser(int side) { 2 */ - printf("LASER (%s)\n", sideinfo[side].name); + net_all_printf("LASER (%s)\n", sideinfo[side].name); assert(side == 0 || side == 1); switch (side) { @@ -209,7 +214,7 @@ laser(int side) { } for (;;) { - printf("pos: (%d,%d)\n", y, x); + net_all_printf("pos: (%d,%d)\n", y, x); switch (board[x][y].piece) { case NONE: break; @@ -235,10 +240,18 @@ laser(int side) { break; } switch (dir & 3) { - case 0: y--; if (y<0) lreturn(L_WALL); break; - case 1: x++; if (x>BOARD_WIDTH-1) lreturn(L_WALL); break; - case 2: y++; if (y>BOARD_HEIGHT-1) lreturn(L_WALL); break; - case 3: x--; if (x<0) lreturn(L_WALL); break; + case 0: y--; + if (y<0) lreturn(L_WALL); + break; + case 1: x++; + if (x>BOARD_WIDTH-1) lreturn(L_WALL); + break; + case 2: y++; + if (y>BOARD_HEIGHT-1) lreturn(L_WALL); + break; + case 3: x--; + if (x<0) lreturn(L_WALL); +break; } } @@ -379,19 +392,20 @@ setup_board(char *desc) } int -read_message(message_t *m) +read_message(int side, message_t *m) { char buf[MAX_MSG_LEN+1]; char c; int i; for (i = 0; i < MAX_MSG_LEN+1; i++) { - c = getchar(); + c = net_getc(side); + printf("input '%c'\n", c); if (c == '\n') break; buf[i] = c; } buf[i] = '\0'; - while (c != '\n') c = getchar(); + while (c != '\n') c = net_getc(side); switch (buf[0]) { case 'M': m->type = MSG_MOVE; break; @@ -417,8 +431,8 @@ read_message(message_t *m) break; } - printf("msg: MOVE (%d,%d) %d\n", m->args.move.row, m->args.move.col, - m->args.move.dir); + net_all_printf("msg: MOVE (%d,%d) %d\n", m->args.move.row, m->args.move.col, + m->args.move.dir); } else if (m->type == MSG_ROTATE) { m->args.rotate.row = buf[2]-'A'; m->args.rotate.col = buf[3]-'0'; @@ -439,7 +453,7 @@ execute_message(message_t msg, int side) return rotate(side, msg.args.rotate.row, msg.args.rotate.col, msg.args.rotate.dir); default: - printf("unknown command type %d\n", msg.type); + net_side_printf(side, "unknown command type %d\n", msg.type); return E_UNKNOWN_COMMAND; } } @@ -456,17 +470,20 @@ simple_game() message_t msg; int r; - printf("%s's move\n", sideinfo[side].name); - - r = read_message(&msg); + net_all_printf("%s's move\n", sideinfo[side].name); + prompt: + net_side_printf(side, "> "); + net_all_flush(); + + r = read_message(side, &msg); switch (r) { case HUGE_SUCCESS: break; case E_UNKNOWN_COMMAND: - printf("unknown command\n"); - continue; + net_side_printf(side, "unknown command\n"); + goto prompt; default: - printf("uh oh (strange return value from read_message: %d)\n", r); - continue; + net_side_printf(side, "uh oh (strange return value from read_message: %d)\n", r); + goto prompt; } r = execute_message(msg, side); @@ -477,31 +494,32 @@ simple_game() print_board_small(); switch (r) { case SILVER_WINS: - printf("SILVER WINS\n"); + net_all_printf("SILVER WINS\n"); return; case RED_WINS: - printf("RED WINS\n"); + net_all_printf("RED WINS\n"); return; case L_WALL: case L_PIECE: - printf("laser hits %s at %c%c\n", - r==L_WALL ? "wall" : "piece", - laser_pos[1]+'A', laser_pos[0]+'0'); + net_all_printf("laser hits %s at %c%c\n", + r==L_WALL ? "wall" : "piece", + laser_pos[1]+'A', laser_pos[0]+'0'); break; } side = 1-side; break; case E_ILLEGAL_MOVE: - printf("illegal move\n"); - continue; + net_side_printf(side, "illegal move\n"); + goto prompt; default: - printf("uh oh (strange return value from execute_message: %d)\n", r); - continue; + net_side_printf(side, "uh oh (strange return value from execute_message: %d)\n", r); + goto prompt; } } } int main() { + net_server(15239); simple_game(); }