aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2023-05-05 22:35:14 +0000
committerrodri <rgl@antares-labs.eu>2023-05-05 22:35:14 +0000
commitd2c0ab7a62b7a2c99c4c491ce55466859429571b (patch)
tree5010f2e6b2e3a87486a7f65dd73f40eee7fec04c
parentf959555dc653ecf54d75b180fcd018075e652e93 (diff)
downloadmusw-d2c0ab7a62b7a2c99c4c491ce55466859429571b.tar.gz
musw-d2c0ab7a62b7a2c99c4c491ce55466859429571b.tar.bz2
musw-d2c0ab7a62b7a2c99c4c491ce55466859429571b.zip
handle player quits gracefully.
also fixed a bug whereby a player would never be freed if no party was happening, and another one where deleting a player from the player queue would cause a nil pointer deref.
-rw-r--r--dat.h4
-rw-r--r--musw.c35
-rw-r--r--muswd.c19
-rw-r--r--party.c2
-rw-r--r--vmodeled/vmodeled.man4
5 files changed, 55 insertions, 9 deletions
diff --git a/dat.h b/dat.h
index 3e8e703..88f7a64 100644
--- a/dat.h
+++ b/dat.h
@@ -32,11 +32,13 @@ enum {
NShi, /* S accepts. sends P and G for DHX */
NCdhx = 12, /* C shares pubkey */
NSdhx, /* S shares pubkey */
- NCnudge = 16,
+ NCnudge = 16, /* nudge ACK */
NSnudge, /* check the pulse of the line */
NCinput = 20, /* C sends player input state */
NSsimstate, /* S sends current simulation state */
+ NCawol = 22, /* AWOL ACK */
+ NSawol, /* notify the adversary flew away */
NCbuhbye = 30,
NSbuhbye,
diff --git a/musw.c b/musw.c
index 0703393..edd3826 100644
--- a/musw.c
+++ b/musw.c
@@ -232,6 +232,26 @@ initconn(void)
}
void
+buhbye(void)
+{
+ Frame *frame;
+ int i, naptime;
+
+ if(netconn.state != NCSConnected)
+ return;
+
+ i = 10;
+ naptime = 2000/i;
+ while(i--){
+ frame = newframe(nil, NCbuhbye, netconn.lastseq+1, 0, 0, nil);
+ signframe(frame, netconn.dh.priv);
+ sendp(egress, frame);
+
+ sleep(naptime);
+ }
+}
+
+void
sendkeys(ulong kdown)
{
Frame *frame;
@@ -273,8 +293,12 @@ kbdproc(void *)
}
if(buf[0] == 'c'){
if(utfrune(buf, Kdel)){
+defenestrate:
close(fd);
threadexitsall(nil);
+ }else if(utfrune(buf, 'q')){
+ buhbye();
+ goto defenestrate;
}
}
if(buf[0] != 'k' && buf[0] != 'K')
@@ -415,6 +439,15 @@ threadnetppu(void *)
sendp(egress, newf);
break;
+ case NSawol:
+ weplaying = 0;
+
+ newf = newframe(nil, NCawol, frame->seq+1, frame->seq, 0, nil);
+ signframe(newf, netconn.dh.priv);
+
+ sendp(egress, newf);
+
+ break;
case NSbuhbye:
weplaying = 0;
netconn.state = NCSDisconnected;
@@ -607,6 +640,8 @@ State *matching_δ(State *s, void*)
State *playing_δ(State *s, void*)
{
+ if(!weplaying)
+ return &gamestates[GSMatching];
return s;
}
diff --git a/muswd.c b/muswd.c
index cb0be8b..472ce39 100644
--- a/muswd.c
+++ b/muswd.c
@@ -47,6 +47,8 @@ dissolveparty(Player *player)
{
int i;
Party *p;
+ Player *adv;
+ Frame *f;
/*
* kick the player and put their adversary back in the
@@ -55,16 +57,25 @@ dissolveparty(Player *player)
for(p = theparty.next; p != &theparty; p = p->next)
for(i = 0; i < nelem(p->players); i++)
if(p->players[i] == player){
- delplayer(p->players[i]);
- players.put(&players, p->players[i^1]);
+ adv = p->players[i^1];
+
+ players.put(&players, adv);
delparty(p);
+
+ /* notify the adversary */
+ f = newframe(&adv->conn->udp, NSawol, 0, 0, 0, nil);
+ signframe(f, adv->conn->dh.priv);
+ sendp(egress, f);
+
+ return;
}
/*
- * also clean the player queue
- * TODO: has nothing to do with the party
+ * make sure to free the player even if there's no
+ * party going on.
*/
players.del(&players, player);
+ delplayer(player);
}
int
diff --git a/party.c b/party.c
index 1360875..be0f4ed 100644
--- a/party.c
+++ b/party.c
@@ -117,7 +117,7 @@ playerq_del(Playerq *pq, Player *p)
return;
}
- for(np = pq->head; np->next != nil; np = np->next)
+ for(np = pq->head; np != nil && np->next != nil; np = np->next)
if(np->next == p){
np->next = np->next->next;
p->next = nil;
diff --git a/vmodeled/vmodeled.man b/vmodeled/vmodeled.man
index c877d32..13ad0ed 100644
--- a/vmodeled/vmodeled.man
+++ b/vmodeled/vmodeled.man
@@ -6,9 +6,7 @@ vmodeled \- musw vector model editor
.I file
.SH DESCRIPTION
.I Vmodeled
-is a vector model—
-.B VModel
-—editor created with the purpose of customizing
+is a vector model (VModel) editor created with the purpose of customizing
.IR musw (1)
ships defined in the
.B vmdl