ref: e19630c0ef62e3e66cc17a438704df07cb2161ce
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; }