ref: d5c2af3bcb04031bd6f2724a480b9c7758eeacbb
dir: /netclient.c/
#ifdef unix
#include "unix.h"
#else
#include <u.h>
#include <libc.h>
#include <draw.h>
#endif
#include "engine.h"
#include "netclient.h"
#include "util.h"
int waitbit = 1; /* 0 is go, 1 is wait */
int networked = 0; /* 0 is local, 1 is networked */
int pside; /* Trapper, Glenda */
int srvfd;
char *pnick;
int pside;
int pgame;
int popts;
static char*
himsg(char *name, int game, int side, int opts)
{
char *msg;
dprint("himsg(%s, %d, %d, %d)\n", name, game, side, opts);
if(side > PRandom)
return nil;
msg = (char*)emalloc(32);
sprint(msg, "%s %d %d %d\n", name, game, side, opts);
return msg;
}
static char*
movemsg(int dir)
{
char *d, *msg;
d = dirtostr(dir);
if(d == nil)
return nil;
msg = (char*)emalloc(8);
sprint(msg, "m %s\n", d);
return msg;
}
static char*
putmsg(int x, int y)
{
char *msg;
dprint("putmsg(%d, %d)\n", x, y);
if(x > SzX || x < 0 || y > SzY || y < 0)
return nil;
msg = (char*)emalloc(10);
sprint(msg, "p %d %d\n", x, y);
return msg;
}
int
nethi(Game *game, char *name, int gameset, int side, int opts)
{
int len;
char *msg;
msg = himsg(name, gameset, side, opts);
if(msg == nil)
return Err;
len = strlen(msg);
if(write(srvfd, msg, len) < len)
sysfatal("nethi(): half written?");
/* otherwise client wont read socket to confirm */
waitbit = 1;
free(msg);
game->state = STATE_INIT;
return Ok;
}
int
netmove(int dir)
{
int len;
char *msg;
msg = movemsg(dir);
if(msg == nil)
return Err;
len = strlen(msg);
if(write(srvfd, msg, len) < len)
sysfatal("netmove(): half written?");
free(msg);
return Ok;
}
int
netput(int x, int y)
{
int len;
char *msg;
msg = putmsg(x, y);
if(msg == nil)
return Err;
len = strlen(msg);
if(write(srvfd, msg, len) < len)
sysfatal("netput(): half written?: %r");
free(msg);
return Ok;
}
static void
netproc(Game *game, Netmsg *msg, char *in)
{
int i, dir;
char *tmp, *xpos, *ypos;
char **tokens = (char**)emalloc(64 * sizeof(char*));
Point p;
msg->omsg = strdup(in);
dprint("msg->omsg: %s\n", msg->omsg);
tokens[0] = strtok(in, " ");
for(i = 1 ; tokens[i-1] != nil ; i++)
{
tokens[i] = strtok(nil, " ");
fprint(2, "token[%d] = %s\n", i, tokens[i]);
}
msg->ntoken = i;
msg->tokens = tokens;
msg->err = Ok;
if(tokens[0] == nil)
msg->err = Err;
else if(!strcmp(tokens[0], "CONN"))
{
switch(*tokens[1])
{
case '0':
pside = PTrapper;
break;
case '1':
pside = PGlenda;
break;
default:
sysfatal("invalid conn");
}
}
else if(!strcmp(tokens[0], "UGUD"))
fprint(srvfd, "y\n");
else if(!strcmp(tokens[0], "WAIT"))
waitbit = 1;
else if(!strcmp(tokens[0], "INIT"))
{
waitbit = 0;
game->state = STATE_INIT;
while(game->state == STATE_INIT)
{
tmp = netread();
/* lots of assuming goes here,
* messages are in the form of:
* {w,g} xx yy\n
*/
strtok(tmp, " ");
switch(*tmp)
{
case 'w':
xpos = strtok(nil, " ");
ypos = strtok(nil, " ");
if(xpos == nil || ypos == nil)
sysfatal("netproc(): w xpos or ypos is nil?\n");
p.x = atoi(xpos);
p.y = atoi(ypos);
game->grid[p.x][p.y] = PIECE_WALL;
break;
case 'g':
xpos = strtok(nil, " ");
ypos = strtok(nil, " ");
if(xpos == nil || ypos == nil)
dprint("netproc(): g xpos or ypos is nil?\n");
p.x = atoi(xpos);
p.y = atoi(ypos);
game->grid[p.x][p.y] = PIECE_GLENDA;
break;
default:
if(!strcmp("SENT", tmp))
game->state = STATE_START;
else
dprint("netproc(): Init: unknown command: %s\n", tmp);
}
}
}
else if(!strcmp(tokens[0], "SENT"))
/* sent is handled in INIT */
dprint("SENT without INIT?\n");
else if(!strcmp(tokens[0], "TURN"))
waitbit = 0;
else if(!strcmp(tokens[0], "SYNC"))
{
if(game->state == STATE_START)
game->state = STATE_PLAYING;
if(msg->ntoken < 2)
sysfatal("netproc(): not enough toknes?");
if(atoi(msg->tokens[1]) % 2 == 0)
{
/* trapper's turn is done */
if(msg->ntoken != 4)
sysfatal("netproc(): not enough tokens to SYNC trapper's move");
p = parseput(tokens[2], tokens[3]);
doput(game, p);
}
else
{
/* glenda's turn is done */
if(msg->ntoken != 3)
sysfatal("netproc(): not enough tokens to SYNC glenda's move");
dir = strtodir(tokens[2]);
domove(game, dir);
}
}
else if(!strcmp(tokens[0], "WON"))
{
msg->err = STATE_WON;
}
else if(!strcmp(tokens[0], "LOST"))
{
msg->err = STATE_LOST;
}
else
sysfatal("netproc(): unkown message: 0x%x %s", *tokens[0], tokens[0]);
}
char*
netread(void)
{
char *s = malloc(1024);
int n = 0;
memset(s, 0, 1024);
while(read(srvfd, s+n, 1) == 1 && n < 1023)
{
if(s[n] == '\n' || s[n] == '\0')
{
s[n] = '\0';
break;
}
n++;
}
return s;
}
void
netinit(Game *game)
{
Netmsg *msg;
char *s;
msg = (Netmsg*)emalloc(sizeof(Netmsg));
game->state = STATE_CONNECT;
nethi(game, pnick, 0, pside, 0);
for(;;)
{
s = netread();
netproc(game, msg, s);
dprint("msg->tokens[0]: %s\n", msg->tokens[0]);
if(msg->tokens[0] != nil && !strcmp(msg->tokens[0], "INIT"))
break;
free(s);
}
free(s);
}
Netmsg*
netmain(Game *game)
{
Netmsg *msg;
char *s;
msg = (Netmsg*)emalloc(sizeof(Netmsg));
s = netread();
netproc(game, msg, s);
free(s);
return msg;
}