aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2021-07-25 20:59:58 +0000
committerrodri <rgl@antares-labs.eu>2021-07-25 20:59:58 +0000
commitbdaa63a1a4604ada3539aeb50e4af144da3ba6f0 (patch)
tree6aa3d68f94d7756d45f78cce10af1796bdb744d2
parentf54a8666413d80db3bda3de6e17f795faf7790eb (diff)
downloadmusw-bdaa63a1a4604ada3539aeb50e4af144da3ba6f0.tar.gz
musw-bdaa63a1a4604ada3539aeb50e4af144da3ba6f0.tar.bz2
musw-bdaa63a1a4604ada3539aeb50e4af144da3ba6f0.zip
implemented parties to hold PvP match info.
started serializing game state through the wire. made some major changes to the Lobby struct, plus the ability to check the health of every connection. added some more debug statements, did some cleanup and put more checks.
-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;
+}