Better support for NQ clients.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2394 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-09-19 01:48:12 +00:00
parent 31215e5b06
commit 72d983a8b8
6 changed files with 780 additions and 321 deletions

View File

@ -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;
}

View File

@ -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<<v->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<<v->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;

View File

@ -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

View File

@ -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

View File

@ -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<<i;
for (i=0 ; i<3 ; i++)
{
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<<i;
}
}
else
{
for (i=0 ; i<3 ; i++)
{
org[i] = ent->current.origin[i];
miss = org[i] - ent->baseline.origin[i];
// if ( miss < -1 || miss > 1 )
bits |= UNQ_ORIGIN1<<i;
}
}
if ( ent->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))

View File

@ -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)