diff options
author | rodri <rgl@antares-labs.eu> | 2021-07-25 20:59:58 +0000 |
---|---|---|
committer | rodri <rgl@antares-labs.eu> | 2021-07-25 20:59:58 +0000 |
commit | bdaa63a1a4604ada3539aeb50e4af144da3ba6f0 (patch) | |
tree | 6aa3d68f94d7756d45f78cce10af1796bdb744d2 | |
parent | f54a8666413d80db3bda3de6e17f795faf7790eb (diff) | |
download | musw-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.h | 35 | ||||
-rw-r--r-- | fns.h | 9 | ||||
-rw-r--r-- | lobby.c | 76 | ||||
-rw-r--r-- | mkfile | 1 | ||||
-rw-r--r-- | musw.c | 18 | ||||
-rw-r--r-- | muswd.c | 75 | ||||
-rw-r--r-- | pack.c | 114 | ||||
-rw-r--r-- | party.c | 44 |
8 files changed, 237 insertions, 135 deletions
@@ -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; @@ -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*); + @@ -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); } @@ -11,6 +11,7 @@ OFILES=\ nanosec.$O\ pack.$O\ lobby.$O\ + party.$O\ HFILES=\ dat.h\ @@ -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; @@ -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); @@ -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; } } @@ -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; +} |