From 36c65378479e64616b1979462c258ebaa414e15a Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 22 Oct 2006 19:18:15 +0000 Subject: [PATCH] Added timeouts to viewers, added a cleanup. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2424 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- fteqtv/control.c | 1 + fteqtv/parse.c | 37 ++++++++++++++----------- fteqtv/qtv.h | 2 +- fteqtv/qw.c | 10 ++++++- fteqtv/rcon.c | 2 +- fteqtv/source.c | 72 ++++++++++++++++++++++++++++-------------------- 6 files changed, 75 insertions(+), 49 deletions(-) diff --git a/fteqtv/control.c b/fteqtv/control.c index c027ab674..8ad009d22 100644 --- a/fteqtv/control.c +++ b/fteqtv/control.c @@ -261,6 +261,7 @@ void Cluster_Run(cluster_t *cluster, qboolean dowait) if (cluster->inputlength >= 1) { cluster->commandinput[cluster->inputlength-1] = 0; // rip off the /n and terminate + cluster->inputlength--; if (cluster->inputlength) { diff --git a/fteqtv/parse.c b/fteqtv/parse.c index 7cdcb6775..e5543d496 100644 --- a/fteqtv/parse.c +++ b/fteqtv/parse.c @@ -387,7 +387,7 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask) } else { - if (tv->file) + if (tv->sourcefile) snprintf(text, sizeof(text), "%s (recorded from: %s)", tv->cluster->hostname, value); else snprintf(text, sizeof(text), "%s (live: %s)", tv->cluster->hostname, value); @@ -1196,15 +1196,15 @@ void ParseDownload(sv_t *tv, netmsg_t *m) unsigned int percent; char buffer[2048]; - size = ReadShort(m); + size = (signed short)ReadShort(m); percent = ReadByte(m); if (size < 0) { Sys_Printf(tv->cluster, "Downloading failed\n"); - if (tv->file) - fclose(tv->file); - tv->file = NULL; + if (tv->downloadfile) + fclose(tv->downloadfile); + tv->downloadfile = NULL; tv->drop = true; return; } @@ -1212,18 +1212,18 @@ void ParseDownload(sv_t *tv, netmsg_t *m) for (b = 0; b < size; b++) buffer[b] = ReadByte(m); - if (!tv->file) + if (!tv->downloadfile) { Sys_Printf(tv->cluster, "Not downloading anything\n"); tv->drop = true; return; } - fwrite(buffer, 1, size, tv->file); + fwrite(buffer, 1, size, tv->downloadfile); if (percent == 100) { - fclose(tv->file); - tv->file = NULL; + fclose(tv->downloadfile); + tv->downloadfile = NULL; snprintf(buffer, sizeof(buffer), "%s/%s", (tv->gamedir&&*tv->gamedir)?tv->gamedir:"id1", tv->modellist[1].name); rename(tv->downloadname, buffer); @@ -1232,7 +1232,10 @@ void ParseDownload(sv_t *tv, netmsg_t *m) tv->bsp = BSP_LoadModel(tv->cluster, tv->gamedir, tv->modellist[1].name); if (!tv->bsp) + { + Sys_Printf(tv->cluster, "Failed to read BSP\n"); tv->drop = true; + } else { SendClientCommand(tv, "prespawn %i 0 %i\n", tv->clservercount, LittleLong(BSP_Checksum(tv->bsp))); @@ -1470,19 +1473,21 @@ void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask) { if (i) SendClientCommand(tv, "modellist %i %i\n", tv->clservercount, i); - else if (!tv->bsp) + else if (!tv->bsp && !tv->cluster->nobsp) { - if (tv->file) + if (tv->downloadfile) { - fclose(tv->file); + fclose(tv->downloadfile); unlink(tv->downloadname); Sys_Printf(tv->cluster, "Was already downloading %s\nOld download canceled\n", tv->downloadname); - tv->file = NULL; + tv->downloadfile = NULL; } snprintf(tv->downloadname, sizeof(tv->downloadname), "%s/%s.tmp", (tv->gamedir&&*tv->gamedir)?tv->gamedir:"id1", tv->modellist[1].name); - tv->file = fopen(tv->downloadname, "wb"); - if (!tv->file) - tv->drop = true; + tv->downloadfile = fopen(tv->downloadname, "wb"); + if (!tv->downloadfile) + { + Sys_Printf(tv->cluster, "Couldn't open temporary file %s\n", tv->downloadname); + } else { strcpy(tv->status, "Downloading map\n"); diff --git a/fteqtv/qtv.h b/fteqtv/qtv.h index c708f67bc..000ee8198 100644 --- a/fteqtv/qtv.h +++ b/fteqtv/qtv.h @@ -559,7 +559,7 @@ struct sv_s { qboolean maysend; - FILE *file; + FILE *sourcefile; unsigned int filelength; SOCKET sourcesock; diff --git a/fteqtv/qw.c b/fteqtv/qw.c index 6830af32f..626a55862 100644 --- a/fteqtv/qw.c +++ b/fteqtv/qw.c @@ -646,6 +646,7 @@ qboolean ChallengePasses(netadr_t *addr, int challenge) void NewClient(cluster_t *cluster, viewer_t *viewer) { + viewer->timeout = cluster->curtime + 15*1000; viewer->trackplayer = -1; @@ -3179,7 +3180,7 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer) sv = viewer->server; WriteString2(&m, "\n\nConnection Admin\n"); WriteString2(&m, sv->hostname); - if (sv->file) + if (sv->sourcefile) WriteString2(&m, " (demo)"); WriteString2(&m, "\n\n"); @@ -3456,6 +3457,8 @@ void QW_UpdateUDPStuff(cluster_t *cluster) if (useserver && useserver->parsingconnectiondata) useserver = NULL; + v->timeout = cluster->curtime + 15*1000; + ParseNQC(cluster, useserver, v, &m); if (v->server && v->server->controller == v) @@ -3475,6 +3478,8 @@ void QW_UpdateUDPStuff(cluster_t *cluster) if (useserver && useserver->parsingconnectiondata) useserver = NULL; + v->timeout = cluster->curtime + 15*1000; + v->netchan.outgoing_sequence = v->netchan.incoming_sequence; //compensate for client->server packetloss. if (v->server && v->server->controller == v) { @@ -3582,6 +3587,9 @@ void QW_UpdateUDPStuff(cluster_t *cluster) v->drop |= v->netchan.drop; + if (v->timeout < cluster->curtime) + v->drop = true; + if (v->netchan.isnqprotocol) { v->maysend = (v->nextpacket < cluster->curtime); diff --git a/fteqtv/rcon.c b/fteqtv/rcon.c index a031564d1..de4135680 100644 --- a/fteqtv/rcon.c +++ b/fteqtv/rcon.c @@ -509,7 +509,7 @@ char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe if (qtv) { catbuffer(buffer, sizeofbuffer, "Selected server: %s\n", qtv->server); - if (qtv->file) + if (qtv->sourcefile) catbuffer(buffer, sizeofbuffer, "Playing from file\n"); if (qtv->sourcesock != INVALID_SOCKET) catbuffer(buffer, sizeofbuffer, "Connected\n"); diff --git a/fteqtv/source.c b/fteqtv/source.c index 060c11eb3..fdadd0e77 100644 --- a/fteqtv/source.c +++ b/fteqtv/source.c @@ -413,12 +413,12 @@ qboolean Net_ConnectToServer(sv_t *qtv, char *ip) if (!strncmp(ip, "file:", 5) || !strncmp(ip, "demo:", 5)) { qtv->sourcesock = INVALID_SOCKET; - qtv->file = fopen(ip+5, "rb"); - if (qtv->file) + qtv->sourcefile = fopen(ip+5, "rb"); + if (qtv->sourcefile) { - fseek(qtv->file, 0, SEEK_END); - qtv->filelength = ftell(qtv->file); - fseek(qtv->file, 0, SEEK_SET); + fseek(qtv->sourcefile, 0, SEEK_END); + qtv->filelength = ftell(qtv->sourcefile); + fseek(qtv->sourcefile, 0, SEEK_SET); return true; } Sys_Printf(qtv->cluster, "Unable to open file %s\n", ip+5); @@ -541,13 +541,13 @@ qboolean Net_ReadStream(sv_t *qtv) return true; //this is bad! buffer = qtv->buffer + qtv->buffersize; - if (qtv->file) + if (qtv->sourcefile) { if (maxreadable > PREFERED_PROXY_BUFFER-qtv->buffersize) maxreadable = PREFERED_PROXY_BUFFER-qtv->buffersize; if (maxreadable<=0) return true; - read = fread(buffer, 1, maxreadable, qtv->file); + read = fread(buffer, 1, maxreadable, qtv->sourcefile); } else { @@ -586,7 +586,7 @@ qboolean Net_ReadStream(sv_t *qtv) err = qerrno; if (read == 0 || (err != EWOULDBLOCK && err != EAGAIN && err != ENOTCONN)) //ENOTCONN can be returned whilst waiting for a connect to finish. { - if (qtv->file) + if (qtv->sourcefile) Sys_Printf(qtv->cluster, "Error: End of file\n"); else if (read) Sys_Printf(qtv->cluster, "Error: source socket error %i\n", qerrno); @@ -597,10 +597,10 @@ qboolean Net_ReadStream(sv_t *qtv) closesocket(qtv->sourcesock); qtv->sourcesock = INVALID_SOCKET; } - if (qtv->file) + if (qtv->sourcefile) { - fclose(qtv->file); - qtv->file = NULL; + fclose(qtv->sourcefile); + qtv->sourcefile = NULL; } return false; } @@ -745,10 +745,10 @@ qboolean QTV_Connect(sv_t *qtv, char *serverurl) qtv->sourcesock = INVALID_SOCKET; } - if (qtv->file) + if (qtv->sourcefile) { - fclose(qtv->file); - qtv->file = NULL; + fclose(qtv->sourcefile); + qtv->sourcefile = NULL; } *qtv->serverinfo = '\0'; @@ -795,10 +795,16 @@ void QTV_Shutdown(sv_t *qtv) closesocket(qtv->sourcesock); qtv->sourcesock = INVALID_SOCKET; } - if (qtv->file) + if (qtv->sourcefile) { - fclose(qtv->file); - qtv->file = NULL; + fclose(qtv->sourcefile); + qtv->sourcefile = NULL; + } + if (qtv->downloadfile) + { + fclose(qtv->downloadfile); + qtv->downloadfile = NULL; + unlink(qtv->downloadname); } if (qtv->tcpsocket != INVALID_SOCKET) closesocket(qtv->tcpsocket); @@ -1002,6 +1008,9 @@ void QTV_ParseQWStream(sv_t *qtv) //FIXME: Check for error break; } + if (readlen > sizeof(buffer)-1) + break; //oversized! + buffer[readlen] = 0; if (*(int*)buffer == -1) { @@ -1166,10 +1175,13 @@ void QTV_Run(sv_t *qtv) int oldcurtime; int packettime; - if (qtv->drop || (qtv->disconnectwhennooneiswatching && qtv->numviewers == 0 && qtv->proxies == NULL)) + if (qtv->disconnectwhennooneiswatching && qtv->numviewers == 0 && qtv->proxies == NULL) + { + Sys_Printf(qtv->cluster, "Stream %s became inactive\n", qtv->server); + qtv->drop = true; + } + if (qtv->drop) { - if (!qtv->drop) - Sys_Printf(qtv->cluster, "Stream %s became inactive\n", qtv->server); QTV_Shutdown(qtv); return; } @@ -1330,7 +1342,7 @@ void QTV_Run(sv_t *qtv) qtv->simtime = qtv->curtime; - if (qtv->sourcesock == INVALID_SOCKET && !qtv->file) + if (qtv->sourcesock == INVALID_SOCKET && !qtv->sourcefile) { if (qtv->curtime >= qtv->nextconnectattempt || qtv->curtime < qtv->nextconnectattempt - RECONNECT_TIME*2) if (!QTV_Connect(qtv, qtv->server)) @@ -1342,7 +1354,7 @@ void QTV_Run(sv_t *qtv) SV_FindProxies(qtv->tcpsocket, qtv->cluster, qtv); //look for any other proxies wanting to muscle in on the action. - if (qtv->file || qtv->sourcesock != INVALID_SOCKET) + if (qtv->sourcefile || qtv->sourcesock != INVALID_SOCKET) { if (!Net_ReadStream(qtv)) { //if we have an error reading it @@ -1499,7 +1511,7 @@ void QTV_Run(sv_t *qtv) if (qtv->parsetime < qtv->curtime) { qtv->parsetime = qtv->curtime + 2*1000; //add two seconds - if (qtv->file || qtv->sourcesock != INVALID_SOCKET) + if (qtv->sourcefile || qtv->sourcesock != INVALID_SOCKET) Sys_Printf(qtv->cluster, "Not enough buffered\n"); } break; @@ -1514,7 +1526,7 @@ void QTV_Run(sv_t *qtv) if (qtv->buffersize < length) { //not enough stuff to play. qtv->parsetime = qtv->curtime + 2*1000; //add two seconds - if (qtv->file || qtv->sourcesock != INVALID_SOCKET) + if (qtv->sourcefile || qtv->sourcesock != INVALID_SOCKET) Sys_Printf(qtv->cluster, "Not enough buffered\n"); continue; } @@ -1540,7 +1552,7 @@ void QTV_Run(sv_t *qtv) if (qtv->buffersize < lengthofs+4) { //the size parameter doesn't fit. - if (qtv->file || qtv->sourcesock != INVALID_SOCKET) + if (qtv->sourcefile || qtv->sourcesock != INVALID_SOCKET) Sys_Printf(qtv->cluster, "Not enough buffered\n"); qtv->parsetime = qtv->curtime + 2*1000; //add two seconds break; @@ -1552,10 +1564,10 @@ void QTV_Run(sv_t *qtv) { //FIXME: THIS SHOULDN'T HAPPEN! //Blame the upstream proxy! Sys_Printf(qtv->cluster, "Warning: corrupt input packet (%i) too big! Flushing and reconnecting!\n", length); - if (qtv->file) + if (qtv->sourcefile) { - fclose(qtv->file); - qtv->file = NULL; + fclose(qtv->sourcefile); + qtv->sourcefile = NULL; } else { @@ -1568,7 +1580,7 @@ void QTV_Run(sv_t *qtv) if (length+lengthofs+4 > qtv->buffersize) { - if (qtv->file || qtv->sourcesock != INVALID_SOCKET) + if (qtv->sourcefile || qtv->sourcesock != INVALID_SOCKET) Sys_Printf(qtv->cluster, "Not enough buffered\n"); qtv->parsetime = qtv->curtime + 2*1000; //add two seconds break; //can't parse it yet. @@ -1615,7 +1627,7 @@ void QTV_Run(sv_t *qtv) qtv->forwardpoint -= length; } - if (qtv->file) + if (qtv->sourcefile) Net_ReadStream(qtv); qtv->parsetime += packettime;