From 72d983a8b8ca4df1c7feebb5a5b338c62d956532 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 19 Sep 2006 01:48:12 +0000 Subject: [PATCH] Better support for NQ clients. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2394 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- fteqtv/forward.c | 22 +- fteqtv/parse.c | 101 +++++++-- fteqtv/qtv.h | 15 +- fteqtv/qtvprox.dsp | 537 ++++++++++++++++++++++++++++++--------------- fteqtv/qw.c | 290 ++++++++++++++++-------- fteqtv/source.c | 136 +++++++++++- 6 files changed, 780 insertions(+), 321 deletions(-) diff --git a/fteqtv/forward.c b/fteqtv/forward.c index cd1b36e35..e1ffddc73 100644 --- a/fteqtv/forward.c +++ b/fteqtv/forward.c @@ -161,6 +161,7 @@ void Net_ProxySend(cluster_t *cluster, oproxy_t *prox, char *buffer, int length) Net_TryFlushProxyBuffer(cluster, prox); //try flushing if (prox->buffersize-prox->bufferpos + length > MAX_PROXY_BUFFER) //damn, still too big. { //they're too slow. hopefully it was just momentary lag + printf("QTV client is too lagged\n"); prox->flushing = true; return; } @@ -311,8 +312,7 @@ void Net_SendConnectionMVD(sv_t *qtv, oproxy_t *prox) Prox_SendPlayerStats(qtv, prox); Net_TryFlushProxyBuffer(qtv->cluster, prox); - if (!qtv->cluster->lateforward) - Net_ProxySend(qtv->cluster, prox, qtv->buffer, qtv->buffersize); //send all the info we've not yet processed. + Net_ProxySend(qtv->cluster, prox, qtv->buffer, qtv->forwardpoint); //send all the info we've not yet processed. if (prox->flushing) @@ -570,6 +570,7 @@ void SV_GenerateQTVStub(cluster_t *cluster, oproxy_t *dest, int streamid) //truth does not imply that it should be freed/released, just unlinked. qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend) { + char tempbuf[512]; char *s; char *e; char *colon; @@ -691,6 +692,7 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend) { *e = '\0'; colon = strchr(s, ':'); + if (*s) if (!colon) { if (!strcmp(s, "SOURCELIST")) @@ -706,14 +708,9 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend) { for (qtv = cluster->servers; qtv; qtv = qtv->next) { - s = "ASOURCE: "; - Net_ProxySend(cluster, pend, s, strlen(s)); - s = qtv->hostname; - if (!s || !*s) - s = qtv->server; - Net_ProxySend(cluster, pend, s, strlen(s)); - s = "\n"; - Net_ProxySend(cluster, pend, s, strlen(s)); + sprintf(tempbuf, "ASOURCE: %i: %15s: %15s\n", qtv->streamid, qtv->server, qtv->hostname); + s = tempbuf; + Net_ProxySend(cluster, pend, s, strlen(s)); } qtv = NULL; } @@ -723,7 +720,6 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend) } else if (!strcmp(s, "DEMOLIST")) { //lists the demos available on this proxy - s = "QTVSV 1\n"; Net_ProxySend(cluster, pend, s, strlen(s)); s = "PERROR: DEMOLIST command not yet implemented\n"; @@ -732,6 +728,8 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend) Net_ProxySend(cluster, pend, s, strlen(s)); pend->flushing = true; } + else + printf("Unrecognised token in QTV connection request (%s)\n", s); } else { @@ -790,6 +788,8 @@ qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend) Net_ProxySend(cluster, pend, s, strlen(s)); pend->flushing = true; } + else + printf("Unrecognised token in QTV connection request (%s)\n", s); } s = e+1; } diff --git a/fteqtv/parse.c b/fteqtv/parse.c index c08050555..835317465 100644 --- a/fteqtv/parse.c +++ b/fteqtv/parse.c @@ -208,21 +208,23 @@ void Multicast(sv_t *tv, char *buffer, int length, int to, unsigned int playerma //check and send to them only if they're tracking this player(s). for (v = tv->cluster->viewers; v; v = v->next) { - if (v->server == tv) - if (v->trackplayer>=0) - if ((1<trackplayer)&playermask) - { - if (suitablefor&(v->netchan.isnqprotocol?NQ:QW)) - SendBufferToViewer(v, buffer, length, true); //FIXME: change the reliable depending on message type - } + if (v->thinksitsconnected||suitablefor&CONNECTING) + if (v->server == tv) + if (v->trackplayer>=0) + if ((1<trackplayer)&playermask) + { + if (suitablefor&(v->netchan.isnqprotocol?NQ:QW)) + SendBufferToViewer(v, buffer, length, true); //FIXME: change the reliable depending on message type + } } break; default: //send to all for (v = tv->cluster->viewers; v; v = v->next) { - if (v->server == tv) - if (suitablefor&(v->netchan.isnqprotocol?NQ:QW)) + if (v->thinksitsconnected||suitablefor&CONNECTING) + if (v->server == tv) + if (suitablefor&(v->netchan.isnqprotocol?NQ:QW)) SendBufferToViewer(v, buffer, length, true); //FIXME: change the reliable depending on message type } break; @@ -521,8 +523,8 @@ static void ParsePrint(sv_t *tv, netmsg_t *m, int to, unsigned int mask) } } - Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, to, mask, QW); - Multicast(tv, buffer, strlen(buffer), to, mask, NQ); + Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, to, mask, QW|CONNECTING); +// Multicast(tv, buffer, strlen(buffer), to, mask, NQ); } static void ParseCenterprint(sv_t *tv, netmsg_t *m, int to, unsigned int mask) { @@ -971,30 +973,69 @@ static void ParseSound(sv_t *tv, netmsg_t *m, int to, unsigned int mask) #define DEFAULT_SOUND_PACKET_VOLUME 255 #define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 int i; - unsigned short chan; + int channel; unsigned char vol; unsigned char atten; unsigned char sound_num; short org[3]; + int ent; - chan = ReadShort(m); - if (chan & SND_VOLUME) + unsigned char nqversion[64]; + int nqlen = 0; + + channel = (unsigned short)ReadShort(m); + + + if (channel & SND_VOLUME) vol = ReadByte (m); else vol = DEFAULT_SOUND_PACKET_VOLUME; - if (chan & SND_ATTENUATION) + if (channel & SND_ATTENUATION) atten = ReadByte (m) / 64.0; else atten = DEFAULT_SOUND_PACKET_ATTENUATION; sound_num = ReadByte (m); + ent = (channel>>3)&1023; + channel &= 7; + for (i=0 ; i<3 ; i++) org[i] = ReadShort (m); Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, to, mask, QW); + + nqversion[0] = svc_sound; + nqversion[1] = 0; + if (vol != DEFAULT_SOUND_PACKET_VOLUME) + nqversion[1] |= 1; + if (atten != DEFAULT_SOUND_PACKET_ATTENUATION) + nqversion[1] |= 2; + nqlen=2; + + if (nqversion[1] & 1) + nqversion[nqlen++] = vol; + if (nqversion[1] & 2) + nqversion[nqlen++] = atten*64; + + channel = (ent<<3) | channel; + + nqversion[nqlen++] = (channel&0x00ff)>>0; + nqversion[nqlen++] = (channel&0xff00)>>8; + nqversion[nqlen++] = sound_num; + + nqversion[nqlen++] = 0; + nqversion[nqlen++] = 0; + + nqversion[nqlen++] = 0; + nqversion[nqlen++] = 0; + + nqversion[nqlen++] = 0; + nqversion[nqlen++] = 0; + + Multicast(tv, nqversion, nqlen, to, mask, NQ); } static void ParseDamage(sv_t *tv, netmsg_t *m, int to, unsigned int mask) @@ -1027,6 +1068,10 @@ enum { static void ParseTempEntity(sv_t *tv, netmsg_t *m, int to, unsigned int mask) { int i; + int dest = QW; + char nqversion[64]; + int nqversionlength=0; + i = ReadByte (m); switch(i) { @@ -1034,27 +1079,35 @@ static void ParseTempEntity(sv_t *tv, netmsg_t *m, int to, unsigned int mask) ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_SUPERSPIKE: ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_GUNSHOT: ReadByte (m); - ReadShort (m); - ReadShort (m); - ReadShort (m); + + nqversion[0] = svc_temp_entity; + nqversion[1] = TE_GUNSHOT; + nqversion[2] = ReadByte (m);nqversion[3] = ReadByte (m); + nqversion[4] = ReadByte (m);nqversion[5] = ReadByte (m); + nqversion[6] = ReadByte (m);nqversion[7] = ReadByte (m); + nqversionlength = 8; break; case TE_EXPLOSION: ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_TAREXPLOSION: ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_LIGHTNING1: case TE_LIGHTNING2: @@ -1068,26 +1121,31 @@ static void ParseTempEntity(sv_t *tv, netmsg_t *m, int to, unsigned int mask) ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_WIZSPIKE: ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_KNIGHTSPIKE: ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_LAVASPLASH: ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_TELEPORT: ReadShort (m); ReadShort (m); ReadShort (m); + dest |= NQ; break; case TE_BLOOD: ReadByte (m); @@ -1105,7 +1163,10 @@ static void ParseTempEntity(sv_t *tv, netmsg_t *m, int to, unsigned int mask) return; } - Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, to, mask, QW); + Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, to, mask, dest); + + if (nqversionlength) + Multicast(tv, nqversion, nqversionlength, to, mask, NQ); } void ParseLightstyle(sv_t *tv, netmsg_t *m) @@ -1280,7 +1341,7 @@ void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask) nq[1] = tv->proxyplayerangles[0]; nq[2] = tv->proxyplayerangles[1]; nq[3] = tv->proxyplayerangles[2]; - Multicast(tv, nq, 4, to, mask, Q1); +// Multicast(tv, nq, 4, to, mask, Q1); } break; diff --git a/fteqtv/qtv.h b/fteqtv/qtv.h index 1d3f86140..e238d0726 100644 --- a/fteqtv/qtv.h +++ b/fteqtv/qtv.h @@ -147,7 +147,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_PROXY_INBUFFER 4096 #define MAX_PROXY_BUFFER (1<<14) //must be power-of-two -#define PREFERED_PROXY_BUFFER 8192 //the ammount of data we try to leave in our input buffer (must be large enough to contain any single mvd frame) +#define PREFERED_PROXY_BUFFER 4096 //the ammount of data we try to leave in our input buffer (must be large enough to contain any single mvd frame) #define MAX_ENTITY_LEAFS 32 #define ENTS_PER_FRAME 64 //max number of entities per frame (OUCH!). @@ -208,14 +208,21 @@ typedef unsigned char netadr_t[64]; #define NETFLAG_CTL 0x80000000 #define CCREQ_CONNECT 0x01 +#define CCREQ_SERVER_INFO 0x02 #define CCREP_ACCEPT 0x81 #define CCREP_REJECT 0x82 +#define CCREP_SERVER_INFO 0x83 #define NET_GAMENAME_NQ "QUAKE" #define NET_PROTOCOL_VERSION 3 +typedef struct soundcapt_s { + int (*update)(struct soundcapt_s *ghnd, int samplechunks, char *buffer); + void (*close)(struct soundcapt_s *ptr); +} soundcapt_t; + typedef struct { unsigned int readpos; unsigned int cursize; @@ -421,6 +428,7 @@ struct sv_s { unsigned char buffer[MAX_PROXY_BUFFER]; //this doesn't cycle. int buffersize; //it memmoves down + int forwardpoint; //the point in the stream that we're forwarded up to. qboolean parsingqtvheader; unsigned char upstreambuffer[2048]; @@ -520,6 +528,9 @@ struct sv_s { bsp_t *bsp; int numinlines; + //audio stuff + soundcapt_t *comentrycapture; + //options: char server[MAX_QPATH]; int streamid; @@ -675,6 +686,7 @@ unsigned int BigLong(unsigned int val); +#define dem_audio 0 #define dem_cmd 0 #define dem_read 1 @@ -732,6 +744,7 @@ unsigned int BigLong(unsigned int val); #define Q1 (NQ|QW) #define QW 1 #define NQ 2 +#define CONNECTING 4 diff --git a/fteqtv/qtvprox.dsp b/fteqtv/qtvprox.dsp index 7e013fba1..766dab003 100644 --- a/fteqtv/qtvprox.dsp +++ b/fteqtv/qtvprox.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=qtvprox - Win32 Debug +CFG=qtvprox - Win32 Viewer Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,12 +13,13 @@ CFG=qtvprox - Win32 Debug !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "qtvprox.mak" CFG="qtvprox - Win32 Debug" +!MESSAGE NMAKE /f "qtvprox.mak" CFG="qtvprox - Win32 Viewer Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "qtvprox - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "qtvprox - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "qtvprox - Win32 Viewer Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -76,15 +77,348 @@ LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "qtvprox___Win32_Viewer_Debug" +# PROP BASE Intermediate_Dir "qtvprox___Win32_Viewer_Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "qtvprox___Win32_Viewer_Debug" +# PROP Intermediate_Dir "qtvprox___Win32_Viewer_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"qtv.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "VIEWER" /FR /Yu"qtv.h" /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + !ENDIF # Begin Target # Name "qtvprox - Win32 Release" # Name "qtvprox - Win32 Debug" +# Name "qtvprox - Win32 Viewer Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "viewer" + +# PROP Default_Filter "" +# Begin Group "d3d" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\viewer\d3drend\d3d_backend.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\d3drend\d3d_image.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\d3drend\d3d_video.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=.\viewer\cvar.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\gl_backend.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\gl_bsp29.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\gl_image.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\gl_mdl.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\gl_testgrid.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\gl_vidsdl.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\matrix.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\model.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\viewer\renderer.cpp + +!IF "$(CFG)" == "qtvprox - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" + +# PROP Exclude_From_Build 1 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# PROP BASE Exclude_From_Build 1 +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# End Group +# Begin Group "sound" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\sc_dsound.c +# End Source File +# Begin Source File + +SOURCE=.\sp_dsound.c +# End Source File +# End Group # Begin Source File SOURCE=.\bsp.c @@ -115,6 +449,11 @@ SOURCE=.\netchan.c # ADD CPP /Yu"qtv.h" +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# ADD BASE CPP /Yu"qtv.h" +# ADD CPP /Yu"qtv.h" + !ENDIF # End Source File @@ -128,6 +467,11 @@ SOURCE=.\parse.c # ADD CPP /Yu"qtv.h" +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# ADD BASE CPP /Yu"qtv.h" +# ADD CPP /Yu"qtv.h" + !ENDIF # End Source File @@ -141,6 +485,11 @@ SOURCE=.\qw.c # ADD CPP /Yu"qtv.h" +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# ADD BASE CPP /Yu"qtv.h" +# ADD CPP /Yu"qtv.h" + !ENDIF # End Source File @@ -158,6 +507,11 @@ SOURCE=.\source.c # ADD CPP /Yc"qtv.h" +!ELSEIF "$(CFG)" == "qtvprox - Win32 Viewer Debug" + +# ADD BASE CPP /Yc"qtv.h" +# ADD CPP /Yc"qtv.h" + !ENDIF # End Source File @@ -174,184 +528,5 @@ SOURCE=.\qtv.h # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group -# Begin Group "viewer" - -# PROP Default_Filter "" -# Begin Group "d3d" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\viewer\d3drend\d3d_backend.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -# SUBTRACT CPP /YX - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\d3drend\d3d_image.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\d3drend\d3d_video.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# End Group -# Begin Source File - -SOURCE=.\viewer\cvar.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\gl_backend.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\gl_bsp29.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\gl_image.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\gl_mdl.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\gl_testgrid.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\gl_vidsdl.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\matrix.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\model.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\viewer\renderer.cpp - -!IF "$(CFG)" == "qtvprox - Win32 Release" - -!ELSEIF "$(CFG)" == "qtvprox - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# End Group # End Target # End Project diff --git a/fteqtv/qw.c b/fteqtv/qw.c index e0092f91e..d6b3d5ab9 100644 --- a/fteqtv/qw.c +++ b/fteqtv/qw.c @@ -266,13 +266,13 @@ void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount) WriteString(msg, "\"\n"); } } -void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount) +void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int playernum) { int i; WriteByte(msg, svc_serverdata); WriteLong(msg, PROTOCOL_VERSION_NQ); WriteByte(msg, 16); //MAX_CLIENTS - WriteByte(msg, 0); //game type + WriteByte(msg, 1); //game type if (!tv || tv->parsingconnectiondata ) @@ -300,7 +300,7 @@ void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount) WriteByte(msg, 0); WriteByte(msg, svc_nqsetview); - WriteShort(msg, 1); + WriteShort(msg, playernum); WriteByte(msg, svc_nqsignonnum); WriteByte(msg, 1); @@ -330,7 +330,7 @@ void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount) WriteByte(msg, tv->cdtrack); WriteByte(msg, svc_nqsetview); - WriteShort(msg, 1); + WriteShort(msg, tv->trackplayer); WriteByte(msg, svc_nqsignonnum); WriteByte(msg, 1); @@ -350,9 +350,9 @@ void SendServerData(sv_t *tv, viewer_t *viewer) if (tv && (tv->controller == viewer || !tv->controller)) viewer->thisplayer = tv->thisplayer; else - viewer->thisplayer = MAX_CLIENTS-1; + viewer->thisplayer = 15; if (viewer->netchan.isnqprotocol) - BuildNQServerData(tv, &msg, false, viewer->servercount); + BuildNQServerData(tv, &msg, false, viewer->thisplayer); else BuildServerData(tv, &msg, false, viewer->servercount); @@ -365,7 +365,9 @@ void SendServerData(sv_t *tv, viewer_t *viewer) void SendNQSpawnInfoToViewer(cluster_t *cluster, viewer_t *viewer, netmsg_t *msg) { + char buffer[64]; int i; + int colours; sv_t *tv = viewer->server; WriteByte(msg, svc_nqtime); WriteFloat(msg, cluster->curtime/1000.0f); @@ -376,13 +378,20 @@ void SendNQSpawnInfoToViewer(cluster_t *cluster, viewer_t *viewer, netmsg_t *msg { WriteByte (msg, svc_nqupdatename); WriteByte (msg, i); - WriteString (msg, "FIXME"); //fixme + Info_ValueForKey(tv->players[i].userinfo, "name", buffer, sizeof(buffer)); + WriteString (msg, buffer); //fixme + WriteByte (msg, svc_updatefrags); WriteByte (msg, i); WriteShort (msg, tv->players[i].frags); + + Info_ValueForKey(tv->players[i].userinfo, "bottomcolor", buffer, sizeof(buffer)); + colours = atoi(buffer); + Info_ValueForKey(tv->players[i].userinfo, "topcolor", buffer, sizeof(buffer)); + colours |= atoi(buffer)*16; WriteByte (msg, svc_nqupdatecolors); WriteByte (msg, i); - WriteByte (msg, 0); //fixme + WriteByte (msg, colours); } } else @@ -1257,7 +1266,20 @@ void SendNQClientData(sv_t *tv, viewer_t *v, netmsg_t *msg) return; if (v->trackplayer < 0) - pl = &tv->players[v->thisplayer]; + { + WriteByte (msg, svc_nqclientdata); + WriteShort (msg, SU_VIEWHEIGHT|SU_ITEMS); + WriteByte (msg, 22); + WriteLong (msg, 0); + WriteShort (msg, 1000); + WriteByte (msg, 0); + WriteByte (msg, 0); + WriteByte (msg, 0); + WriteByte (msg, 0); + WriteByte (msg, 0); + WriteByte (msg, 0); + return; + } else pl = &tv->players[v->trackplayer]; @@ -1383,9 +1405,14 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg WriteShort(msg, v->trackplayer+1); WriteByte(msg, svc_setangle); - WriteByte(msg, tv->players[v->trackplayer].current.angles[0]>>8); - WriteByte(msg, tv->players[v->trackplayer].current.angles[1]>>8); - WriteByte(msg, tv->players[v->trackplayer].current.angles[2]>>8); + WriteByte(msg, (int)InterpolateAngle(tv->players[v->trackplayer].old.angles[0], tv->players[v->trackplayer].current.angles[0], lerp)>>8); + WriteByte(msg, (int)InterpolateAngle(tv->players[v->trackplayer].old.angles[1], tv->players[v->trackplayer].current.angles[1], lerp)>>8); + WriteByte(msg, (int)InterpolateAngle(tv->players[v->trackplayer].old.angles[2], tv->players[v->trackplayer].current.angles[2], lerp)>>8); + } + else + { + WriteByte(msg, svc_nqsetview); + WriteShort(msg, v->thisplayer+1); } @@ -1393,6 +1420,50 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg { pl = &tv->players[e]; ent = &tv->entity[e+1]; + + if (e == v->thisplayer && v->trackplayer < 0) + { + bits = UNQ_ORIGIN1 | UNQ_ORIGIN2 | UNQ_ORIGIN3 | UNQ_COLORMAP; + + + if (e+1 >= 256) + bits |= UNQ_LONGENTITY; + + if (bits >= 256) + bits |= UNQ_MOREBITS; + WriteByte (msg,bits | UNQ_SIGNAL); + if (bits & UNQ_MOREBITS) + WriteByte (msg, bits>>8); + if (bits & UNQ_LONGENTITY) + WriteShort (msg,e+1); + else + WriteByte (msg,e+1); + + if (bits & UNQ_MODEL) + WriteByte (msg, 0); + if (bits & UNQ_FRAME) + WriteByte (msg, 0); + if (bits & UNQ_COLORMAP) + WriteByte (msg, 0); + if (bits & UNQ_SKIN) + WriteByte (msg, 0); + if (bits & UNQ_EFFECTS) + WriteByte (msg, 0); + if (bits & UNQ_ORIGIN1) + WriteShort (msg, v->origin[0]); + if (bits & UNQ_ANGLE1) + WriteByte(msg, -(v->ucmds[2].angles[0]>>8)); + if (bits & UNQ_ORIGIN2) + WriteShort (msg, v->origin[1]); + if (bits & UNQ_ANGLE2) + WriteByte(msg, v->ucmds[2].angles[1]>>8); + if (bits & UNQ_ORIGIN3) + WriteShort (msg, v->origin[2]); + if (bits & UNQ_ANGLE3) + WriteByte(msg, v->ucmds[2].angles[2]>>8); + continue; + } + if (!pl->active) continue; @@ -1422,7 +1493,7 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg // if (pl->v.movetype == MOVETYPE_STEP) // bits |= UNQ_NOLERP; // don't mess up the step animation - if (ent->baseline.colormap != e+1) + if (ent->baseline.colormap != e+1 || ent->baseline.colormap > 15) bits |= UNQ_COLORMAP; if (ent->baseline.skinnum != pl->current.skinnum) @@ -1489,13 +1560,26 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg // send an update bits = 0; - - for (i=0 ; i<3 ; i++) + + if (tv->entity[i].updatetime == tv->oldpackettime) { - org[i] = (lerp)*ent->current.origin[i] + (1-lerp)*ent->old.origin[i]; - miss = org[i] - ent->baseline.origin[i]; - // if ( miss < -1 || miss > 1 ) - bits |= UNQ_ORIGIN1<current.origin[i] + (1-lerp)*ent->old.origin[i]; + miss = org[i] - ent->baseline.origin[i]; + // if ( miss < -1 || miss > 1 ) + bits |= UNQ_ORIGIN1<current.origin[i]; + miss = org[i] - ent->baseline.origin[i]; + // if ( miss < -1 || miss > 1 ) + bits |= UNQ_ORIGIN1<current.angles[0] != ent->baseline.angles[0] ) @@ -1510,7 +1594,7 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg // if (ent->v.movetype == MOVETYPE_STEP) // bits |= UNQ_NOLERP; // don't mess up the step animation - if (ent->baseline.colormap != ent->current.colormap) + if (ent->baseline.colormap != ent->current.colormap || ent->baseline.colormap > 15) bits |= UNQ_COLORMAP; if (ent->baseline.skinnum != ent->current.skinnum) @@ -1957,7 +2041,36 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean ".qw qwserver:port\n" ".qtv tcpserver:port\n" ".demo gamedir/demoname.mvd\n" - ".disconnect\n"); + ".disconnect\n" + ".admin\n" + ".bind\n" + ); + } + else if (!strncmp(message, ".reset", 6)) + { + QW_SetViewersServer(v, NULL); + QW_SetMenu(v, MENU_SERVERS); + } + else if (!strncmp(message, ".admin", 6)) + { + if (!*cluster->adminpassword) + { + if (Netchan_IsLocal(v->netchan.remote_address)) + { + Sys_Printf(cluster, "Local player %s logs in as admin\n", v->name); + QW_SetMenu(v, MENU_ADMIN); + v->isadmin = true; + } + else + QW_PrintfToViewer(v, "There is no admin password set\nYou may not log in.\n"); + } + else if (v->isadmin) + QW_SetMenu(v, MENU_ADMIN); + else + { + strcpy(v->expectcommand, "admin"); + QW_StuffcmdToViewer(v, "echo Please enter the rcon password\nmessagemode\n"); + } } else if (!strncmp(message, ".connect ", 9) || !strncmp(message, ".qw ", 4)) { @@ -2025,9 +2138,9 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean QW_SetViewersServer(v, NULL); QW_PrintfToViewer(v, "Connected\n", message); } - else if (!strncmp(message, ".admin", 11)) + else if (!strncmp(message, "admin", 11)) { - QW_StuffcmdToViewer(v, "cmd admin\n"); + QW_StuffcmdToViewer(v, "cmd say \".admin\"\n"); } else if (!strncmp(message, "proxy:menu up", 13)) { @@ -2067,19 +2180,30 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean else QW_SetMenu(v, MENU_SERVERS); } + else if (!strncmp(message, ".bind", 5)) + { + QW_StuffcmdToViewer(v, "bind uparrow +proxfwd\n"); + QW_StuffcmdToViewer(v, "bind downarrow +proxback\n"); + QW_StuffcmdToViewer(v, "bind rightarrow +proxright\n"); + QW_StuffcmdToViewer(v, "bind leftarrow +proxleft\n"); + } else if (!strncmp(message, ".menu bind", 10) || !strncmp(message, "proxy:menu bindstd", 18)) { - QW_StuffcmdToViewer(v, "bind uparrow proxy:menu up\n"); - QW_StuffcmdToViewer(v, "bind downarrow proxy:menu down\n"); - QW_StuffcmdToViewer(v, "bind rightarrow proxy:menu right\n"); - QW_StuffcmdToViewer(v, "bind leftarrow proxy:menu left\n"); + QW_StuffcmdToViewer(v, "bind uparrow \"proxy:menu up\"\n"); + QW_StuffcmdToViewer(v, "bind downarrow \"proxy:menu down\"\n"); + QW_StuffcmdToViewer(v, "bind rightarrow \"proxy:menu right\"\n"); + QW_StuffcmdToViewer(v, "bind leftarrow \"proxy:menu left\"\n"); - QW_StuffcmdToViewer(v, "bind enter proxy:menu select\n"); + QW_StuffcmdToViewer(v, "bind enter \"proxy:menu select\"\n"); - QW_StuffcmdToViewer(v, "bind home proxy:menu home\n"); - QW_StuffcmdToViewer(v, "bind end proxy:menu end\n"); - QW_StuffcmdToViewer(v, "bind pause proxy:menu\n"); - QW_StuffcmdToViewer(v, "bind backspace proxy:back up\n"); + QW_StuffcmdToViewer(v, "bind home \"proxy:menu home\"\n"); + QW_StuffcmdToViewer(v, "bind end \"proxy:menu end\"\n"); + QW_StuffcmdToViewer(v, "bind pause \"proxy:menu\"\n"); + QW_StuffcmdToViewer(v, "bind backspace \"proxy:menu back\"\n"); + } + else if (!strncmp(message, ".", 1)) + { + QW_PrintfToViewer(v, "Proxy command not recognised\n"); } else { @@ -2128,7 +2252,7 @@ viewer_t *QW_IsOn(cluster_t *cluster, char *name) { viewer_t *v; for (v = cluster->viewers; v; v = v->next) - if (!strcmp(v->name, name)) //this needs to allow dequakified names. + if (!stricmp(v->name, name)) //this needs to allow dequakified names. return v; return NULL; @@ -2195,15 +2319,15 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m) msg.cursize = 0; msg.overflowed = 0; - if (qtv) - { - SendCurrentBaselines(qtv, 64, &msg, msg.maxsize, 0); - SendCurrentLightmaps(qtv, 64, &msg, msg.maxsize, 0); + if (qtv) + { + SendCurrentBaselines(qtv, 64, &msg, msg.maxsize, 0); + SendCurrentLightmaps(qtv, 64, &msg, msg.maxsize, 0); - SendStaticSounds(qtv, 64, &msg, msg.maxsize, 0); + SendStaticSounds(qtv, 64, &msg, msg.maxsize, 0); - SendStaticEntities(qtv, 64, &msg, msg.maxsize, 0); - } + SendStaticEntities(qtv, 64, &msg, msg.maxsize, 0); + } WriteByte (&msg, svc_nqsignonnum); WriteByte (&msg, 2); SendBufferToViewer(v, msg.data, msg.cursize, true); @@ -2268,12 +2392,22 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m) v->ucmds[2].upmove = ReadShort(m); //one button - v->ucmds[2].buttons = ReadByte(m); + v->ucmds[1].buttons = v->ucmds[2].buttons; + v->ucmds[2].buttons = ReadByte(m); //one impulse v->ucmds[2].impulse = ReadByte(m); - v->ucmds[2].msec = 1000/NQ_PACKETS_PER_SECOND; + v->ucmds[2].msec = 5000/NQ_PACKETS_PER_SECOND; PMove(v, &v->ucmds[2]); + + if ((v->ucmds[1].buttons&1) != (v->ucmds[2].buttons&1) && (v->ucmds[2].buttons&1)) + { + v->trackplayer++; + } + if ((v->ucmds[1].buttons&2) != (v->ucmds[2].buttons&2) && (v->ucmds[2].buttons&2)) + { + v->trackplayer--; + } break; default: Sys_Printf(cluster, "Bad message type %i\n", mtype); @@ -2462,7 +2596,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m) if ((other = QW_IsOn(cluster, buf+5))) { if (!other->server) - QW_PrintfToViewer(v, "%s is on the proxy, but not yet watching a game\n"); + QW_PrintfToViewer(v, "%s is on the proxy, but not yet watching a game\n", other->name); else QW_PrintfToViewer(v, "%s is watching %s\n", buf+5, other->server->server); } @@ -2490,32 +2624,6 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m) { QW_SetMenu(v, MENU_SERVERS); } - else if (!strncmp(buf, "reset", 5)) - { - QW_SetViewersServer(v, NULL); - QW_SetMenu(v, MENU_SERVERS); - } - else if (!strncmp(buf, "admin", 5)) - { - if (!*cluster->adminpassword) - { - if (Netchan_IsLocal(v->netchan.remote_address)) - { - Sys_Printf(cluster, "Local player %s logs in as admin\n", v->name); - QW_SetMenu(v, MENU_ADMIN); - v->isadmin = true; - } - else - QW_PrintfToViewer(v, "There is no admin password set\nYou may not log in.\n"); - } - else if (v->isadmin) - QW_SetMenu(v, MENU_ADMIN); - else - { - strcpy(v->expectcommand, "admin"); - QW_StuffcmdToViewer(v, "echo Please enter the rcon password\nmessagemode\n"); - } - } else if (!strncmp(buf, "setinfo", 5)) { @@ -2602,34 +2710,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m) ReadDeltaUsercmd(m, &nullcmd, &v->ucmds[0]); ReadDeltaUsercmd(m, &v->ucmds[0], &v->ucmds[1]); ReadDeltaUsercmd(m, &v->ucmds[1], &v->ucmds[2]); -/* - if (v->server && v->server->controller) - { - v-> - } -*/ -/* if (v->menunum) - { - if (newcmd.buttons&1 && !(oldcmd.buttons&1)) - Menu_Enter(cluster, v, 0); - if (newcmd.buttons&2 && !(oldcmd.buttons&2)) - Menu_Enter(cluster, v, 1); - if (newcmd.sidemove && !oldcmd.sidemove) - Menu_Enter(cluster, v, newcmd.sidemove<0); - if (newcmd.forwardmove && !oldcmd.forwardmove) - { //they pressed the button... - if (newcmd.forwardmove < 0) - { - v->menuop+=1; - } - else - { - v->menuop-=1; - } - } - } -*/ PMove(v, &v->ucmds[2]); break; case clc_tmove: @@ -3145,6 +3226,23 @@ void QW_UpdateUDPStuff(cluster_t *cluster) { //looks hopeful switch(ReadByte(&m)) { + case CCREQ_SERVER_INFO: + ReadString(&m, tempbuffer, sizeof(tempbuffer)); + if (!strcmp(tempbuffer, NET_GAMENAME_NQ)) + { + m.cursize = 0; + WriteLong(&m, 0); + WriteByte(&m, CCREP_SERVER_INFO); + WriteString(&m, "??"); + WriteString(&m, cluster->hostname); + WriteString(&m, "Quake TV"); + WriteByte(&m, cluster->numviewers>255?255:cluster->numviewers); + WriteByte(&m, cluster->maxviewers>255?255:cluster->maxviewers); + WriteByte(&m, NET_PROTOCOL_VERSION); + *(int*)m.data = BigLong(NETFLAG_CTL | m.cursize); + NET_SendPacket(cluster, cluster->qwdsocket, m.cursize, m.data, from); + } + break; case CCREQ_CONNECT: ReadString(&m, tempbuffer, sizeof(tempbuffer)); if (!strcmp(tempbuffer, NET_GAMENAME_NQ)) diff --git a/fteqtv/source.c b/fteqtv/source.c index 297a32651..e98bf5aac 100644 --- a/fteqtv/source.c +++ b/fteqtv/source.c @@ -477,6 +477,49 @@ qboolean Net_WriteUpStream(sv_t *qtv) return true; } +int SV_ConsistantMVDData(unsigned char *buffer, int remaining) +{ + int lengthofs; + int length; + int available = 0; + while(1) + { + if (remaining < 2) + return available; + + //buffer[0] is time + + switch (buffer[1]&dem_mask) + { + case dem_set: + length = 10; + goto gottotallength; + case dem_multiple: + lengthofs = 6; + break; + default: + lengthofs = 2; + break; + } + + if (lengthofs+4 > remaining) + return available; + + length = (buffer[lengthofs]<<0) + (buffer[lengthofs+1]<<8) + (buffer[lengthofs+2]<<16) + (buffer[lengthofs+3]<<24); + + length += lengthofs+4; + if (length > 1400) + printf("Corrupt mvd\n"); +gottotallength: + if (remaining < length) + return available; + + remaining -= length; + available += length; + buffer += length; + } +} + qboolean Net_ReadStream(sv_t *qtv) { int maxreadable; @@ -515,8 +558,16 @@ qboolean Net_ReadStream(sv_t *qtv) if (read > 0) { qtv->buffersize += read; - if (!qtv->cluster->lateforward && !qtv->parsingqtvheader) - SV_ForwardStream(qtv, buffer, read); + if (!qtv->cluster->lateforward && !qtv->parsingqtvheader) //qtv header being the auth part of the connection rather than the stream + { + int forwardable; + forwardable = SV_ConsistantMVDData(qtv->buffer+qtv->forwardpoint, qtv->buffersize - qtv->forwardpoint); + if (forwardable > 0) + { + SV_ForwardStream(qtv, qtv->buffer+qtv->forwardpoint, forwardable); + qtv->forwardpoint += forwardable; + } + } } else { @@ -1009,6 +1060,50 @@ void QTV_ParseQWStream(sv_t *qtv) } } +void QTV_CollectCommentry(sv_t *qtv) +{ + int samps; + unsigned char buffer[8192+6]; + unsigned char *uchar; + signed char *schar; + int bytesleft; + if (!qtv->comentrycapture) + { + if (0) + qtv->comentrycapture = SND_InitCapture(11025, 8); + return; + } + + while(1) + { + buffer[0] = 0; + buffer[1] = dem_audio; + buffer[2] = 255; + buffer[3] = 255; + buffer[4] = 8; + buffer[5] = 11*5; + + samps=qtv->comentrycapture->update(qtv->comentrycapture, 2048, buffer+6); + + bytesleft = samps; + schar = buffer+6; + uchar = buffer+6; + while(bytesleft-->0) + { + *schar++ = *uchar++ - 128; + } + + buffer[2] = samps&255; + buffer[3] = samps>>8; + + if (samps) + SV_ForwardStream(qtv, buffer, 6 + samps); + + if (samps < 64) + break; + } +} + void QTV_Run(sv_t *qtv) { int lengthofs; @@ -1322,10 +1417,11 @@ void QTV_Run(sv_t *qtv) if (!qtv->usequkeworldprotocols) Sys_Printf(qtv->cluster, "Connection established, buffering for %i seconds\n", BUFFERTIME); - if (!qtv->cluster->lateforward) - SV_ForwardStream(qtv, qtv->buffer, qtv->buffersize); + SV_ForwardStream(qtv, qtv->buffer, qtv->forwardpoint); } + QTV_CollectCommentry(qtv); + while (qtv->curtime >= qtv->parsetime) { @@ -1345,7 +1441,8 @@ void QTV_Run(sv_t *qtv) switch (qtv->buffer[1]&dem_mask) { case dem_set: - if (qtv->buffersize < 10) + length = 10; + 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) @@ -1353,8 +1450,16 @@ void QTV_Run(sv_t *qtv) continue; } qtv->parsetime += buffer[0]; //well this was pointless - memmove(qtv->buffer, qtv->buffer+10, qtv->buffersize-(10)); - qtv->buffersize -= 10; + + if (qtv->forwardpoint < length) //we're about to destroy this data, so it had better be forwarded by now! + { + SV_ForwardStream(qtv, qtv->buffer, length); + qtv->forwardpoint += length; + } + + memmove(qtv->buffer, qtv->buffer+10, qtv->buffersize-(length)); + qtv->buffersize -= length; + qtv->forwardpoint -= length; continue; case dem_multiple: lengthofs = 6; @@ -1404,9 +1509,6 @@ void QTV_Run(sv_t *qtv) if (qtv->nextpackettime < qtv->curtime) { - if (qtv->cluster->lateforward) - SV_ForwardStream(qtv, qtv->buffer, lengthofs+4+length); - switch(qtv->buffer[1]&dem_mask) { case dem_multiple: @@ -1425,13 +1527,23 @@ void QTV_Run(sv_t *qtv) break; } + length = lengthofs+4+length; //make length be the length of the entire packet + qtv->oldpackettime = qtv->curtime; packettime = buffer[0]; if (qtv->buffersize) { //svc_disconnect can flush our input buffer (to prevent the EndOfDemo part from interfering) - memmove(qtv->buffer, qtv->buffer+lengthofs+4+length, qtv->buffersize-(lengthofs+length+4)); - qtv->buffersize -= lengthofs+4+length; + + if (qtv->forwardpoint < length) //we're about to destroy this data, so it had better be forwarded by now! + { + SV_ForwardStream(qtv, qtv->buffer, length); + qtv->forwardpoint += length; + } + + memmove(qtv->buffer, qtv->buffer+length, qtv->buffersize-(length)); + qtv->buffersize -= length; + qtv->forwardpoint -= length; } if (qtv->file)