aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dat.h35
-rw-r--r--fns.h9
-rw-r--r--lobby.c76
-rw-r--r--mkfile1
-rw-r--r--musw.c18
-rw-r--r--muswd.c75
-rw-r--r--pack.c114
-rw-r--r--party.c44
8 files changed, 237 insertions, 135 deletions
diff --git a/dat.h b/dat.h
index fb790ae..9ea1f7f 100644
--- a/dat.h
+++ b/dat.h
@@ -2,8 +2,10 @@
typedef struct GameState GameState;
typedef struct Derivative Derivative;
-typedef struct Seats Seats;
+typedef struct Conn Conn;
+typedef struct Player Player;
typedef struct Lobby Lobby;
+typedef struct Party Party;
struct GameState
{
@@ -15,18 +17,35 @@ struct Derivative
double dx, dv;
};
-struct Seats
+struct Conn
{
- int *fds;
- ulong len;
- ulong cap;
+ char dir[40];
+ int ctl;
+ int data;
+};
+
+struct Player
+{
+ char *name;
+ Conn conn;
};
struct Lobby
{
- Seats seats;
+ Player *seats;
+ ulong nseats;
+ ulong cap;
- int (*takeseat)(Lobby*, int);
- int (*getcouple)(Lobby*, int*);
+ int (*takeseat)(Lobby*, char*, int, int);
int (*leaveseat)(Lobby*, ulong);
+ int (*getcouple)(Lobby*, Player*);
+ void (*healthcheck)(Lobby*);
};
+
+struct Party
+{
+ Player players[2]; /* the needle and the wedge */
+ Party *prev, *next;
+};
+
+extern Party theparty;
diff --git a/fns.h b/fns.h
index 99a3603..a925117 100644
--- a/fns.h
+++ b/fns.h
@@ -26,3 +26,12 @@ int unpack(uchar*, int, char*, ...);
*/
Lobby *newlobby(void);
void dellobby(Lobby*);
+
+/*
+ * lobby
+ */
+void inittheparty(void);
+Party *newparty(Player[2]);
+void delparty(Party*);
+void addparty(Party*);
+
diff --git a/lobby.c b/lobby.c
index 4004983..2007f2a 100644
--- a/lobby.c
+++ b/lobby.c
@@ -4,40 +4,75 @@
#include "fns.h"
static int
-lobby_takeseat(Lobby *l, int fd)
+lobby_takeseat(Lobby *l, char *dir, int cfd, int dfd)
{
- if(l->seats.len >= l->seats.cap){
- l->seats.cap += 8;
- l->seats.fds = erealloc(l->seats.fds, l->seats.cap*sizeof(*l->seats.fds));
+ if(l->nseats >= l->cap){
+ l->cap += 8;
+ l->seats = erealloc(l->seats, l->cap*sizeof(*l->seats));
}
- l->seats.fds[l->seats.len] = fd;
- return l->seats.len++;
+ l->seats[l->nseats].name = nil;
+ memmove(l->seats[l->nseats].conn.dir, dir, sizeof l->seats[l->nseats].conn.dir);
+ l->seats[l->nseats].conn.ctl = cfd;
+ l->seats[l->nseats].conn.data = dfd;
+
+ return l->nseats++;
+}
+
+static int
+lobby_leaveseat(Lobby *l, ulong idx)
+{
+ if(idx >= l->cap)
+ return -1;
+
+ if(idx < l->cap - 1)
+ memmove(&l->seats[idx], &l->seats[idx+1], l->cap*sizeof(*l->seats) - (idx + 1)*sizeof(*l->seats));
+
+ return --l->nseats;
}
static int
-lobby_getcouple(Lobby *l, int *fds)
+lobby_getcouple(Lobby *l, Player *couple)
{
- if(l->seats.len >= 2){
- fds[0] = l->seats.fds[l->seats.len-2];
- fds[1] = l->seats.fds[l->seats.len-1];
+ if(l->nseats >= 2){
+ couple[0] = l->seats[l->nseats-2];
+ couple[1] = l->seats[l->nseats-1];
- if(l->seats.len < l->seats.cap-2)
- memmove(&l->seats.fds[l->seats.len], &l->seats.fds[l->seats.len+2], l->seats.cap*sizeof(int) - (l->seats.len + 2)*sizeof(int));
+ if(l->nseats < l->cap - 2)
+ memmove(&l->seats[l->nseats], &l->seats[l->nseats+2], l->cap*sizeof(*l->seats) - (l->nseats + 2)*sizeof(*l->seats));
+
+ l->nseats -= 2;
- l->seats.len -= 2;
return 0;
}
+
return -1;
}
-static int
-lobby_leaveseat(Lobby *l, ulong idx)
+static void
+lobby_healthcheck(Lobby *l)
{
- if(idx < l->seats.cap-1)
- memmove(&l->seats.fds[idx], &l->seats.fds[idx+1], l->seats.cap*sizeof(int) - (idx + 1)*sizeof(int));
- l->seats.len--;
- return 0;
+ char status[48], buf[16];
+ int i, fd;
+
+ for(i = 0; i < l->nseats; i++){
+ snprint(status, sizeof status, "%s/status", l->seats[i].conn.dir);
+
+ fd = open(status, OREAD);
+ if(fd < 0)
+ goto cleanup;
+
+ if(read(fd, buf, sizeof buf) > 0)
+ if(strncmp(buf, "Close", 5) == 0)
+ goto cleanup;
+ else{
+ close(fd);
+ continue;
+ }
+cleanup:
+ close(fd);
+ l->leaveseat(l, i);
+ }
}
Lobby *
@@ -50,6 +85,7 @@ newlobby(void)
l->takeseat = lobby_takeseat;
l->getcouple = lobby_getcouple;
l->leaveseat = lobby_leaveseat;
+ l->healthcheck = lobby_healthcheck;
return l;
}
@@ -57,6 +93,6 @@ newlobby(void)
void
dellobby(Lobby *l)
{
- free(l->seats.fds);
+ free(l->seats);
free(l);
}
diff --git a/mkfile b/mkfile
index 115f0b5..c9c09ff 100644
--- a/mkfile
+++ b/mkfile
@@ -11,6 +11,7 @@ OFILES=\
nanosec.$O\
pack.$O\
lobby.$O\
+ party.$O\
HFILES=\
dat.h\
diff --git a/musw.c b/musw.c
index a88f0fc..1b40264 100644
--- a/musw.c
+++ b/musw.c
@@ -4,19 +4,26 @@
#include "dat.h"
#include "fns.h"
+int debug;
+
+
void
threadnetin(void *arg)
{
- char buf[256];
+ uchar buf[256];
int fd, n;
+ double x, v;
Ioproc *io;
fd = *((int*)arg);
io = ioproc();
- while((n = ioread(io, fd, buf, sizeof buf)) > 0)
+ while((n = ioread(io, fd, buf, sizeof buf)) > 0){
+ unpack(buf, n, "dd", &x, &v);
+ n = snprint((char *)buf, sizeof buf, "state: x=%g v=%g\n", x, v);
if(iowrite(io, 1, buf, n) != n)
- fprint(2, "netin iowrite: %r\n");
+ fprint(2, "iowrite: %r\n");
+ }
closeioproc(io);
}
@@ -32,7 +39,7 @@ threadnetout(void *arg)
while((n = ioread(io, 0, buf, sizeof buf)) > 0)
if(iowrite(io, fd, buf, n) != n)
- fprint(2, "netout iowrite: %r\n");
+ fprint(2, "iowrite: %r\n");
closeioproc(io);
}
@@ -50,6 +57,9 @@ threadmain(int argc, char *argv[])
int fd;
ARGBEGIN{
+ case 'd':
+ debug++;
+ break;
default:
usage();
}ARGEND;
diff --git a/muswd.c b/muswd.c
index 249e516..b3667e2 100644
--- a/muswd.c
+++ b/muswd.c
@@ -55,15 +55,36 @@ threadlisten(void *arg)
continue;
}
- lobby->takeseat(lobby, dfd);
+ lobby->takeseat(lobby, ldir, lcfd, dfd);
if(debug)
fprint(2, "added conn for %lud conns at %lud max\n",
- lobby->seats.len, lobby->seats.cap);
+ lobby->nseats, lobby->cap);
}
}
void
+broadcaststate(void)
+{
+ int i, n;
+ uchar buf[256];
+ Party *p;
+
+ if(debug)
+ fprint(2, "state: x=%g v=%g\n", state.x, state.v);
+
+ for(p = theparty.next; p != &theparty; p = p->next)
+ for(i = 0; i < nelem(p->players); i++){
+ n = pack(buf, sizeof buf, "dd", state.x, state.v);
+ if(write(p->players[i].conn.data, buf, n) != n){
+ lobby->takeseat(lobby, p->players[i^1].conn.dir, p->players[i^1].conn.ctl, p->players[i^1].conn.data);
+ delparty(p);
+ }
+ }
+
+}
+
+void
resetsim(void)
{
t = 0;
@@ -74,10 +95,10 @@ resetsim(void)
void
threadsim(void *)
{
- int i;
uvlong then, now;
double frametime, timeacc;
Ioproc *io;
+ Player couple[2];
Δt = 0.01;
then = nanosec();
@@ -87,24 +108,30 @@ threadsim(void *)
resetsim();
for(;;){
- now = nanosec();
- frametime = now - then;
- then = now;
- timeacc += frametime/1e9;
+ lobby->healthcheck(lobby);
- for(i = 0; i < lobby->seats.len; i++)
- if(fprint(lobby->seats.fds[i], "state: x=%g v=%g\n", state.x, state.v) < 0){
- if(debug)
- fprint(2, "client #%d hanged up\n", i+1);
+ if(debug){
+ Party *p;
+ ulong nparties = 0;
- lobby->leaveseat(lobby, i);
+ for(p = theparty.next; p != &theparty; p = p->next)
+ nparties++;
- if(debug)
- fprint(2, "removed conn %d for %lud conns at %lud max\n",
- i, lobby->seats.len, lobby->seats.cap);
+ fprint(2, "lobby status: %lud conns at %lud cap\n",
+ lobby->nseats, lobby->cap);
+ fprint(2, "party status: %lud parties going on\n",
+ nparties);
+ }
- i--;
- }
+ if(lobby->getcouple(lobby, couple) != -1)
+ newparty(couple);
+
+ broadcaststate();
+
+ now = nanosec();
+ frametime = now - then;
+ then = now;
+ timeacc += frametime/1e9;
while(timeacc >= Δt){
integrate(&state, t, Δt);
@@ -119,7 +146,7 @@ threadsim(void *)
void
usage(void)
{
- fprint(2, "usage: %s [-d]\n", argv0);
+ fprint(2, "usage: %s [-d] [-a addr]\n", argv0);
threadexitsall("usage");
}
@@ -127,9 +154,13 @@ void
threadmain(int argc, char *argv[])
{
int acfd;
- char adir[40];
+ char adir[40], *addr;
+ addr = "udp!*!112";
ARGBEGIN{
+ case 'a':
+ addr = EARGF(usage());
+ break;
case 'd':
debug++;
break;
@@ -139,11 +170,15 @@ threadmain(int argc, char *argv[])
if(argc != 0)
usage();
- acfd = announce("tcp!*!112", adir);
+ acfd = announce(addr, adir);
if(acfd < 0)
sysfatal("announce: %r");
+ if(debug)
+ fprint(2, "listening on %s\n", addr);
+
lobby = newlobby();
+ inittheparty();
threadcreate(threadlisten, adir, 4096);
threadcreate(threadsim, nil, 4096);
diff --git a/pack.c b/pack.c
index 5899dbd..d60800d 100644
--- a/pack.c
+++ b/pack.c
@@ -3,58 +3,37 @@
#include "dat.h"
#include "fns.h"
-/*
- * these routines were taken directly from ssh(1).
- * they serve as a reference.
- */
+static ulong
+get4(uchar *p)
+{
+ return p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
+}
+
+static void
+put4(uchar *p, ulong u)
+{
+ p[0] = u>>24, p[1] = u>>16, p[2] = u>>8, p[3] = u;
+}
static int
vpack(uchar *p, int n, char *fmt, va_list a)
{
uchar *p0 = p, *e = p+n;
- u32int u;
-// mpint *m;
- void *s;
- int c;
+ FPdbleword d;
for(;;){
- switch(c = *fmt++){
+ switch(*fmt++){
case '\0':
return p - p0;
- case '_':
- if(++p > e) goto err;
- break;
- case '.':
- *va_arg(a, void**) = p;
- break;
- case 'b':
- if(p >= e) goto err;
- *p++ = va_arg(a, int);
- break;
- case 'm':
-// m = va_arg(a, mpint*);
-// u = (mpsignif(m)+8)/8;
- if(p+4 > e) goto err;
-// PUT4(p, u), p += 4;
- if(u > e-p) goto err;
-// mptober(m, p, u), p += u;
- break;
- case '[':
- case 's':
- s = va_arg(a, void*);
- u = va_arg(a, int);
- if(c == 's'){
- if(p+4 > e) goto err;
-// PUT4(p, u), p += 4;
- }
- if(u > e-p) goto err;
- memmove(p, s, u);
- p += u;
- break;
- case 'u':
- u = va_arg(a, int);
- if(p+4 > e) goto err;
-// PUT4(p, u), p += 4;
+ case 'd':
+ d.x = va_arg(a, double);
+
+ if(p+8 > e)
+ goto err;
+
+ put4(p, d.hi), p += 4;
+ put4(p, d.lo), p += 4;
+
break;
}
}
@@ -66,51 +45,20 @@ static int
vunpack(uchar *p, int n, char *fmt, va_list a)
{
uchar *p0 = p, *e = p+n;
- u32int u;
-// mpint *m;
- void *s;
+ FPdbleword d;
for(;;){
switch(*fmt++){
case '\0':
return p - p0;
- case '_':
- if(++p > e) goto err;
- break;
- case '.':
- *va_arg(a, void**) = p;
- break;
- case 'b':
- if(p >= e) goto err;
- *va_arg(a, int*) = *p++;
- break;
- case 'm':
- if(p+4 > e) goto err;
-// u = GET4(p), p += 4;
- if(u > e-p) goto err;
-// m = va_arg(a, mpint*);
-// betomp(p, u, m), p += u;
- break;
- case 's':
- if(p+4 > e) goto err;
-// u = GET4(p), p += 4;
- if(u > e-p) goto err;
- *va_arg(a, void**) = p;
- *va_arg(a, int*) = u;
- p += u;
- break;
- case '[':
- s = va_arg(a, void*);
- u = va_arg(a, int);
- if(u > e-p) goto err;
- memmove(s, p, u);
- p += u;
- break;
- case 'u':
- if(p+4 > e) goto err;
-// u = GET4(p);
- *va_arg(a, int*) = u;
- p += 4;
+ case 'd':
+ if(p+8 > e)
+ goto err;
+
+ d.hi = get4(p), p += 4;
+ d.lo = get4(p), p += 4;
+ *va_arg(a, double*) = d.x;
+
break;
}
}
diff --git a/party.c b/party.c
new file mode 100644
index 0000000..d6b0e52
--- /dev/null
+++ b/party.c
@@ -0,0 +1,44 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
+
+Party theparty;
+
+
+void
+inittheparty(void)
+{
+ theparty.next = theparty.prev = &theparty;
+}
+
+Party *
+newparty(Player *players)
+{
+ Party *p;
+
+ p = emalloc(sizeof(Party));
+ p->players[0] = players[0];
+ p->players[1] = players[1];
+
+ addparty(p);
+
+ return p;
+}
+
+void
+delparty(Party *p)
+{
+ p->next->prev = p->prev;
+ p->prev->next = p->next;
+ free(p);
+}
+
+void
+addparty(Party *p)
+{
+ p->prev = theparty.prev;
+ p->next = &theparty;
+ theparty.prev->next = p;
+ theparty.prev = p;
+}