From c69fa66f609925a98acf8dc7f645b9b50ce3a8ba Mon Sep 17 00:00:00 2001 From: rodri Date: Sat, 11 Jun 2022 22:37:59 +0000 Subject: implemented a custom PDU/frame structure on top of UDP for game networking. --- dat.h | 18 +++++++++++++++++- lobby.c | 1 + musw.c | 14 +++++++++++++- muswd.c | 29 ++++++++++++++++++----------- pack.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ party.c | 1 + physics.c | 1 + sprite.c | 1 + universe.c | 1 + 9 files changed, 102 insertions(+), 13 deletions(-) diff --git a/dat.h b/dat.h index 40171cf..b4f7147 100644 --- a/dat.h +++ b/dat.h @@ -23,6 +23,10 @@ enum { SCRHB = SCRH+2*Borderwidth }; +enum { + Framesize = 4+4+4+2, +}; + typedef struct VModel VModel; typedef struct Sprite Sprite; typedef struct Particle Particle; @@ -31,9 +35,11 @@ typedef struct Ship Ship; typedef struct Star Star; typedef struct Universe Universe; typedef struct Derivative Derivative; + +typedef struct Frame Frame; typedef struct Conn Conn; -typedef struct Player Player; typedef struct PInput PInput; +typedef struct Player Player; typedef struct Lobby Lobby; typedef struct Party Party; @@ -111,6 +117,16 @@ struct Derivative Point2 dv; /* a */ }; +struct Frame +{ + Udphdr *udp; + uint seq; + uint ack; + uint id; + ushort len; + uchar data[]; +}; + struct Conn { char dir[40]; diff --git a/lobby.c b/lobby.c index b1a1ff3..d5f56f2 100644 --- a/lobby.c +++ b/lobby.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "libgeometry/geometry.h" #include "dat.h" diff --git a/musw.c b/musw.c index 70a8a4b..10ca01b 100644 --- a/musw.c +++ b/musw.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -219,12 +220,23 @@ threadnetsend(void *arg) uchar buf[1024]; int fd, n; ulong kdown; + Frame *frame; fd = *(int*)arg; + frame = emalloc(sizeof(Frame)+sizeof(kdown)); + frame->udp = nil; + frame->seq = 223; + frame->ack = 222; + frame->id = ntruerand(100); + frame->len = sizeof(kdown); for(;;){ kdown = recvul(kchan); - n = pack(buf, sizeof buf, "k", kdown); + frame->data[0] = kdown>>24; + frame->data[1] = kdown>>16; + frame->data[2] = kdown>>8; + frame->data[3] = kdown; + n = pack(buf, sizeof buf, "F", frame); if(write(fd, buf, n) != n) sysfatal("write: %r"); } diff --git a/muswd.c b/muswd.c index 8e07272..4ebd7e9 100644 --- a/muswd.c +++ b/muswd.c @@ -20,26 +20,33 @@ threadlisten(void *arg) ushort rport, lport; ulong kdown; Ioproc *io; - Udphdr *udp; +// Udphdr *udp; + Frame *frame; fd = *(int*)arg; io = ioproc(); + frame = emalloc(sizeof(Frame)); while((n = ioread(io, fd, buf, sizeof buf)) > 0){ - if(n < Udphdrsize) - continue; - - udp = (Udphdr*)buf; - p = buf+Udphdrsize; +// if(n < Udphdrsize) +// continue; +// +// udp = (Udphdr*)buf; + p = buf; e = buf+n; - rport = udp->rport[0]<<8 | udp->rport[1]; - lport = udp->lport[0]<<8 | udp->lport[1]; + unpack(p, e-p, "F", frame); + + rport = frame->udp->rport[0]<<8 | frame->udp->rport[1]; + lport = frame->udp->lport[0]<<8 | frame->udp->lport[1]; + kdown = frame->data[0]<<24| + frame->data[1]<<16| + frame->data[2]<<8| + frame->data[3]; - unpack(p, e-p, "k", &kdown); if(debug) - fprint(2, "%I!%d → %I!%d | %d (%d) rcvd %.*lub\n", - udp->raddr, rport, udp->laddr, lport, threadid(), getpid(), sizeof(kdown)*8, kdown); + fprint(2, "%I!%d → %I!%d | %d (%d) rcvd seq %ud ack %ud id %ud len %ud %.*lub\n", + frame->udp->raddr, rport, frame->udp->laddr, lport, threadid(), getpid(), frame->seq, frame->ack, frame->id, frame->len, sizeof(kdown)*8, kdown); } closeioproc(io); } diff --git a/pack.c b/pack.c index be9b170..1096f6b 100644 --- a/pack.c +++ b/pack.c @@ -1,10 +1,23 @@ #include #include +#include #include #include "libgeometry/geometry.h" #include "dat.h" #include "fns.h" +static ushort +get2(uchar *p) +{ + return p[0]<<8 | p[1]; +} + +static void +put2(uchar *p, ushort u) +{ + p[0] = u>>8, p[1] = u; +} + static ulong get4(uchar *p) { @@ -24,6 +37,7 @@ vpack(uchar *p, int n, char *fmt, va_list a) ulong k; FPdbleword d; Point2 P; + Frame *F; for(;;){ switch(*fmt++){ @@ -56,6 +70,19 @@ vpack(uchar *p, int n, char *fmt, va_list a) put4(p, k), p += 4; + break; + case 'F': + F = va_arg(a, Frame*); + + if(p+Framesize+F->len > e) + goto err; + + put4(p, F->seq), p += 4; + put4(p, F->ack), p += 4; + put4(p, F->id), p += 4; + put2(p, F->len), p += 2; + memmove(p, F->data, F->len), p += F->len; + break; } } @@ -70,6 +97,7 @@ vunpack(uchar *p, int n, char *fmt, va_list a) ulong k; FPdbleword d; Point2 P; + Frame *F; for(;;){ switch(*fmt++){ @@ -99,6 +127,27 @@ vunpack(uchar *p, int n, char *fmt, va_list a) k = get4(p), p += 4; *va_arg(a, ulong*) = k; + break; + case 'F': + if(p+Udphdrsize+Framesize > e) + goto err; + + F = va_arg(a, Frame*); + + F->udp = (Udphdr*)p, p += Udphdrsize; + F->seq = get4(p), p += 4; + F->ack = get4(p), p += 4; + F->id = get4(p), p += 4; + F->len = get2(p), p += 2; + + /* XXX: I'm not happy with this. */ + if(p+F->len > e) + goto err; + + F = erealloc(F, sizeof(Frame)+F->len); + memmove(F->data, p, F->len); + p += F->len; + break; } } diff --git a/party.c b/party.c index 2b2496a..cacf2e4 100644 --- a/party.c +++ b/party.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "libgeometry/geometry.h" #include "dat.h" diff --git a/physics.c b/physics.c index 5c8879d..f7fd284 100644 --- a/physics.c +++ b/physics.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "libgeometry/geometry.h" #include "dat.h" diff --git a/sprite.c b/sprite.c index cf5af36..c857a85 100644 --- a/sprite.c +++ b/sprite.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "libgeometry/geometry.h" #include "dat.h" diff --git a/universe.c b/universe.c index b620a61..5a4ea82 100644 --- a/universe.c +++ b/universe.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "libgeometry/geometry.h" #include "dat.h" -- cgit v1.2.3