More fixes for network code (slaves don't block anymore)

This commit is contained in:
Stefan Bühler 2009-08-10 21:44:41 +02:00
parent 36a55544f9
commit 9b60fa91f0
2 changed files with 68 additions and 63 deletions

25
game.c
View File

@ -836,7 +836,7 @@ static int getaction(void) {
static int iterate(void) { static int iterate(void) {
int i; int i;
static int deathcount=0; static int deathcount = 0;
mypause(); mypause();
scaninput(); scaninput();
@ -845,9 +845,9 @@ static int iterate(void) {
clearspritelist(); clearspritelist();
gfxunlock(); gfxunlock();
myaction=getaction(); myaction = getaction();
if(NETWORK_NONE == network && myaction==ACT_QUIT) return CODE_QUIT; if (NETWORK_NONE == network && myaction==ACT_QUIT) return CODE_QUIT;
i=networktraffic(); i = networktraffic();
if(i<0) if(i<0)
gountil=mycount+1; gountil=mycount+1;
else else
@ -855,12 +855,12 @@ static int iterate(void) {
while(mycount<gountil) { while(mycount<gountil) {
++mycount; ++mycount;
if(NETWORK_NONE != network) { if (NETWORK_NONE != network) {
i=gountil-mycount; i = gountil - mycount;
if(i>=ACTIONHIST) // too far behind if(i >= ACTIONHIST) // too far behind
return CODE_QUIT; goto leave_game;
memcpy(actions,actionblock+i*MAXNETNODES,MAXNETNODES); memcpy(actions, actionblock+i*MAXNETNODES, MAXNETNODES);
if(actions[myslot]==ACT_QUIT) return CODE_QUIT; if (actions[myslot] == ACT_QUIT) return CODE_QUIT;
} }
processbombs(); processbombs();
dodetonations(); dodetonations();
@ -907,6 +907,11 @@ static int iterate(void) {
deathcount=0; deathcount=0;
} }
return CODE_CONT; return CODE_CONT;
leave_game: /* client disconnect/timeout: send ACT_QUIT to master */
myaction = ACT_QUIT;
networktraffic();
return CODE_QUIT;
} }
void set_game_options(GameOptions *options) { void set_game_options(GameOptions *options) {

106
network.c
View File

@ -291,66 +291,66 @@ int networktraffic(void) {
case NETWORK_MASTER: case NETWORK_MASTER:
memcpy(actions,latestactions,MAXNETNODES); memcpy(actions,latestactions,MAXNETNODES);
actions[0]=myaction; actions[0]=myaction;
now=gtime(); if (myaction == ACT_QUIT) {
for(;;) { for (i = 1; i < MAXNETNODES; ++i) {
if(gtime()-now>15) break; if (netnodes[i].used)
length=getmsg(5); actions[i]=ACT_QUIT;
if(length>0 && *mesg!=PKT_MYDATA) fprintf(stderr, "Strange packet %d\n", (int) *mesg); }
// check for unexpected old packets... } else {
// for example JOIN on frame 0, respond with BEGIN if player already in game now=gtime();
// respond with uninvite INVITE on JOIN from others for(;;) {
if(length<10) continue; if(gtime()-now>15) break;
whosent = isvalidmsg_from_slave(); length=getmsg(5);
if(whosent<=0) continue; if(length>0 && *mesg!=PKT_MYDATA) fprintf(stderr, "Strange packet %d\n", (int) *mesg);
count=readuint32(mesg+5); /* check for unexpected old packets...
if(count>latestcounts[whosent]) { * for example JOIN on frame 0, respond with BEGIN if player already in game
latestcounts[whosent]=count; * respond with uninvite INVITE on JOIN from others
actions[whosent]=mesg[9]; */
if (length < 10) continue;
whosent = isvalidmsg_from_slave();
if (whosent <= 0) continue;
count = readuint32(mesg+5);
if (count > latestcounts[whosent]) {
latestcounts[whosent] = count;
actions[whosent] = mesg[9];
}
} }
} }
if(myaction==ACT_QUIT) {
for(i=1;i<MAXNETNODES;++i)
if(netnodes[i].used)
actions[i]=ACT_QUIT;
}
addactions(); addactions(); /* update action history block */
for(i=1;i<MAXNETNODES;++i)
if(netnodes[i].used) for (i = 1; i < MAXNETNODES; ++i) {
sendactions(i); if(netnodes[i].used) {
for(i=1;i<MAXNETNODES;++i) sendactions(i); /* send actions to every active node */
if(netnodes[i].used && actions[i]==ACT_QUIT) if (actions[i]==ACT_QUIT)
netnodes[i].used=0; netnodes[i].used=0; /* remove disconnected clients */
}
}
return actioncount; return actioncount;
case NETWORK_SLAVE: case NETWORK_SLAVE:
{ count = -1; /* set to actioncount if we got at least one packet */
long latest=-1; now = gtime();
long lastsent;
lastsent=now=gtime(); ++mydatacount;
++mydatacount; sendmine(mydatacount);
sendmine(mydatacount);
for(;;) { for(;;) {
/* /* if we got already one packet we only wait 3msec, otherwise 30msec */
if(gtime()-lastsent>=1) long cur = gtime();
{ if (count >= 0 && cur - now > 3) break;
lastsent=gtime(); if (exitflag || cur - now > 30) break;
sendmine(mydatacount);
} length = getmsg(count >= 0 ? 3 : 20);
*/
if(latest>=0 && gtime()-now>3) break; if (MAXNETNODES*ACTIONHIST+9 != length) continue;
length=getmsg(3); if (!isvalidmsg_from_master()) continue;
if(length==MAXNETNODES*ACTIONHIST+9 &&
sender.sin_addr.s_addr==mastername.sin_addr.s_addr && i = readuint32(mesg+5);
sender.sin_port==mastername.sin_port) { if (i < actioncount) continue;
i=readuint32(mesg+5); count = actioncount = i;
if(i<latest) continue; memcpy(actionblock,mesg+9,MAXNETNODES*ACTIONHIST);
latest=i;
memmove(actionblock,mesg+9,MAXNETNODES*ACTIONHIST);
}
}
return latest;
} }
return actioncount;
} }
return -1; return -1;
} }