implement Gamer; include "sys.m";include "gamer.m"; sys: Sys;FD, Connection: import Sys; devsysname: con "/dev/sysname"; addr: string;stderr: ref FD; getaddr() : int{ f := sys->open(devsysname, sys->OREAD); if (f == nil) { sys->fprint(stderr, "open %s failed: %r\n", devsysname); return -1; } buff := array[64] of byte; n := sys->read(f, buff, len buff); if (n < 0) { sys->fprint(stderr, "read %s failed: %r\n", devsysname); return -1; } addr = "tcp!" + string buff[0:n] + "!gamed"; return 0;} Join(game: string) : Game{ g: Game; g.player = -1; if(sys == nil) { sys = load Sys Sys->PATH; stderr = sys->fildes(2); if (getaddr() < 0) return g; } (ok, c) := sys->dial(addr, nil); if (ok < 0) { sys->fprint(stderr, "dial %s failed: %r\n", addr); return g; } s := "join " + game; b := array of byte s; if (sys->write(c.dfd, b, len b) < 0) { sys->fprint(stderr, "write %s failed: %r\n", addr); return g; } buff := array[64] of byte; n := sys->read(c.dfd, buff, len buff); if (n < 0) { sys->fprint(stderr, "read %s failed: %r\n", addr); return g; } if (n == 0) { sys->fprint(stderr, "eof on read %s\n", addr); return g; } s = string buff[0:n]; if (s == "error") { sys->fprint(stderr, "%s returns error\n", addr); return g; } c.dfd = nil; (t, l) := sys->tokenize(s, " \t\n"); if (t != 3) { sys->fprint(stderr, "%s returns bad response\n", addr); return g; } g.opponent = hd tl l; player := int hd tl tl l; s = "local " + s; (ok, c) = sys->dial(addr, nil); if (ok < 0) { sys->fprint(stderr, "dial %s failed: %r\n", addr); return g; } b = array of byte s; if (sys->write(c.dfd, b, len b) < 0) { sys->fprint(stderr, "write %s failed: %r\n", addr); return g; } n = sys->read(c.dfd, buff, len buff); if (n < 0) { sys->fprint(stderr, "read %s failed: %r\n", addr); return g; } g.wf = c.dfd; if (n == 0) { sys->fprint(stderr, "eof on read %s\n", addr); return g; } s = string buff[0:n]; if (s == "error") { sys->fprint(stderr, "%s returns error\n", addr); return g; } g.rf = sys->open(s, sys->OREAD); if (g.rf == nil) { sys->fprint(stderr, "pipe open %s failed: %r\n", s); return g; } g.player = player; return g;} Game.In(g: self Game) : int{ buff := array[1] of byte; if ((rd := sys->read(g.rf, buff, 1)) == 1) return int buff[0]; if (rd < 0) sys->fprint(stderr, "gamed read failed: %r\n"); g.rf = nil; return -1;} Game.Out(g: self Game, i: int){ buff := array[1] of byte; buff[0] = byte i; if (sys->write(g.wf, buff, 1) != 1) { sys->fprint(stderr, "gamed write failed: %r\n"); g.wf = nil; return; }} Game.Exit(g: self Game){ g.Out(255); g.rf = nil; g.wf = nil;}
implement Gamer;
include "sys.m";
include "gamer.m";
sys: Sys;
FD, Connection: import Sys;
devsysname: con "/dev/sysname";
addr: string;
stderr: ref FD;
getaddr() : int
{
f := sys->open(devsysname, sys->OREAD);
if (f == nil) {
sys->fprint(stderr, "open %s failed: %r\n", devsysname);
return -1;
}
buff := array[64] of byte;
n := sys->read(f, buff, len buff);
if (n < 0) {
sys->fprint(stderr, "read %s failed: %r\n", devsysname);
return -1;
}
addr = "tcp!" + string buff[0:n] + "!gamed";
return 0;
}
Join(game: string) : Game
{
g: Game;
g.player = -1;
if(sys == nil) {
sys = load Sys Sys->PATH;
stderr = sys->fildes(2);
if (getaddr() < 0)
return g;
}
(ok, c) := sys->dial(addr, nil);
if (ok < 0) {
sys->fprint(stderr, "dial %s failed: %r\n", addr);
return g;
}
s := "join " + game;
b := array of byte s;
if (sys->write(c.dfd, b, len b) < 0) {
sys->fprint(stderr, "write %s failed: %r\n", addr);
return g;
}
buff := array[64] of byte;
n := sys->read(c.dfd, buff, len buff);
if (n < 0) {
sys->fprint(stderr, "read %s failed: %r\n", addr);
return g;
}
if (n == 0) {
sys->fprint(stderr, "eof on read %s\n", addr);
return g;
}
s = string buff[0:n];
if (s == "error") {
sys->fprint(stderr, "%s returns error\n", addr);
return g;
}
c.dfd = nil;
(t, l) := sys->tokenize(s, " \t\n");
if (t != 3) {
sys->fprint(stderr, "%s returns bad response\n", addr);
return g;
}
g.opponent = hd tl l;
player := int hd tl tl l;
s = "local " + s;
(ok, c) = sys->dial(addr, nil);
if (ok < 0) {
sys->fprint(stderr, "dial %s failed: %r\n", addr);
return g;
}
b = array of byte s;
if (sys->write(c.dfd, b, len b) < 0) {
sys->fprint(stderr, "write %s failed: %r\n", addr);
return g;
}
n = sys->read(c.dfd, buff, len buff);
if (n < 0) {
sys->fprint(stderr, "read %s failed: %r\n", addr);
return g;
}
g.wf = c.dfd;
if (n == 0) {
sys->fprint(stderr, "eof on read %s\n", addr);
return g;
}
s = string buff[0:n];
if (s == "error") {
sys->fprint(stderr, "%s returns error\n", addr);
return g;
}
g.rf = sys->open(s, sys->OREAD);
if (g.rf == nil) {
sys->fprint(stderr, "pipe open %s failed: %r\n", s);
return g;
}
g.player = player;
return g;
}
Game.In(g: self Game) : int
{
buff := array[1] of byte;
if ((rd := sys->read(g.rf, buff, 1)) == 1)
return int buff[0];
if (rd < 0)
sys->fprint(stderr, "gamed read failed: %r\n");
g.rf = nil;
return -1;
}
Game.Out(g: self Game, i: int)
{
buff := array[1] of byte;
buff[0] = byte i;
if (sys->write(g.wf, buff, 1) != 1) {
sys->fprint(stderr, "gamed write failed: %r\n");
g.wf = nil;
return;
}
}
Game.Exit(g: self Game)
{
g.Out(255);
g.rf = nil;
g.wf = nil;
}