Almost working network support.
This commit is contained in:
parent
7d42846db7
commit
227e1e9254
@ -1 +1,3 @@
|
|||||||
CFLAGS=-g -std=c99 -Wall -pedantic
|
CFLAGS=-g -std=gnu99 -Wall -pedantic
|
||||||
|
|
||||||
|
server: server.o net.o
|
||||||
|
72
src/net.c
72
src/net.c
@ -10,6 +10,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
#define MAX_CLIENTS 2
|
#define MAX_CLIENTS 2
|
||||||
#define SRV_FDS 1
|
#define SRV_FDS 1
|
||||||
@ -18,10 +21,14 @@ int servsock;
|
|||||||
struct pollfd pollfds[SRV_FDS+MAX_CLIENTS];
|
struct pollfd pollfds[SRV_FDS+MAX_CLIENTS];
|
||||||
int nclients = 0;
|
int nclients = 0;
|
||||||
|
|
||||||
|
FILE *net_side[2];
|
||||||
|
|
||||||
int
|
int
|
||||||
errx(int eval, const char *fmt, ...) {
|
errx(int eval, const char *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
exit(eval);
|
exit(eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,22 +38,77 @@ net_server(int port) {
|
|||||||
serveraddr.sin_family = AF_INET;
|
serveraddr.sin_family = AF_INET;
|
||||||
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
serveraddr.sin_port = htons(port);
|
serveraddr.sin_port = htons(port);
|
||||||
|
|
||||||
|
|
||||||
servsock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
servsock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (servsock<0)
|
if (servsock<0)
|
||||||
errx(1, "socket: %s", strerror(errno));
|
errx(1, "socket: %s\n", strerror(errno));
|
||||||
if (bind(servsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
|
int r;
|
||||||
errx(1, "bind port %d: %s", port, strerror(errno));
|
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)
|
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].fd=servsock;
|
||||||
pollfds[0].events=POLLIN|POLLERR|POLLHUP;
|
pollfds[0].events=POLLIN|POLLERR|POLLHUP;
|
||||||
for (int i=SRV_FDS; i<(SRV_FDS+MAX_CLIENTS); i++) {
|
for (int i=SRV_FDS; i<(SRV_FDS+MAX_CLIENTS); i++) {
|
||||||
pollfds[0].fd=-1;
|
pollfds[0].fd=-1;
|
||||||
pollfds[0].events=0;
|
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
|
void
|
||||||
net_poll() {
|
net_poll() {
|
||||||
|
118
src/server.c
118
src/server.c
@ -5,6 +5,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
#define NONE 0
|
#define NONE 0
|
||||||
#define PHARAO 1
|
#define PHARAO 1
|
||||||
#define DJHED 2
|
#define DJHED 2
|
||||||
@ -105,9 +107,9 @@ void
|
|||||||
print_piece_small(int piece, int side, int dir)
|
print_piece_small(int piece, int side, int dir)
|
||||||
{
|
{
|
||||||
int index = (piece*4*2 + side*4 + dir) * 2;
|
int index = (piece*4*2 + side*4 + dir) * 2;
|
||||||
printf("%c%c",
|
net_all_printf("%c%c",
|
||||||
asciiart_small_pieces[index],
|
asciiart_small_pieces[index],
|
||||||
asciiart_small_pieces[index+1]);
|
asciiart_small_pieces[index+1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -116,6 +118,9 @@ laser_at(int x, int y)
|
|||||||
return laser_pos[0] == x && laser_pos[1] == y;
|
return laser_pos[0] == x && laser_pos[1] == y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME rewrite this to format the board in a char *?
|
||||||
void
|
void
|
||||||
print_board_small()
|
print_board_small()
|
||||||
{
|
{
|
||||||
@ -126,59 +131,59 @@ print_board_small()
|
|||||||
vline = '|', hline = '-', xline = '+';
|
vline = '|', hline = '-', xline = '+';
|
||||||
lline = '#';
|
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
|
// column numbers
|
||||||
printf(" %c", vline);
|
net_all_printf(" %c", vline);
|
||||||
for (x = 0; x < BOARD_WIDTH; x++) {
|
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
|
// line
|
||||||
printf("%c%c%c", hline, hline, xline);
|
net_all_printf("%c%c%c", hline, hline, xline);
|
||||||
for (x = 0; x < BOARD_WIDTH; x++)
|
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,
|
||||||
laser_at(x, -1) ? lline : hline,
|
laser_at(x, -1) ? lline : hline,
|
||||||
xline);
|
xline);
|
||||||
printf("%c%c\n", hline, hline);
|
net_all_printf("%c%c\n", hline, hline);
|
||||||
|
|
||||||
for (y = 0; y < BOARD_HEIGHT; y++) {
|
for (y = 0; y < BOARD_HEIGHT; y++) {
|
||||||
// row name
|
// 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
|
// row
|
||||||
for (x = 0; x < BOARD_WIDTH; x++) {
|
for (x = 0; x < BOARD_WIDTH; x++) {
|
||||||
if (laser_at(x, y))
|
if (laser_at(x, y))
|
||||||
printf("%s", dead_piece);
|
net_all_printf("%s", dead_piece);
|
||||||
else
|
else
|
||||||
print_piece_small(board[x][y].piece,
|
print_piece_small(board[x][y].piece,
|
||||||
board[x][y].side,
|
board[x][y].side,
|
||||||
board[x][y].dir);
|
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
|
// row name
|
||||||
printf("%c\n", 'A'+y);
|
net_all_printf("%c\n", 'A'+y);
|
||||||
|
|
||||||
// line
|
// line
|
||||||
printf("%c%c%c", hline, hline, xline);
|
net_all_printf("%c%c%c", hline, hline, xline);
|
||||||
for (x = 0; x < BOARD_WIDTH; x++)
|
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,
|
||||||
(y==BOARD_HEIGHT-1 && laser_at(x, y+1)) ? lline : hline,
|
(y==BOARD_HEIGHT-1 && laser_at(x, y+1)) ? lline : hline,
|
||||||
xline);
|
xline);
|
||||||
printf("%c%c\n", hline, hline);
|
net_all_printf("%c%c\n", hline, hline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// column numbers
|
// column numbers
|
||||||
printf(" %c", vline);
|
net_all_printf(" %c", vline);
|
||||||
for (x = 0; x < BOARD_WIDTH; x++)
|
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");
|
||||||
|
|
||||||
for (x = 0; x < (BOARD_WIDTH+2)*3-1-strlen(sideinfo[SILVER].name)-3; x++)
|
for (x = 0; x < (BOARD_WIDTH+2)*3-1-strlen(sideinfo[SILVER].name)-3; x++)
|
||||||
printf(" ");
|
net_all_printf(" ");
|
||||||
printf("%s(%c)\n", sideinfo[SILVER].name, sideinfo[SILVER].ch);
|
net_all_printf("%s(%c)\n", sideinfo[SILVER].name, sideinfo[SILVER].ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -196,7 +201,7 @@ laser(int side) {
|
|||||||
2
|
2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf("LASER (%s)\n", sideinfo[side].name);
|
net_all_printf("LASER (%s)\n", sideinfo[side].name);
|
||||||
|
|
||||||
assert(side == 0 || side == 1);
|
assert(side == 0 || side == 1);
|
||||||
switch (side) {
|
switch (side) {
|
||||||
@ -209,7 +214,7 @@ laser(int side) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
printf("pos: (%d,%d)\n", y, x);
|
net_all_printf("pos: (%d,%d)\n", y, x);
|
||||||
switch (board[x][y].piece) {
|
switch (board[x][y].piece) {
|
||||||
case NONE:
|
case NONE:
|
||||||
break;
|
break;
|
||||||
@ -235,10 +240,18 @@ laser(int side) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (dir & 3) {
|
switch (dir & 3) {
|
||||||
case 0: y--; if (y<0) lreturn(L_WALL); break;
|
case 0: y--;
|
||||||
case 1: x++; if (x>BOARD_WIDTH-1) lreturn(L_WALL); break;
|
if (y<0) lreturn(L_WALL);
|
||||||
case 2: y++; if (y>BOARD_HEIGHT-1) lreturn(L_WALL); break;
|
break;
|
||||||
case 3: x--; if (x<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
|
int
|
||||||
read_message(message_t *m)
|
read_message(int side, message_t *m)
|
||||||
{
|
{
|
||||||
char buf[MAX_MSG_LEN+1];
|
char buf[MAX_MSG_LEN+1];
|
||||||
char c;
|
char c;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MAX_MSG_LEN+1; i++) {
|
for (i = 0; i < MAX_MSG_LEN+1; i++) {
|
||||||
c = getchar();
|
c = net_getc(side);
|
||||||
|
printf("input '%c'\n", c);
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
break;
|
break;
|
||||||
buf[i] = c;
|
buf[i] = c;
|
||||||
}
|
}
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
while (c != '\n') c = getchar();
|
while (c != '\n') c = net_getc(side);
|
||||||
|
|
||||||
switch (buf[0]) {
|
switch (buf[0]) {
|
||||||
case 'M': m->type = MSG_MOVE; break;
|
case 'M': m->type = MSG_MOVE; break;
|
||||||
@ -417,8 +431,8 @@ read_message(message_t *m)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("msg: MOVE (%d,%d) %d\n", m->args.move.row, m->args.move.col,
|
net_all_printf("msg: MOVE (%d,%d) %d\n", m->args.move.row, m->args.move.col,
|
||||||
m->args.move.dir);
|
m->args.move.dir);
|
||||||
} else if (m->type == MSG_ROTATE) {
|
} else if (m->type == MSG_ROTATE) {
|
||||||
m->args.rotate.row = buf[2]-'A';
|
m->args.rotate.row = buf[2]-'A';
|
||||||
m->args.rotate.col = buf[3]-'0';
|
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,
|
return rotate(side, msg.args.rotate.row, msg.args.rotate.col,
|
||||||
msg.args.rotate.dir);
|
msg.args.rotate.dir);
|
||||||
default:
|
default:
|
||||||
printf("unknown command type %d\n", msg.type);
|
net_side_printf(side, "unknown command type %d\n", msg.type);
|
||||||
return E_UNKNOWN_COMMAND;
|
return E_UNKNOWN_COMMAND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,17 +470,20 @@ simple_game()
|
|||||||
message_t msg;
|
message_t msg;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
printf("%s's move\n", sideinfo[side].name);
|
net_all_printf("%s's move\n", sideinfo[side].name);
|
||||||
|
prompt:
|
||||||
r = read_message(&msg);
|
net_side_printf(side, "> ");
|
||||||
|
net_all_flush();
|
||||||
|
|
||||||
|
r = read_message(side, &msg);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case HUGE_SUCCESS: break;
|
case HUGE_SUCCESS: break;
|
||||||
case E_UNKNOWN_COMMAND:
|
case E_UNKNOWN_COMMAND:
|
||||||
printf("unknown command\n");
|
net_side_printf(side, "unknown command\n");
|
||||||
continue;
|
goto prompt;
|
||||||
default:
|
default:
|
||||||
printf("uh oh (strange return value from read_message: %d)\n", r);
|
net_side_printf(side, "uh oh (strange return value from read_message: %d)\n", r);
|
||||||
continue;
|
goto prompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = execute_message(msg, side);
|
r = execute_message(msg, side);
|
||||||
@ -477,31 +494,32 @@ simple_game()
|
|||||||
print_board_small();
|
print_board_small();
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case SILVER_WINS:
|
case SILVER_WINS:
|
||||||
printf("SILVER WINS\n");
|
net_all_printf("SILVER WINS\n");
|
||||||
return;
|
return;
|
||||||
case RED_WINS:
|
case RED_WINS:
|
||||||
printf("RED WINS\n");
|
net_all_printf("RED WINS\n");
|
||||||
return;
|
return;
|
||||||
case L_WALL:
|
case L_WALL:
|
||||||
case L_PIECE:
|
case L_PIECE:
|
||||||
printf("laser hits %s at %c%c\n",
|
net_all_printf("laser hits %s at %c%c\n",
|
||||||
r==L_WALL ? "wall" : "piece",
|
r==L_WALL ? "wall" : "piece",
|
||||||
laser_pos[1]+'A', laser_pos[0]+'0');
|
laser_pos[1]+'A', laser_pos[0]+'0');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
side = 1-side;
|
side = 1-side;
|
||||||
break;
|
break;
|
||||||
case E_ILLEGAL_MOVE:
|
case E_ILLEGAL_MOVE:
|
||||||
printf("illegal move\n");
|
net_side_printf(side, "illegal move\n");
|
||||||
continue;
|
goto prompt;
|
||||||
default:
|
default:
|
||||||
printf("uh oh (strange return value from execute_message: %d)\n", r);
|
net_side_printf(side, "uh oh (strange return value from execute_message: %d)\n", r);
|
||||||
continue;
|
goto prompt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main() {
|
main() {
|
||||||
|
net_server(15239);
|
||||||
simple_game();
|
simple_game();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user