From f321ee32eebce575c742d31dbef8e8eb7710ef10 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 9 Jan 2007 05:24:03 +0000 Subject: [PATCH] some bugs have been spotted. one serious one regarding demos and small downloads and reading configs. a couple of minor ones, and a minor cleanup too. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2464 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- fteqtv/forward.c | 37 +++++ fteqtv/parse.c | 7 +- fteqtv/qtv.h | 17 ++- fteqtv/qw.c | 355 +++++++++++++++++++++++++---------------------- fteqtv/rcon.c | 7 +- fteqtv/source.c | 83 +++++++++-- 6 files changed, 314 insertions(+), 192 deletions(-) diff --git a/fteqtv/forward.c b/fteqtv/forward.c index b6009ac73..41890ac93 100644 --- a/fteqtv/forward.c +++ b/fteqtv/forward.c @@ -825,6 +825,7 @@ void SV_GenerateQTVDemoListing(cluster_t *cluster, oproxy_t *dest) namelen = strlen(oneentry->d_name); if (namelen > 4 && !strcmp(oneentry->d_name + namelen-4, ".mvd")) { + numdemos++; snprintf(link, sizeof(link), "%s
", oneentry->d_name, oneentry->d_name); Net_ProxySend(cluster, dest, link, strlen(link)); } @@ -1064,6 +1065,42 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend) Net_ProxySend(cluster, pend, s, strlen(s)); pend->flushing = true; } + else if (!strcmp(s, "REVERSE")) + { //this is actually a server trying to connect to us + //start up a new stream + } + else if (!strcmp(s, "RECEIVE")) + { //a client connection request without a source + if (cluster->numservers == 1) + { //only one stream anyway + qtv = cluster->servers; + } + else + { //try and hunt down an explicit stream (rather than a user-recorded one) + int numfound = 0; + sv_t *suitable; + for (qtv = cluster->servers; qtv; qtv = qtv->next) + { + if (!qtv->disconnectwhennooneiswatching) + { + suitable = qtv; + numfound++; + } + } + if (numfound == 1) + qtv = suitable; + } + if (!qtv) + { + s = "QTVSV 1\n"; + Net_ProxySend(cluster, pend, s, strlen(s)); + s = "PERROR: Multiple streams are currently playing\n"; + Net_ProxySend(cluster, pend, s, strlen(s)); + s = "\n"; + Net_ProxySend(cluster, pend, s, strlen(s)); + pend->flushing = true; + } + } else if (!strcmp(s, "DEMOLIST")) { //lists the demos available on this proxy s = "QTVSV 1\n"; diff --git a/fteqtv/parse.c b/fteqtv/parse.c index 0c42c1bbd..41b633731 100644 --- a/fteqtv/parse.c +++ b/fteqtv/parse.c @@ -880,7 +880,12 @@ static void ParsePacketEntities(sv_t *tv, netmsg_t *m, int deltaframe) { newframe = &tv->frame[tv->netchan.incoming_sequence & (ENTITY_FRAMES-1)]; - if (newframe->oldframe != deltaframe) + if (tv->netchan.outgoing_sequence - tv->netchan.incoming_sequence >= ENTITY_FRAMES - 1) + { + //should drop it + Sys_Printf(tv->cluster, "Outdated frames\n"); + } + else if (deltaframe != -1 && newframe->oldframe != deltaframe) Sys_Printf(tv->cluster, "Mismatching delta frames\n"); } else diff --git a/fteqtv/qtv.h b/fteqtv/qtv.h index 015c31bb4..4f4eaf992 100644 --- a/fteqtv/qtv.h +++ b/fteqtv/qtv.h @@ -501,7 +501,7 @@ typedef struct { float angle[3]; } intermission_t; -struct sv_s { +struct sv_s { //details about a server connection (also known as stream) char connectpassword[64]; //password given to server netadr_t serveraddress; netchan_t netchan; @@ -557,7 +557,9 @@ struct sv_s { unsigned int timeout; qboolean ispaused; unsigned int packetratelimiter; + viewer_t *controller; + int controllersquencebias; qboolean proxyplayer; //a player is actually playing on the proxy. usercmd_t proxyplayerucmds[3]; @@ -572,8 +574,8 @@ struct sv_s { unsigned int filelength; SOCKET sourcesock; - SOCKET tcpsocket; //tcp + mvd protocol - int tcplistenportnum; +// SOCKET tcpsocket; //tcp + mvd protocol +// int tcplistenportnum; oproxy_t *proxies; @@ -654,10 +656,11 @@ struct cluster_s { oproxy_t *pendingproxies; }; -#define MENU_NONE 0 -#define MENU_SERVERS 1 -#define MENU_ADMIN 2 -#define MENU_ADMINSERVER 3 +#define MENU_NONE 0 +#define MENU_SERVERS 1 +#define MENU_ADMIN 2 +#define MENU_ADMINSERVER 3 +#define MENU_MAIN MENU_SERVERS diff --git a/fteqtv/qw.c b/fteqtv/qw.c index aa57c6356..d9fe9795f 100644 --- a/fteqtv/qw.c +++ b/fteqtv/qw.c @@ -914,7 +914,7 @@ void NewQWClient(cluster_t *cluster, netadr_t *addr, char *connectmessage) viewer->delta_frame = -1; initialserver = NULL; - if (cluster->numservers == 1) + if (cluster->nouserconnects && cluster->numservers == 1) { initialserver = cluster->servers; if (!initialserver->modellist[1].name[0]) @@ -1817,6 +1817,25 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg } } +//returns self, or the final commentator +viewer_t *GetCommentator(viewer_t *v) +{ + viewer_t *orig = v; + int runaway = 10; + + while(runaway-- > 0) + { + if (!v->commentator) + break; + if (v->commentator->thinksitsconnected == false) + break; + if (v->commentator->server != orig->server) + break; + v = v->commentator; + } + return v; +} + void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg) { viewer_t *cv; @@ -1839,14 +1858,6 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg) if (tv) { - if (v->trackplayer >= 0 && !v->backbuffered) - { - if (v->trackplayer != tv->trackplayer && tv->usequkeworldprotocols) - if (!tv->players[v->trackplayer].active && tv->players[tv->trackplayer].active) - { - QW_StuffcmdToViewer (v, "track %i\n", tv->trackplayer); - } - } if (tv->physicstime != v->settime && tv->cluster->chokeonnotupdated) { WriteByte(msg, svc_updatestatlong); @@ -1867,20 +1878,25 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg) if (tv->controller == v) lerp = 1; - track = v->trackplayer; - for (cv = v; cv && runaway-->0; cv = cv->commentator) - { - track = cv->trackplayer; - if (track != MAX_CLIENTS-2) - break; + cv = GetCommentator(v); + track = cv->trackplayer; + + if (cv != v && track < 0) + { //following a commentator + track = MAX_CLIENTS-2; } - /* - if (v->commentator && track == MAX_CLIENTS-2) + + if (v->trackplayer != track) + QW_StuffcmdToViewer (v, "track %i\n", track); + + if (!v->commentator && track >= 0 && !v->backbuffered) { - track = v->commentator->trackplayer; - if (track < 0) - track = MAX_CLIENTS-2; - }*/ + if (v->trackplayer != tv->trackplayer && tv->usequkeworldprotocols) + if (!tv->players[v->trackplayer].active && tv->players[tv->trackplayer].active) + { + QW_StuffcmdToViewer (v, "track %i\n", tv->trackplayer); + } + } for (i = 0; i < MAX_CLIENTS; i++) { @@ -1890,46 +1906,6 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg) continue; } - if (v->commentator && v->thinksitsconnected)// && track == i) - { - if (i == MAX_CLIENTS-2) - { - flags = PF_COMMAND; - WriteByte(msg, svc_playerinfo); - WriteByte(msg, i); - WriteShort(msg, flags); - - - interp = v->commentator->origin[0]*8; - WriteShort(msg, interp); - interp = v->commentator->origin[1]*8; - WriteShort(msg, interp); - interp = v->commentator->origin[2]*8; - WriteShort(msg, interp); - - WriteByte(msg, 0); - - if (flags & PF_MSEC) - { - WriteByte(msg, 0); - } - if (flags & PF_COMMAND) - { - to.angles[0] = v->commentator->ucmds[2].angles[0]; - to.angles[1] = v->commentator->ucmds[2].angles[1]; - to.angles[2] = v->commentator->ucmds[2].angles[2]; - WriteDeltaUsercmd(msg, &nullcmd, &to); - } - if (flags & PF_MODEL) - WriteByte(msg, tv->players[i].current.modelindex); - if (flags & PF_WEAPONFRAME) - WriteByte(msg, tv->players[i].current.weaponframe); - continue; - } - if (track == i) - continue; - } - if (!tv->players[i].active) continue; @@ -2010,8 +1986,7 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg) topacket = &tv->frame[tv->netchan.incoming_sequence&(ENTITY_FRAMES-1)]; if (tv->usequkeworldprotocols) { - //qw protocols don't interpolate... yet - frompacket = topacket; + frompacket = &tv->frame[(topacket->oldframe)&(ENTITY_FRAMES-1)]; } else { @@ -2341,31 +2316,26 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean { int newp; int news; - if (qtv) + + newp = atoi(message); + + if (newp) { - newp = atoi(message); + news = Net_MVDListen(newp); - if (newp) + if (news != INVALID_SOCKET) { - news = Net_MVDListen(newp); - - if (news != INVALID_SOCKET) - { - if (qtv->tcpsocket != INVALID_SOCKET) - closesocket(qtv->tcpsocket); - qtv->tcpsocket = news; - qtv->tcplistenportnum = newp; - qtv->disconnectwhennooneiswatching = false; - } - } - else if (qtv->tcpsocket != INVALID_SOCKET) - { - closesocket(qtv->tcpsocket); - qtv->tcpsocket = INVALID_SOCKET; + if (cluster->tcpsocket != INVALID_SOCKET) + closesocket(cluster->tcpsocket); + cluster->tcpsocket = news; + cluster->tcplistenportnum = newp; } } - else - QW_PrintfToViewer(v, "You were disconnected from that stream\n"); + else if (cluster->tcpsocket != INVALID_SOCKET) + { + closesocket(cluster->tcpsocket); + cluster->tcpsocket = INVALID_SOCKET; + } } else { @@ -2678,7 +2648,7 @@ guimenu: if (ov->server) { if (ov->server->controller == ov) - QW_PrintfToViewer(v, "%i: %s: %s\n", ov->userid, ov->name, ov->server->server); + QW_PrintfToViewer(v, "%i: %s: *%s\n", ov->userid, ov->name, ov->server->server); else QW_PrintfToViewer(v, "%i: %s: %s\n", ov->userid, ov->name, ov->server->server); } @@ -2862,7 +2832,7 @@ guimenu: { if (cluster->notalking) return; - SendClientCommand(qtv, "say %s: %s\n", v->name, message); + SendClientCommand(qtv, "say [%s]: %s\n", v->name, message); } //FIXME: we ought to broadcast this to everyone not watching that qtv. @@ -3146,8 +3116,11 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m) } if ((v->ucmds[1].buttons&2) != (v->ucmds[2].buttons&2) && (v->ucmds[2].buttons&2)) { + if (!v->server && !v->menunum) + QW_SetMenu(v, MENU_MAIN); v->trackplayer--; } + break; default: Sys_Printf(cluster, "Bad message type %i\n", mtype); @@ -3376,7 +3349,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m) else if (!strncmp(buf, "ptrack", 6)) { v->trackplayer = -1; - QW_SetCommentator(cluster, v, NULL); + QW_SetCommentator(cluster, v, NULL); //clicking out will stop the client from tracking thier commentator } else if (!strncmp(buf, "pings", 5)) { @@ -3490,6 +3463,12 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m) ReadDeltaUsercmd(m, &v->ucmds[1], &v->ucmds[2]); PMove(v, &v->ucmds[2]); + + if (v->ucmds[0].buttons & 2) + { + if (!v->server && !v->menunum) + QW_SetMenu(v, MENU_MAIN); + } break; case clc_tmove: v->origin[0] = ((signed short)ReadShort(m))/8.0f; @@ -3528,15 +3507,24 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum) i = 0; sv = viewer->server; if (i++ == viewer->menuop) - { //mvd port - QW_StuffcmdToViewer(viewer, "echo Please enter a new tcp port number\nmessagemode\n"); - strcpy(viewer->expectcommand, "setmvdport"); + { //auto disconnect + sv->disconnectwhennooneiswatching ^= 1; } if (i++ == viewer->menuop) { //disconnect QTV_Shutdown(viewer->server); } if (i++ == viewer->menuop) + { + if (sv->controller == viewer) + sv->controller = NULL; + else + { + sv->controller = viewer; + sv->controllersquencebias = viewer->netchan.outgoing_sequence - sv->netchan.outgoing_sequence; + } + } + if (i++ == viewer->menuop) { //back QW_SetMenu(viewer, MENU_ADMIN); } @@ -3670,7 +3658,7 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer) WriteString2(&m, "bad menu"); break; - case 3: //per-connection options + case MENU_ADMINSERVER: //per-connection options if (viewer->server) { sv = viewer->server; @@ -3684,16 +3672,23 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer) viewer->menuop = 0; i = 0; - WriteString2(&m, " port"); + + WriteString2(&m, " auto disconnect"); WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : "); - if (sv->tcpsocket == INVALID_SOCKET) - sprintf(str, "!%-19i", sv->tcplistenportnum); + if (viewer->server->disconnectwhennooneiswatching) + sprintf(str, "%-20s", "when inactive"); else - sprintf(str, "%-20i", sv->tcplistenportnum); + sprintf(str, "%-20s", "never"); WriteString2(&m, str); WriteString2(&m, "\n"); - WriteString2(&m, " disconnect"); + WriteString2(&m, "force disconnect"); + WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : "); + sprintf(str, "%-20s", "..."); + WriteString2(&m, str); + WriteString2(&m, "\n"); + + WriteString2(&m, " take control"); WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : "); sprintf(str, "%-20s", "..."); WriteString2(&m, str); @@ -3708,10 +3703,18 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer) if (viewer->menuop >= i) viewer->menuop = i - 1; + WriteString2(&m, "\n"); + + WriteString2(&m, " status"); + WriteString2(&m, " : "); + sprintf(str, "%-20s", viewer->server->status); + WriteString2(&m, str); + WriteString2(&m, "\n"); + break; } //fallthrough - case 1: //connections list + case MENU_SERVERS: //connections list WriteString2(&m, "\n\nServers\n\n"); @@ -3749,7 +3752,7 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer) } break; - case 2: //admin menu + case MENU_ADMIN: //admin menu WriteString2(&m, "\n\nCluster Admin\n\n"); @@ -3867,7 +3870,12 @@ void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer) if (viewer->server) { if (viewer->server->controller == viewer) - viewer->server->drop = true; + { + if (viewer->server->disconnectwhennooneiswatching) + viewer->server->drop = true; + else + viewer->server->controller = NULL; + } viewer->server->numviewers--; } @@ -3883,6 +3891,78 @@ void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer) cluster->numviewers--; } +void SendViewerPackets(cluster_t *cluster, viewer_t *v) +{ + char buffer[MAX_MSGLEN*2]; + netmsg_t m; + int read; + sv_t *useserver; + + v->drop |= v->netchan.drop; + + if (v->timeout < cluster->curtime) + { + Sys_Printf(cluster, "Viewer %s timed out\n", v->name); + v->drop = true; + } + + if (v->netchan.isnqprotocol) + { + v->maysend = (v->nextpacket < cluster->curtime); + } + if (!Netchan_CanPacket(&v->netchan)) + return; + if (v->maysend) //don't send incompleate connection data. + { + v->nextpacket = cluster->curtime + 1000/NQ_PACKETS_PER_SECOND; + + useserver = v->server; + if (useserver && useserver->parsingconnectiondata) + useserver = NULL; + + v->maysend = false; + InitNetMsg(&m, buffer, MAX_MSGLEN); + m.cursize = 0; + if (v->thinksitsconnected) + { + if (v->netchan.isnqprotocol) + SendNQPlayerStates(cluster, useserver, v, &m); + else + SendPlayerStates(useserver, v, &m); + UpdateStats(useserver, v); + } + if (v->menunum) + Menu_Draw(cluster, v); + else if (v->server && v->server->parsingconnectiondata) + { + WriteByte(&m, svc_centerprint); + WriteString(&m, v->server->status); + } +//printf("in %i, out %i, ", v->netchan.incoming_sequence, v->netchan.outgoing_sequence); +if (v->netchan.incoming_sequence != v->netchan.outgoing_sequence) +printf("%s: in %i, out %i\n", v->name, v->netchan.incoming_sequence, v->netchan.outgoing_sequence); + Netchan_Transmit(cluster, &v->netchan, m.cursize, m.data); + + if (!v->netchan.message.cursize && v->backbuffered) + {//shift the backbuffers around + memcpy(v->netchan.message.data, v->backbuf[0].data, v->backbuf[0].cursize); + v->netchan.message.cursize = v->backbuf[0].cursize; + for (read = 0; read < v->backbuffered; read++) + { + if (read == v->backbuffered-1) + { + v->backbuf[read].cursize = 0; + } + else + { + memcpy(v->backbuf[read].data, v->backbuf[read+1].data, v->backbuf[read+1].cursize); + v->backbuf[read].cursize = v->backbuf[read+1].cursize; + } + } + v->backbuffered--; + } + } +} void QW_UpdateUDPStuff(cluster_t *cluster) { char buffer[MAX_MSGLEN*2]; @@ -3893,8 +3973,8 @@ void QW_UpdateUDPStuff(cluster_t *cluster) int qport; netmsg_t m; - sv_t *useserver; viewer_t *v, *f; + sv_t *useserver; if (*cluster->master && (cluster->curtime > cluster->mastersendtime || cluster->mastersendtime > cluster->curtime + 4*1000*60)) //urm... time wrapped? { @@ -3910,10 +3990,7 @@ void QW_UpdateUDPStuff(cluster_t *cluster) cluster->mastersendtime = cluster->curtime + 3*1000*60; //3 minuites. } - m.data = buffer; - m.cursize = 0; - m.maxsize = MAX_MSGLEN; - m.readpos = 0; + InitNetMsg(&m, buffer, MAX_MSGLEN); for (;;) { @@ -3926,10 +4003,7 @@ void QW_UpdateUDPStuff(cluster_t *cluster) continue; } - m.data = buffer; m.cursize = read; - m.maxsize = MAX_MSGLEN; - m.readpos = 0; if (*(int*)buffer == -1) { //connectionless message @@ -3979,6 +4053,9 @@ void QW_UpdateUDPStuff(cluster_t *cluster) { if (Net_CompareAddress(&v->netchan.remote_address, &from, v->netchan.qport, qport)) { + if (v->server && v->server->controller == v && v->maysend) + SendViewerPackets(cluster, v); //do this before we read the new sequences + if (Netchan_Process(&v->netchan, &m)) { useserver = v->server; @@ -3991,8 +4068,8 @@ void QW_UpdateUDPStuff(cluster_t *cluster) if (v->server && v->server->controller == v) { // v->maysend = true; - v->server->maysend = true; - // v->server->netchan.outgoing_sequence = v->netchan.incoming_sequence; + v->server->maysend = true; + v->server->netchan.outgoing_sequence = v->netchan.incoming_sequence + v->server->controllersquencebias; } else { @@ -4093,66 +4170,6 @@ void QW_UpdateUDPStuff(cluster_t *cluster) QW_FreeViewer(cluster, f); } - v->drop |= v->netchan.drop; - - if (v->timeout < cluster->curtime) - { - Sys_Printf(cluster, "Viewer %s timed out\n", v->name); - v->drop = true; - } - - if (v->netchan.isnqprotocol) - { - v->maysend = (v->nextpacket < cluster->curtime); - } - if (!Netchan_CanPacket(&v->netchan)) - continue; - if (v->maysend) //don't send incompleate connection data. - { - v->nextpacket = cluster->curtime + 1000/NQ_PACKETS_PER_SECOND; - - useserver = v->server; - if (useserver && useserver->parsingconnectiondata) - useserver = NULL; - - v->maysend = false; - m.cursize = 0; - if (v->thinksitsconnected) - { - if (v->netchan.isnqprotocol) - SendNQPlayerStates(cluster, useserver, v, &m); - else - SendPlayerStates(useserver, v, &m); - UpdateStats(useserver, v); - - if (v->menunum) - Menu_Draw(cluster, v); - } - if (!v->menunum && v->server && v->server->parsingconnectiondata) - { - WriteByte(&m, svc_centerprint); - WriteString(&m, v->server->status); - } - - Netchan_Transmit(cluster, &v->netchan, m.cursize, m.data); - - if (!v->netchan.message.cursize && v->backbuffered) - {//shift the backbuffers around - memcpy(v->netchan.message.data, v->backbuf[0].data, v->backbuf[0].cursize); - v->netchan.message.cursize = v->backbuf[0].cursize; - for (read = 0; read < v->backbuffered; read++) - { - if (read == v->backbuffered-1) - { - v->backbuf[read].cursize = 0; - } - else - { - memcpy(v->backbuf[read].data, v->backbuf[read+1].data, v->backbuf[read+1].cursize); - v->backbuf[read].cursize = v->backbuf[read+1].cursize; - } - } - } - } + SendViewerPackets(cluster, v); } } diff --git a/fteqtv/rcon.c b/fteqtv/rcon.c index 3bcaddf8f..affa693fd 100644 --- a/fteqtv/rcon.c +++ b/fteqtv/rcon.c @@ -362,7 +362,8 @@ char *Cmd_Master(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe strncpy(cluster->master, arg[1], sizeof(cluster->master)-1); cluster->mastersendtime = cluster->curtime; - NET_SendPacket (cluster, cluster->qwdsocket, 1, "k", addr); + if (cluster->qwdsocket != INVALID_SOCKET) + NET_SendPacket (cluster, cluster->qwdsocket, 1, "k", addr); return "Master server set.\n"; } @@ -535,6 +536,7 @@ char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe { catbuffer(buffer, sizeofbuffer, " udp port %i\n", cluster->qwlistenportnum); } + catbuffer(buffer, sizeofbuffer, " user connections are %sallowed\n", cluster->nouserconnects?"":"NOT "); catbuffer(buffer, sizeofbuffer, "\n"); @@ -568,10 +570,11 @@ char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe if (qtv->disconnectwhennooneiswatching) catbuffer(buffer, sizeofbuffer, "Stream is temporary\n"); - if (qtv->tcpsocket != INVALID_SOCKET) +/* if (qtv->tcpsocket != INVALID_SOCKET) { catbuffer(buffer, sizeofbuffer, "Listening for proxies (%i)\n", qtv->tcplistenportnum); } +*/ if (qtv->bsp) { diff --git a/fteqtv/source.c b/fteqtv/source.c index 06f352f61..1a93a268b 100644 --- a/fteqtv/source.c +++ b/fteqtv/source.c @@ -281,6 +281,12 @@ void Net_SendQTVConnectionRequest(sv_t *qtv, char *authmethod, char *challenge) str = "\n"; Net_QueueUpstream(qtv, strlen(str), str); *at = '@'; } + else + { + *at = '\0'; + str = "RECEIVE\n"; Net_QueueUpstream(qtv, strlen(str), str); + *at = '@'; + } if (!qtv->parsingqtvheader) { @@ -428,6 +434,52 @@ qboolean Net_ConnectToUDPServer(sv_t *qtv, char *ip) return true; } +qboolean DemoFilenameIsOkay(char *fname) +{ + int len; + if (strchr(fname, '/')) + return false; //unix path seperator + if (strchr(fname, '\\')) + return false; //windows path seperator + if (strchr(fname, ':')) + return false; //mac path seperator + + //now make certain that the last four characters are '.mvd' and not something like '.cfg' perhaps + len = strlen(fname); + if (len < 5) + return false; + if (strcmp(fname+len-4, ".mvd")) + return false; + + return true; + +/* + if (strchr(fname, '\\')) + { + char *s; + Con_Printf("Warning: \\ charactures in filename %s\n", fname); + while((s = strchr(fname, '\\'))) + *s = '/'; + } + + if (strstr(fname, "..")) + { + Con_Printf("Error: '..' charactures in filename %s\n", fname); + } + else if (fname[0] == '/') + { + Con_Printf("Error: absolute path in filename %s\n", fname); + } + else if (strstr(fname, ":")) //win32 drive seperator (or mac path seperator, but / works there and they're used to it) + { + Con_Printf("Error: absolute path in filename %s\n", fname); + } + else + return false; + return true; +*/ +} + qboolean Net_ConnectToServer(sv_t *qtv, char *ip) { char *at; @@ -442,7 +494,10 @@ qboolean Net_ConnectToServer(sv_t *qtv, char *ip) if (!strncmp(ip, "file:", 5) || !strncmp(ip, "demo:", 5)) { qtv->sourcesock = INVALID_SOCKET; - qtv->sourcefile = fopen(ip+5, "rb"); + if (DemoFilenameIsOkay(ip+5)) + qtv->sourcefile = fopen(ip+5, "rb"); + else + qtv->sourcefile = NULL; if (qtv->sourcefile) { fseek(qtv->sourcefile, 0, SEEK_END); @@ -461,7 +516,7 @@ qboolean Net_ConnectToServer(sv_t *qtv, char *ip) qtv->usequkeworldprotocols = true; status = Net_ConnectToUDPServer(qtv, ip); } - else if (!strncmp(ip, "tcp:", 4)) + else if (!strncmp(ip, "tcp:", 4) || at!=NULL) status = Net_ConnectToTCPServer(qtv, ip); else { @@ -837,8 +892,8 @@ void QTV_Shutdown(sv_t *qtv) qtv->downloadfile = NULL; unlink(qtv->downloadname); } - if (qtv->tcpsocket != INVALID_SOCKET) - closesocket(qtv->tcpsocket); +// if (qtv->tcpsocket != INVALID_SOCKET) +// closesocket(qtv->tcpsocket); BSP_Free(qtv->bsp); qtv->bsp = NULL; @@ -1107,8 +1162,10 @@ void QTV_ParseQWStream(sv_t *qtv) if (qtv->controller) { qtv->controller->maysend = true; - qtv->controller->netchan.outgoing_sequence = qtv->netchan.incoming_sequence; - qtv->controller->netchan.incoming_sequence = qtv->netchan.incoming_acknowledged; +if (qtv->controller->netchan.outgoing_sequence != qtv->controller->netchan.incoming_sequence) +printf("bug is here\n"); + qtv->controller->netchan.outgoing_sequence = qtv->controller->netchan.incoming_sequence; +// qtv->controller->netchan.incoming_sequence = qtv->netchan.incoming_acknowledged; } } } @@ -1283,15 +1340,15 @@ void QTV_Run(sv_t *qtv) if (qtv->controller && !qtv->controller->netchan.isnqprotocol) { - qtv->netchan.outgoing_sequence = qtv->controller->netchan.incoming_sequence; - qtv->netchan.incoming_sequence = qtv->controller->netchan.incoming_acknowledged; +// qtv->netchan.outgoing_sequence = qtv->controller->netchan.incoming_sequence; +// qtv->netchan.incoming_sequence = qtv->controller->netchan.incoming_acknowledged; if (qtv->maysend) { qtv->maysend = false; - qtv->curtime = qtv->packetratelimiter; + qtv->packetratelimiter = qtv->curtime; } else - qtv->curtime = qtv->packetratelimiter - 1; + qtv->packetratelimiter = qtv->curtime + 1; } else { @@ -1407,7 +1464,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. +// SV_FindProxies(qtv->tcpsocket, qtv->cluster, qtv); //look for any other proxies wanting to muscle in on the action. if (qtv->sourcefile || qtv->sourcesock != INVALID_SOCKET) { @@ -1716,12 +1773,12 @@ sv_t *QTV_NewServerConnection(cluster_t *cluster, char *server, char *password, memset(qtv, 0, sizeof(*qtv)); //set up a default config - qtv->tcplistenportnum = PROX_DEFAULTLISTENPORT; +// qtv->tcplistenportnum = PROX_DEFAULTLISTENPORT; strcpy(qtv->server, PROX_DEFAULTSERVER); memcpy(qtv->connectpassword, password, sizeof(qtv->connectpassword)-1); - qtv->tcpsocket = INVALID_SOCKET; +// qtv->tcpsocket = INVALID_SOCKET; qtv->sourcesock = INVALID_SOCKET; qtv->disconnectwhennooneiswatching = autoclose; qtv->parsingconnectiondata = true;