Almost working network support.

This commit is contained in:
Steinar Hamre 2008-10-09 19:20:37 +00:00
parent 7d42846db7
commit 227e1e9254
3 changed files with 138 additions and 56 deletions

View File

@ -1 +1,3 @@
CFLAGS=-g -std=c99 -Wall -pedantic
CFLAGS=-g -std=gnu99 -Wall -pedantic
server: server.o net.o

View File

@ -10,6 +10,9 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#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() {

View File

@ -5,6 +5,8 @@
#include <assert.h>
#include <string.h>
#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();
}