mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
finally got around to updating qtv to add a few common protocol extensions.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5234 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
e44d8a85d8
commit
a4942abf52
13 changed files with 678 additions and 378 deletions
|
@ -401,7 +401,9 @@ int BSP_SphereLeafNums_r(bsp_t *bsp, int first, int maxleafs, unsigned short *li
|
||||||
|
|
||||||
rn = -1-rn;
|
rn = -1-rn;
|
||||||
|
|
||||||
if (maxleafs>numleafs)
|
if (rn <= 0)
|
||||||
|
; //leaf 0 has no pvs info, so don't add it.
|
||||||
|
else if (maxleafs>numleafs)
|
||||||
{
|
{
|
||||||
list[numleafs] = rn-1;
|
list[numleafs] = rn-1;
|
||||||
numleafs++;
|
numleafs++;
|
||||||
|
|
|
@ -13,46 +13,6 @@ Contains the control routines that handle both incoming and outgoing stuff
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// char *date = "Oct 24 1996";
|
|
||||||
static const char *date = __DATE__ ;
|
|
||||||
static const char *mon[12] =
|
|
||||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
|
||||||
static char mond[12] =
|
|
||||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
|
||||||
|
|
||||||
// returns days since Oct 24 1996
|
|
||||||
int build_number( void )
|
|
||||||
{
|
|
||||||
int m;
|
|
||||||
int d = 0;
|
|
||||||
int y;
|
|
||||||
int b;
|
|
||||||
|
|
||||||
for (m = 0; m < 11; m++)
|
|
||||||
{
|
|
||||||
if (strncmp( &date[0], mon[m], 3 ) == 0)
|
|
||||||
break;
|
|
||||||
d += mond[m];
|
|
||||||
}
|
|
||||||
|
|
||||||
d += atoi( &date[4] ) - 1;
|
|
||||||
|
|
||||||
y = atoi( &date[7] ) - 1900;
|
|
||||||
|
|
||||||
b = d + (int)((y - 1) * 365.25);
|
|
||||||
|
|
||||||
if (((y % 4) == 0) && m > 1)
|
|
||||||
{
|
|
||||||
b += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
b -= 35778; // Dec 16 1998
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char name[56];
|
char name[56];
|
||||||
int offset;
|
int offset;
|
||||||
|
@ -517,12 +477,11 @@ int main(int argc, char **argv)
|
||||||
cluster->qwlistenportnum = 0;
|
cluster->qwlistenportnum = 0;
|
||||||
cluster->allownqclients = true;
|
cluster->allownqclients = true;
|
||||||
strcpy(cluster->hostname, DEFAULT_HOSTNAME);
|
strcpy(cluster->hostname, DEFAULT_HOSTNAME);
|
||||||
cluster->buildnumber = build_number();
|
|
||||||
cluster->maxproxies = -1;
|
cluster->maxproxies = -1;
|
||||||
|
|
||||||
strcpy(cluster->demodir, "qw/demos/");
|
strcpy(cluster->demodir, "qw/demos/");
|
||||||
|
|
||||||
Sys_Printf(cluster, "QTV Build %i.\n", cluster->buildnumber);
|
Sys_Printf(cluster, "QTV "QTV_VERSION_STRING"\n");
|
||||||
|
|
||||||
DoCommandLine(cluster, argc, argv);
|
DoCommandLine(cluster, argc, argv);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#define MINPLUGVER "4239"
|
#define MINPLUGVER "4239"
|
||||||
//main reason to use connection close is because we're lazy and don't want to give sizes in advance (yes, we could use chunks..)
|
//main reason to use connection close is because we're lazy and don't want to give sizes in advance (yes, we could use chunks..)
|
||||||
|
|
||||||
|
size_t SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen);
|
||||||
|
|
||||||
void tobase64(unsigned char *out, int outlen, unsigned char *in, int inlen)
|
void tobase64(unsigned char *out, int outlen, unsigned char *in, int inlen)
|
||||||
{
|
{
|
||||||
|
@ -235,7 +236,7 @@ static void HTTPSV_SendHTMLFooter(cluster_t *cluster, oproxy_t *dest)
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
|
|
||||||
/*Proxy version*/
|
/*Proxy version*/
|
||||||
snprintf(buffer, sizeof(buffer), "<br/>Server Version: %i <a href=\""PROXYWEBSITE"\" target=\"_blank\">"PROXYWEBSITE"</a>", cluster->buildnumber);
|
snprintf(buffer, sizeof(buffer), "<br/>Server Version: "QTV_VERSION_STRING" <a href=\""PROXYWEBSITE"\" target=\"_blank\">"PROXYWEBSITE"</a>");
|
||||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1193,7 +1194,7 @@ void HTTPSV_GetMethod(cluster_t *cluster, oproxy_t *pend)
|
||||||
unsigned char sha1digest[20];
|
unsigned char sha1digest[20];
|
||||||
char padkey[512];
|
char padkey[512];
|
||||||
snprintf(padkey, sizeof(padkey), "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key);
|
snprintf(padkey, sizeof(padkey), "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key);
|
||||||
tobase64(acceptkey, sizeof(acceptkey), sha1digest, SHA1(sha1digest, sizeof(sha1digest), padkey));
|
tobase64(acceptkey, sizeof(acceptkey), sha1digest, SHA1(sha1digest, sizeof(sha1digest), padkey, strlen(padkey)));
|
||||||
|
|
||||||
snprintf(padkey, sizeof(padkey),
|
snprintf(padkey, sizeof(padkey),
|
||||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||||
|
|
|
@ -12,6 +12,8 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
|
||||||
switch(viewer->menunum)
|
switch(viewer->menunum)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
if (buttonnum < 0)
|
||||||
|
QW_SetMenu(viewer, MENU_MAIN); //no other sort of back button...
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_MAIN:
|
case MENU_MAIN:
|
||||||
|
@ -73,8 +75,25 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_CLIENTS:
|
case MENU_CLIENTS:
|
||||||
|
if (buttonnum >= 0)
|
||||||
{
|
{
|
||||||
|
viewer_t *v = cluster->viewers;
|
||||||
|
for (i = 0; i < viewer->menuop && v; i++)
|
||||||
|
v = v->next;
|
||||||
|
if (!v)
|
||||||
|
break;
|
||||||
|
if (v == viewer)
|
||||||
|
{
|
||||||
|
if (viewer->commentator)
|
||||||
|
QW_SetCommentator(cluster, viewer, NULL);
|
||||||
|
else
|
||||||
|
QW_PrintfToViewer(viewer, "Please stop touching yourself\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
QW_SetCommentator(cluster, viewer, v);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
QW_SetMenu(viewer, MENU_MAIN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_DEMOS:
|
case MENU_DEMOS:
|
||||||
|
@ -115,7 +134,9 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
|
||||||
}
|
}
|
||||||
//fallthrough
|
//fallthrough
|
||||||
case MENU_SERVERS:
|
case MENU_SERVERS:
|
||||||
if (!cluster->servers)
|
if (buttonnum < 0)
|
||||||
|
QW_SetMenu(viewer, MENU_MAIN);
|
||||||
|
else if (!cluster->servers)
|
||||||
{
|
{
|
||||||
QW_StuffcmdToViewer(viewer, "echo Please enter a server ip\nmessagemode\n");
|
QW_StuffcmdToViewer(viewer, "echo Please enter a server ip\nmessagemode\n");
|
||||||
strcpy(viewer->expectcommand, "insecadddemo");
|
strcpy(viewer->expectcommand, "insecadddemo");
|
||||||
|
@ -252,8 +273,7 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
|
||||||
|
|
||||||
WriteByte(&m, svc_centerprint);
|
WriteByte(&m, svc_centerprint);
|
||||||
|
|
||||||
sprintf(str, "FTEQTV build %i\n", cluster->buildnumber);
|
WriteString2(&m, "/PFTEQTV "QTV_VERSION_STRING"\n");
|
||||||
WriteString2(&m, str);
|
|
||||||
WriteString2(&m, PROXYWEBSITE"\n");
|
WriteString2(&m, PROXYWEBSITE"\n");
|
||||||
WriteString2(&m, "-------------\n");
|
WriteString2(&m, "-------------\n");
|
||||||
|
|
||||||
|
@ -302,6 +322,11 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
|
||||||
int c;
|
int c;
|
||||||
v = cluster->viewers;
|
v = cluster->viewers;
|
||||||
|
|
||||||
|
if (viewer->menuop < 0)
|
||||||
|
viewer->menuop = 0;
|
||||||
|
if (viewer->menuop > cluster->numviewers - 1)
|
||||||
|
viewer->menuop = cluster->numviewers - 1;
|
||||||
|
|
||||||
WriteString2(&m, "\nActive Clients\n\n");
|
WriteString2(&m, "\nActive Clients\n\n");
|
||||||
|
|
||||||
start = viewer->menuop & ~7;
|
start = viewer->menuop & ~7;
|
||||||
|
@ -358,16 +383,13 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
|
||||||
start = viewer->menuop & ~7;
|
start = viewer->menuop & ~7;
|
||||||
for (i = start; i < start+8; i++)
|
for (i = start; i < start+8; i++)
|
||||||
{
|
{
|
||||||
if (i == viewer->menuop)
|
char cleanname[128];
|
||||||
{
|
char *us;
|
||||||
WriteByte(&m, '[');
|
strlcpy(cleanname, cluster->availdemos[i].name, sizeof(cleanname));
|
||||||
WriteString2(&m, cluster->availdemos[i].name);
|
for (us = cleanname; *us; us++)
|
||||||
WriteByte(&m, ']');
|
if (*us == '_')
|
||||||
}
|
*us = ' ';
|
||||||
else
|
WriteStringSelection(&m, i == viewer->menuop, cleanname);
|
||||||
{
|
|
||||||
WriteString2(&m, cluster->availdemos[i].name);
|
|
||||||
}
|
|
||||||
WriteByte(&m, '\n');
|
WriteByte(&m, '\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
fteqtv/msg.c
12
fteqtv/msg.c
|
@ -91,16 +91,16 @@ void ReadString(netmsg_t *b, char *string, int maxlen)
|
||||||
while(ReadByte(b)) //finish reading the string, even if we will loose part of it
|
while(ReadByte(b)) //finish reading the string, even if we will loose part of it
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
float ReadCoord(netmsg_t *b, unsigned int pext)
|
float ReadCoord(netmsg_t *b, unsigned int pext1)
|
||||||
{
|
{
|
||||||
if (pext & PEXT_FLOATCOORDS)
|
if (pext1 & PEXT_FLOATCOORDS)
|
||||||
return ReadFloat(b);
|
return ReadFloat(b);
|
||||||
else
|
else
|
||||||
return ReadShort(b) / 8.0;
|
return (short)ReadShort(b) / 8.0;
|
||||||
}
|
}
|
||||||
float ReadAngle(netmsg_t *b, unsigned int pext)
|
float ReadAngle(netmsg_t *b, unsigned int pext1)
|
||||||
{
|
{
|
||||||
if (pext & PEXT_FLOATCOORDS)
|
if (pext1 & PEXT_FLOATCOORDS)
|
||||||
return (ReadShort(b) * 360.0) / 0x10000;
|
return (ReadShort(b) * 360.0) / 0x10000;
|
||||||
else
|
else
|
||||||
return (ReadByte(b) * 360.0) / 0x100;
|
return (ReadByte(b) * 360.0) / 0x100;
|
||||||
|
@ -139,7 +139,7 @@ void WriteCoord(netmsg_t *b, float c, unsigned int pext)
|
||||||
if (pext & PEXT_FLOATCOORDS)
|
if (pext & PEXT_FLOATCOORDS)
|
||||||
WriteFloat(b, c);
|
WriteFloat(b, c);
|
||||||
else
|
else
|
||||||
WriteShort(b, c*8);
|
WriteShort(b, (short)(c*8));
|
||||||
}
|
}
|
||||||
void WriteAngle(netmsg_t *b, float a, unsigned int pext)
|
void WriteAngle(netmsg_t *b, float a, unsigned int pext)
|
||||||
{
|
{
|
||||||
|
|
491
fteqtv/parse.c
491
fteqtv/parse.c
|
@ -24,6 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#define ParseError(m) (m)->readpos = (m)->cursize+1 //
|
#define ParseError(m) (m)->readpos = (m)->cursize+1 //
|
||||||
|
|
||||||
|
static const entity_state_t null_entity_state;
|
||||||
|
|
||||||
void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean reliable)
|
void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean reliable)
|
||||||
{
|
{
|
||||||
if (reliable)
|
if (reliable)
|
||||||
|
@ -46,6 +48,7 @@ void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean re
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
//create a new backbuffer
|
//create a new backbuffer
|
||||||
if (!v->backbuf[v->backbuffered].data)
|
if (!v->backbuf[v->backbuffered].data)
|
||||||
{
|
{
|
||||||
|
@ -121,8 +124,11 @@ static void ParseServerData(sv_t *tv, netmsg_t *m, int to, unsigned int playerma
|
||||||
//free the old map state
|
//free the old map state
|
||||||
QTV_CleanupMap(tv);
|
QTV_CleanupMap(tv);
|
||||||
|
|
||||||
tv->pext = 0;
|
tv->pext1 = 0;
|
||||||
|
tv->pext2 = 0;
|
||||||
|
|
||||||
|
//when it comes to QTV, the proxy 'blindly' forwards the data after parsing the header, so we need to support EVERYTHING the original server might.
|
||||||
|
//and if we don't, then we might have troubles.
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
protocol = ReadLong(m);
|
protocol = ReadLong(m);
|
||||||
|
@ -132,26 +138,74 @@ static void ParseServerData(sv_t *tv, netmsg_t *m, int to, unsigned int playerma
|
||||||
break;
|
break;
|
||||||
case PROTOCOL_VERSION_FTE:
|
case PROTOCOL_VERSION_FTE:
|
||||||
protocol = ReadLong(m);
|
protocol = ReadLong(m);
|
||||||
tv->pext = protocol;
|
tv->pext1 = protocol;
|
||||||
|
|
||||||
|
//HAVE
|
||||||
supported = PEXT_SETVIEW|PEXT_ACCURATETIMINGS; /*simple forwarding*/
|
supported = PEXT_SETVIEW|PEXT_ACCURATETIMINGS; /*simple forwarding*/
|
||||||
supported |= PEXT_256PACKETENTITIES|PEXT_VIEW2|PEXT_HLBSP|PEXT_Q2BSP|PEXT_Q3BSP; //features other than the protocol (stats, simple limits etc)
|
supported |= PEXT_256PACKETENTITIES|PEXT_VIEW2|PEXT_HLBSP|PEXT_Q2BSP|PEXT_Q3BSP; //features other than the protocol (stats, simple limits etc)
|
||||||
|
|
||||||
//supported |= PEXT_FLOATCOORDS|PEXT_TRANS|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2; //things we ought to support, but do not
|
supported |= PEXT_FLOATCOORDS|PEXT_SPAWNSTATIC2; //working
|
||||||
|
// supported |= PEXT_CHUNKEDDOWNLOADS; //shouldn't be relevant...
|
||||||
|
supported |= PEXT_TRANS|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_SOUNDDBL;
|
||||||
|
|
||||||
|
//replaced by replacementdeltas. we parse these, but we don't actually forward the data right now
|
||||||
|
supported |= PEXT_SCALE|PEXT_TRANS|PEXT_FATNESS|PEXT_COLOURMOD|PEXT_HEXEN2|PEXT_SETATTACHMENT|PEXT_DPFLAGS;
|
||||||
|
|
||||||
|
//stuff that we ought to handle, but don't currently
|
||||||
|
//PEXT_LIGHTSTYLECOL - woo, fancy rgb colours
|
||||||
|
//PEXT_CUSTOMTEMPEFFECTS - required for hexen2's effects. kinda messy.
|
||||||
|
//PEXT_TE_BULLET - implies nq tents too.
|
||||||
|
|
||||||
|
//HARD...
|
||||||
|
//PEXT_CSQC -- all bets are off if we receive a csqc ent update
|
||||||
|
|
||||||
|
//totally optional... so will probably never be added...
|
||||||
|
//PEXT_HULLSIZE - bigger players... maybe. like anyone can depend on this... not supported with mvd players so w/e
|
||||||
|
//PEXT_CHUNKEDDOWNLOADS - not sure there's much point
|
||||||
|
//PEXT_SPLITSCREEN - irrelevant for mvds. might be useful as a qw client, but who cares.
|
||||||
|
//PEXT_SHOWPIC - rare, lame, limited. just yuck.
|
||||||
|
|
||||||
if (protocol & PEXT_FLOATCOORDS)
|
|
||||||
{
|
|
||||||
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FTE (PEXT_FLOATCOORDS) not supported\n");
|
|
||||||
supported |= PEXT_FLOATCOORDS;
|
|
||||||
}
|
|
||||||
if (protocol & ~supported)
|
if (protocol & ~supported)
|
||||||
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FTE (%x) not supported\n", protocol & ~supported);
|
{
|
||||||
|
int i;
|
||||||
|
const char *names[] = {
|
||||||
|
"PEXT_SETVIEW", "PEXT_SCALE", "PEXT_LIGHTSTYLECOL", "PEXT_TRANS",
|
||||||
|
"PEXT_VIEW2", "0x00000020", "PEXT_ACCURATETIMINGS", "PEXT_SOUNDDBL",
|
||||||
|
"PEXT_FATNESS", "PEXT_HLBSP", "PEXT_TE_BULLET", "PEXT_HULLSIZE",
|
||||||
|
"PEXT_MODELDBL", "PEXT_ENTITYDBL", "PEXT_ENTITYDBL2", "PEXT_FLOATCOORDS",
|
||||||
|
"0x00010000", "PEXT_Q2BSP", "PEXT_Q3BSP", "PEXT_COLOURMOD",
|
||||||
|
"PEXT_SPLITSCREEN", "PEXT_HEXEN2", "PEXT_SPAWNSTATIC2", "PEXT_CUSTOMTEMPEFFECTS",
|
||||||
|
"PEXT_256PACKETENTITIES", "0x02000000", "PEXT_SHOWPIC", "PEXT_SETATTACHMENT",
|
||||||
|
"0x10000000", "PEXT_CHUNKEDDOWNLOADS","PEXT_CSQC", "PEXT_DPFLAGS",
|
||||||
|
};
|
||||||
|
for (i = 0; i < sizeof(names)/sizeof(names[0]); i++)
|
||||||
|
{
|
||||||
|
if (protocol & ~supported & (1u<<i))
|
||||||
|
{
|
||||||
|
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FTE (%s) not supported\n", names[i]);
|
||||||
|
supported |= (1u<<i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (protocol & ~supported)
|
||||||
|
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FTE (%x) not supported\n", protocol & ~supported);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
case PROTOCOL_VERSION_FTE2:
|
case PROTOCOL_VERSION_FTE2:
|
||||||
protocol = ReadLong(m);
|
protocol = ReadLong(m);
|
||||||
|
tv->pext2 = protocol;
|
||||||
supported = 0;
|
supported = 0;
|
||||||
// supported |= PEXT2_PRYDONCURSOR|PEXT2_VOICECHAT|PEXT2_SETANGLEDELTA|PEXT2_REPLACEMENTDELTAS|PEXT2_MAXPLAYERS;
|
// supported |= PEXT2_PRYDONCURSOR|PEXT2_VOICECHAT|PEXT2_SETANGLEDELTA|PEXT2_REPLACEMENTDELTAS|PEXT2_MAXPLAYERS;
|
||||||
|
|
||||||
|
//FIXME: handle the svc and clc if they arrive.
|
||||||
|
supported |= PEXT2_VOICECHAT;
|
||||||
|
|
||||||
|
//WANT
|
||||||
|
//PEXT2_SETANGLEDELTA
|
||||||
|
//PEXT2_REPLACEMENTDELTAS
|
||||||
|
//PEXT2_SETANGLEDELTA
|
||||||
|
//PEXT2_PREDINFO
|
||||||
|
//PEXT2_PRYDONCURSOR
|
||||||
|
|
||||||
if (protocol & ~supported)
|
if (protocol & ~supported)
|
||||||
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FTE2 (%x) not supported\n", protocol & ~supported);
|
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FTE2 (%x) not supported\n", protocol & ~supported);
|
||||||
continue;
|
continue;
|
||||||
|
@ -270,7 +324,7 @@ void QTV_UpdatedServerInfo(sv_t *tv)
|
||||||
fromproxy = false;
|
fromproxy = false;
|
||||||
|
|
||||||
//add on our extra infos
|
//add on our extra infos
|
||||||
Info_SetValueForStarKey(tv->map.serverinfo, "*qtv", VERSION, sizeof(tv->map.serverinfo));
|
Info_SetValueForStarKey(tv->map.serverinfo, "*qtv", QTV_VERSION_STRING, sizeof(tv->map.serverinfo));
|
||||||
Info_SetValueForStarKey(tv->map.serverinfo, "*z_ext", Z_EXT_STRING, sizeof(tv->map.serverinfo));
|
Info_SetValueForStarKey(tv->map.serverinfo, "*z_ext", Z_EXT_STRING, sizeof(tv->map.serverinfo));
|
||||||
|
|
||||||
Info_ValueForKey(tv->map.serverinfo, "hostname", tv->map.hostname, sizeof(tv->map.hostname));
|
Info_ValueForKey(tv->map.serverinfo, "hostname", tv->map.hostname, sizeof(tv->map.hostname));
|
||||||
|
@ -326,6 +380,11 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
if (tv->controller)
|
if (tv->controller)
|
||||||
QW_SetMenu(tv->controller, atoi(text+18)?MENU_FORWARDING:MENU_NONE);
|
QW_SetMenu(tv->controller, atoi(text+18)?MENU_FORWARDING:MENU_NONE);
|
||||||
}
|
}
|
||||||
|
// else if (!strncmp(text, "//set protocolname ", 19))
|
||||||
|
// else if (!strncmp(text, "//set recorddate ", 17)) //reports when the demo was originally recorded, without needing to depend upon metadata.
|
||||||
|
// else if (!strncmp(text, "//paknames ", 11))
|
||||||
|
// else if (!strncmp(text, "//paks ", 7))
|
||||||
|
// else if (!strncmp(text, "//vwep ", 7))
|
||||||
else if (strstr(text, "screenshot"))
|
else if (strstr(text, "screenshot"))
|
||||||
{
|
{
|
||||||
if (tv->controller)
|
if (tv->controller)
|
||||||
|
@ -363,8 +422,6 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
/*strip trailing quote*/
|
/*strip trailing quote*/
|
||||||
text[strlen(text)-1] = '\0';
|
text[strlen(text)-1] = '\0';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//copy over the server's serverinfo
|
//copy over the server's serverinfo
|
||||||
strlcpy(tv->map.serverinfo, text+16, sizeof(tv->map.serverinfo));
|
strlcpy(tv->map.serverinfo, text+16, sizeof(tv->map.serverinfo));
|
||||||
|
|
||||||
|
@ -407,6 +464,8 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
{
|
{
|
||||||
if (tv->controller)
|
if (tv->controller)
|
||||||
{ //if we're acting as a proxy, forward the realip packets, and ONLY to the controller
|
{ //if we're acting as a proxy, forward the realip packets, and ONLY to the controller
|
||||||
|
//quakeworld proxies are usually there for routing or protocol advantages, NOT privacy
|
||||||
|
//(client can always ignore it themselves, but a server might ban you, but at least they'll be less inclined to ban the proxy).
|
||||||
SendBufferToViewer(tv->controller, (char*)m->data+m->startpos, m->readpos - m->startpos, true);
|
SendBufferToViewer(tv->controller, (char*)m->data+m->startpos, m->readpos - m->startpos, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -557,11 +616,14 @@ static void ParseCenterprint(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int ParseList(sv_t *tv, netmsg_t *m, filename_t *list, int to, unsigned int mask)
|
static int ParseList(sv_t *tv, netmsg_t *m, filename_t *list, int to, unsigned int mask, qboolean big)
|
||||||
{
|
{
|
||||||
int first;
|
int first;
|
||||||
|
|
||||||
first = ReadByte(m)+1;
|
if (big)
|
||||||
|
first = ReadShort(m)+1;
|
||||||
|
else
|
||||||
|
first = ReadByte(m)+1;
|
||||||
for (; first < MAX_LIST; first++)
|
for (; first < MAX_LIST; first++)
|
||||||
{
|
{
|
||||||
ReadString(m, list[first].name, sizeof(list[first].name));
|
ReadString(m, list[first].name, sizeof(list[first].name));
|
||||||
|
@ -584,23 +646,10 @@ static void ParseEntityState(sv_t *tv, entity_state_t *es, netmsg_t *m) //for ba
|
||||||
es->skinnum = ReadByte(m);
|
es->skinnum = ReadByte(m);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
es->origin[i] = ReadCoord(m, tv->pext);
|
es->origin[i] = ReadCoord(m, tv->pext1);
|
||||||
es->angles[i] = ReadAngle(m, tv->pext);
|
es->angles[i] = ReadAngle(m, tv->pext1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void ParseBaseline(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
|
||||||
{
|
|
||||||
unsigned int entnum;
|
|
||||||
entnum = ReadShort(m);
|
|
||||||
if (entnum >= MAX_ENTITIES)
|
|
||||||
{
|
|
||||||
ParseError(m);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ParseEntityState(tv, &tv->map.entity[entnum].baseline, m);
|
|
||||||
|
|
||||||
ConnectionData(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, Q1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ParseStaticSound(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
static void ParseStaticSound(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
{
|
{
|
||||||
|
@ -610,9 +659,9 @@ static void ParseStaticSound(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
Sys_Printf(tv->cluster, "Too many static sounds\n");
|
Sys_Printf(tv->cluster, "Too many static sounds\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
tv->map.staticsound[tv->map.staticsound_count].origin[0] = ReadShort(m);
|
tv->map.staticsound[tv->map.staticsound_count].origin[0] = ReadCoord(m, tv->pext1);
|
||||||
tv->map.staticsound[tv->map.staticsound_count].origin[1] = ReadShort(m);
|
tv->map.staticsound[tv->map.staticsound_count].origin[1] = ReadCoord(m, tv->pext1);
|
||||||
tv->map.staticsound[tv->map.staticsound_count].origin[2] = ReadShort(m);
|
tv->map.staticsound[tv->map.staticsound_count].origin[2] = ReadCoord(m, tv->pext1);
|
||||||
tv->map.staticsound[tv->map.staticsound_count].soundindex = ReadByte(m);
|
tv->map.staticsound[tv->map.staticsound_count].soundindex = ReadByte(m);
|
||||||
tv->map.staticsound[tv->map.staticsound_count].volume = ReadByte(m);
|
tv->map.staticsound[tv->map.staticsound_count].volume = ReadByte(m);
|
||||||
tv->map.staticsound[tv->map.staticsound_count].attenuation = ReadByte(m);
|
tv->map.staticsound[tv->map.staticsound_count].attenuation = ReadByte(m);
|
||||||
|
@ -634,21 +683,6 @@ static void ParseIntermission(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
Multicast(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, QW);
|
Multicast(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, QW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseSpawnStatic(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
|
||||||
{
|
|
||||||
if (tv->map.spawnstatic_count == MAX_STATICENTITIES)
|
|
||||||
{
|
|
||||||
tv->map.spawnstatic_count--; // don't be fatal.
|
|
||||||
Sys_Printf(tv->cluster, "Too many static entities\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseEntityState(tv, &tv->map.spawnstatic[tv->map.spawnstatic_count], m);
|
|
||||||
|
|
||||||
tv->map.spawnstatic_count++;
|
|
||||||
|
|
||||||
ConnectionData(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, Q1);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern const usercmd_t nullcmd;
|
extern const usercmd_t nullcmd;
|
||||||
static void ParsePlayerInfo(sv_t *tv, netmsg_t *m, qboolean clearoldplayers)
|
static void ParsePlayerInfo(sv_t *tv, netmsg_t *m, qboolean clearoldplayers)
|
||||||
{
|
{
|
||||||
|
@ -679,9 +713,9 @@ static void ParsePlayerInfo(sv_t *tv, netmsg_t *m, qboolean clearoldplayers)
|
||||||
{
|
{
|
||||||
flags = (unsigned short)ReadShort (m);
|
flags = (unsigned short)ReadShort (m);
|
||||||
|
|
||||||
tv->map.players[num].current.origin[0] = ReadCoord (m, tv->pext);
|
tv->map.players[num].current.origin[0] = ReadCoord (m, tv->pext1);
|
||||||
tv->map.players[num].current.origin[1] = ReadCoord (m, tv->pext);
|
tv->map.players[num].current.origin[1] = ReadCoord (m, tv->pext1);
|
||||||
tv->map.players[num].current.origin[2] = ReadCoord (m, tv->pext);
|
tv->map.players[num].current.origin[2] = ReadCoord (m, tv->pext1);
|
||||||
|
|
||||||
tv->map.players[num].current.frame = ReadByte(m);
|
tv->map.players[num].current.frame = ReadByte(m);
|
||||||
|
|
||||||
|
@ -705,9 +739,9 @@ static void ParsePlayerInfo(sv_t *tv, netmsg_t *m, qboolean clearoldplayers)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tv->map.players[num].current.angles[0] = tv->proxyplayerangles[0]/360*65535;
|
tv->map.players[num].current.angles[0] = tv->proxyplayerangles[0];
|
||||||
tv->map.players[num].current.angles[1] = tv->proxyplayerangles[1]/360*65535;
|
tv->map.players[num].current.angles[1] = tv->proxyplayerangles[1];
|
||||||
tv->map.players[num].current.angles[2] = tv->proxyplayerangles[2]/360*65535;
|
tv->map.players[num].current.angles[2] = tv->proxyplayerangles[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,14 +788,14 @@ static void ParsePlayerInfo(sv_t *tv, netmsg_t *m, qboolean clearoldplayers)
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
if (flags & (DF_ORIGIN << i))
|
if (flags & (DF_ORIGIN << i))
|
||||||
tv->map.players[num].current.origin[i] = ReadCoord (m, tv->pext);
|
tv->map.players[num].current.origin[i] = ReadCoord (m, tv->pext1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
if (flags & (DF_ANGLES << i))
|
if (flags & (DF_ANGLES << i))
|
||||||
{
|
{
|
||||||
tv->map.players[num].current.angles[i] = ReadShort(m);
|
tv->map.players[num].current.angles[i] = (ReadShort(m)/(float)0x10000)*360;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,28 +839,35 @@ static int readentitynum(netmsg_t *m, unsigned int *retflags)
|
||||||
{
|
{
|
||||||
flags |= ReadByte(m);
|
flags |= ReadByte(m);
|
||||||
|
|
||||||
/* if (flags & U_EVENMORE)
|
if (flags & UX_EVENMORE)
|
||||||
flags |= ReadByte(m)<<16;
|
flags |= ReadByte(m)<<16;
|
||||||
if (flags & U_YETMORE)
|
if (flags & UX_YETMORE)
|
||||||
flags |= ReadByte(m)<<24;
|
flags |= ReadByte(m)<<24;
|
||||||
*/ }
|
}
|
||||||
|
|
||||||
/* if (flags & U_ENTITYDBL)
|
if (flags & UX_ENTITYDBL)
|
||||||
entnum += 512;
|
entnum += 512;
|
||||||
if (flags & U_ENTITYDBL2)
|
if (flags & UX_ENTITYDBL2)
|
||||||
entnum += 1024;
|
entnum += 1024;
|
||||||
*/
|
|
||||||
*retflags = flags;
|
*retflags = flags;
|
||||||
|
|
||||||
return entnum;
|
return entnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ParseEntityDelta(sv_t *tv, netmsg_t *m, entity_state_t *old, entity_state_t *new, unsigned int flags, entity_t *ent, qboolean forcerelink)
|
static void ParseEntityDelta(sv_t *tv, netmsg_t *m, const entity_state_t *old, entity_state_t *new, unsigned int flags, entity_t *ent, qboolean forcerelink)
|
||||||
{
|
{
|
||||||
memcpy(new, old, sizeof(entity_state_t));
|
memcpy(new, old, sizeof(entity_state_t));
|
||||||
|
|
||||||
if (flags & U_MODEL)
|
if (flags & U_MODEL)
|
||||||
new->modelindex = ReadByte(m);
|
{
|
||||||
|
if (flags & UX_MODELDBL)
|
||||||
|
new->modelindex = ReadByte(m)|0x100; //doubled limit...
|
||||||
|
else
|
||||||
|
new->modelindex = ReadByte(m);
|
||||||
|
}
|
||||||
|
else if (flags & UX_MODELDBL)
|
||||||
|
new->modelindex = ReadShort(m); //more sane path...
|
||||||
if (flags & U_FRAME)
|
if (flags & U_FRAME)
|
||||||
new->frame = ReadByte(m);
|
new->frame = ReadByte(m);
|
||||||
if (flags & U_COLORMAP)
|
if (flags & U_COLORMAP)
|
||||||
|
@ -834,29 +875,67 @@ static void ParseEntityDelta(sv_t *tv, netmsg_t *m, entity_state_t *old, entity_
|
||||||
if (flags & U_SKIN)
|
if (flags & U_SKIN)
|
||||||
new->skinnum = ReadByte(m);
|
new->skinnum = ReadByte(m);
|
||||||
if (flags & U_EFFECTS)
|
if (flags & U_EFFECTS)
|
||||||
new->effects = ReadByte(m);
|
new->effects = (new->effects&0xff00)|ReadByte(m);
|
||||||
|
|
||||||
if (flags & U_ORIGIN1)
|
if (flags & U_ORIGIN1)
|
||||||
new->origin[0] = ReadCoord(m, tv->pext);
|
new->origin[0] = ReadCoord(m, tv->pext1);
|
||||||
if (flags & U_ANGLE1)
|
if (flags & U_ANGLE1)
|
||||||
new->angles[0] = ReadAngle(m, tv->pext);
|
new->angles[0] = ReadAngle(m, tv->pext1);
|
||||||
if (flags & U_ORIGIN2)
|
if (flags & U_ORIGIN2)
|
||||||
new->origin[1] = ReadCoord(m, tv->pext);
|
new->origin[1] = ReadCoord(m, tv->pext1);
|
||||||
if (flags & U_ANGLE2)
|
if (flags & U_ANGLE2)
|
||||||
new->angles[1] = ReadAngle(m, tv->pext);
|
new->angles[1] = ReadAngle(m, tv->pext1);
|
||||||
if (flags & U_ORIGIN3)
|
if (flags & U_ORIGIN3)
|
||||||
new->origin[2] = ReadCoord(m, tv->pext);
|
new->origin[2] = ReadCoord(m, tv->pext1);
|
||||||
if (flags & U_ANGLE3)
|
if (flags & U_ANGLE3)
|
||||||
new->angles[2] = ReadAngle(m, tv->pext);
|
new->angles[2] = ReadAngle(m, tv->pext1);
|
||||||
|
|
||||||
|
if (flags & UX_SCALE)
|
||||||
|
new->scale = ReadByte(m);
|
||||||
|
if (flags & UX_ALPHA)
|
||||||
|
new->alpha = ReadByte(m);
|
||||||
|
if (flags & UX_FATNESS)
|
||||||
|
/*new->fatness =*/ (signed char)ReadByte(m);
|
||||||
|
if (flags & UX_DRAWFLAGS)
|
||||||
|
/*new->hexen2flags =*/ ReadByte(m);
|
||||||
|
if (flags & UX_ABSLIGHT)
|
||||||
|
/*new->abslight =*/ ReadByte(m);
|
||||||
|
if (flags & UX_COLOURMOD)
|
||||||
|
{
|
||||||
|
/*new->colormod[0] =*/ ReadByte(m);
|
||||||
|
/*new->colormod[1] =*/ ReadByte(m);
|
||||||
|
/*new->colormod[2] =*/ ReadByte(m);
|
||||||
|
}
|
||||||
|
if (flags & UX_DPFLAGS)
|
||||||
|
{ // these are bits for the 'flags' field of the entity_state_t
|
||||||
|
/*new->dpflags =*/ ReadByte(m);
|
||||||
|
}
|
||||||
|
if (flags & UX_TAGINFO)
|
||||||
|
{
|
||||||
|
/*new->tagentity =*/ ReadShort(m);
|
||||||
|
/*new->tagindex =*/ ReadShort(m);
|
||||||
|
}
|
||||||
|
if (flags & UX_LIGHT)
|
||||||
|
{
|
||||||
|
/*new->light[0] =*/ ReadShort(m);
|
||||||
|
/*new->light[1] =*/ ReadShort(m);
|
||||||
|
/*new->light[2] =*/ ReadShort(m);
|
||||||
|
/*new->light[3] =*/ ReadShort(m);
|
||||||
|
/*new->lightstyle =*/ ReadByte(m);
|
||||||
|
/*new->lightpflags =*/ ReadByte(m);
|
||||||
|
}
|
||||||
|
if (flags & UX_EFFECTS16)
|
||||||
|
new->effects = (new->effects&0x00ff)|(ReadByte(m)<<8);
|
||||||
|
|
||||||
|
|
||||||
if (forcerelink || (flags & (U_ORIGIN1|U_ORIGIN2|U_ORIGIN3|U_MODEL)))
|
if (forcerelink || (flags & (U_ORIGIN1|U_ORIGIN2|U_ORIGIN3|U_MODEL)))
|
||||||
{
|
{
|
||||||
ent->leafcount =
|
if (ent)
|
||||||
BSP_SphereLeafNums(tv->map.bsp, MAX_ENTITY_LEAFS, ent->leafs,
|
ent->leafcount =
|
||||||
new->origin[0],
|
BSP_SphereLeafNums(tv->map.bsp, MAX_ENTITY_LEAFS, ent->leafs,
|
||||||
new->origin[1],
|
new->origin[0],
|
||||||
new->origin[2], 32);
|
new->origin[1],
|
||||||
|
new->origin[2], 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1105,6 +1184,59 @@ return;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParseSpawnStatic(sv_t *tv, netmsg_t *m, int to, unsigned int mask, qboolean delta)
|
||||||
|
{
|
||||||
|
if (tv->map.spawnstatic_count == MAX_STATICENTITIES)
|
||||||
|
{
|
||||||
|
tv->map.spawnstatic_count--; // don't be fatal.
|
||||||
|
Sys_Printf(tv->cluster, "Too many static entities\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta)
|
||||||
|
{
|
||||||
|
unsigned int flags;
|
||||||
|
readentitynum(m, &flags);
|
||||||
|
ParseEntityDelta(tv, m, &null_entity_state, &tv->map.spawnstatic[tv->map.spawnstatic_count], flags, NULL, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ParseEntityState(tv, &tv->map.spawnstatic[tv->map.spawnstatic_count], m);
|
||||||
|
|
||||||
|
tv->map.spawnstatic_count++;
|
||||||
|
|
||||||
|
ConnectionData(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, Q1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseBaseline(sv_t *tv, netmsg_t *m, int to, unsigned int mask, qboolean delta)
|
||||||
|
{
|
||||||
|
unsigned int entnum;
|
||||||
|
if (delta)
|
||||||
|
{
|
||||||
|
entity_state_t es;
|
||||||
|
unsigned int flags;
|
||||||
|
entnum = readentitynum(m, &flags);
|
||||||
|
ParseEntityDelta(tv, m, &null_entity_state, &es, flags, NULL, false);
|
||||||
|
|
||||||
|
if (entnum >= MAX_ENTITIES)
|
||||||
|
{
|
||||||
|
ParseError(m);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tv->map.entity[entnum].baseline = es;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entnum = ReadShort(m);
|
||||||
|
if (entnum >= MAX_ENTITIES)
|
||||||
|
{
|
||||||
|
ParseError(m);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParseEntityState(tv, &tv->map.entity[entnum].baseline, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionData(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, Q1);
|
||||||
|
}
|
||||||
|
|
||||||
static void ParseUpdatePing(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
static void ParseUpdatePing(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
{
|
{
|
||||||
int pnum;
|
int pnum;
|
||||||
|
@ -1242,12 +1374,13 @@ static void ParseSound(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
unsigned char vol;
|
unsigned char vol;
|
||||||
unsigned char atten;
|
unsigned char atten;
|
||||||
unsigned char sound_num;
|
unsigned char sound_num;
|
||||||
short org[3];
|
float org[3];
|
||||||
int ent;
|
int ent;
|
||||||
|
|
||||||
|
|
||||||
unsigned char nqversion[64];
|
netmsg_t nqversion;
|
||||||
int nqlen = 0;
|
unsigned char nqbuffer[64];
|
||||||
|
InitNetMsg(&nqversion, nqbuffer, sizeof(nqbuffer));
|
||||||
|
|
||||||
channel = (unsigned short)ReadShort(m);
|
channel = (unsigned short)ReadShort(m);
|
||||||
|
|
||||||
|
@ -1268,48 +1401,51 @@ static void ParseSound(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
channel &= 7;
|
channel &= 7;
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
org[i] = ReadCoord (m, tv->pext);
|
org[i] = ReadCoord (m, tv->pext1);
|
||||||
|
|
||||||
Multicast(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, QW);
|
Multicast(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, QW);
|
||||||
|
|
||||||
nqversion[0] = svc_sound;
|
|
||||||
nqversion[1] = 0;
|
WriteByte(&nqversion, svc_sound);
|
||||||
|
i = 0;
|
||||||
if (vol != DEFAULT_SOUND_PACKET_VOLUME)
|
if (vol != DEFAULT_SOUND_PACKET_VOLUME)
|
||||||
nqversion[1] |= 1;
|
i |= 1;
|
||||||
if (atten != DEFAULT_SOUND_PACKET_ATTENUATION)
|
if (atten != DEFAULT_SOUND_PACKET_ATTENUATION)
|
||||||
nqversion[1] |= 2;
|
i |= 2;
|
||||||
nqlen=2;
|
if (ent > 8191 || channel > 7)
|
||||||
|
i |= 8;
|
||||||
|
if (sound_num > 255)
|
||||||
|
i |= 16;
|
||||||
|
WriteByte(&nqversion, i);
|
||||||
|
if (i & 1)
|
||||||
|
WriteByte(&nqversion, vol);
|
||||||
|
if (i & 2)
|
||||||
|
WriteByte(&nqversion, atten*64);
|
||||||
|
if (i & 8)
|
||||||
|
{
|
||||||
|
WriteShort(&nqversion, ent);
|
||||||
|
WriteByte(&nqversion, channel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
WriteShort(&nqversion, (ent<<3) | channel);
|
||||||
|
if (i & 16)
|
||||||
|
WriteShort(&nqversion, sound_num);
|
||||||
|
else
|
||||||
|
WriteByte(&nqversion, sound_num);
|
||||||
|
WriteCoord(&nqversion, org[0], tv->pext1);
|
||||||
|
WriteCoord(&nqversion, org[1], tv->pext1);
|
||||||
|
WriteCoord(&nqversion, org[2], tv->pext1);
|
||||||
|
|
||||||
if (nqversion[1] & 1)
|
Multicast(tv, nqversion.data, nqversion.cursize, to, mask, NQ);
|
||||||
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)
|
static void ParseDamage(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
{
|
{
|
||||||
ReadByte (m);
|
ReadByte (m);
|
||||||
ReadByte (m);
|
ReadByte (m);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
Multicast(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, QW);
|
Multicast(tv, (char*)m->data+m->startpos, m->readpos - m->startpos, to, mask, QW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1341,15 +1477,15 @@ static void ParseTempEntity(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
switch(i)
|
switch(i)
|
||||||
{
|
{
|
||||||
case TE_SPIKE:
|
case TE_SPIKE:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_SUPERSPIKE:
|
case TE_SUPERSPIKE:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_GUNSHOT:
|
case TE_GUNSHOT:
|
||||||
|
@ -1357,21 +1493,23 @@ static void ParseTempEntity(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
|
|
||||||
nqversion[0] = svc_temp_entity;
|
nqversion[0] = svc_temp_entity;
|
||||||
nqversion[1] = TE_GUNSHOT;
|
nqversion[1] = TE_GUNSHOT;
|
||||||
nqversion[2] = ReadByte (m);nqversion[3] = ReadByte (m);
|
if (tv->pext1 & PEXT_FLOATCOORDS)
|
||||||
nqversion[4] = ReadByte (m);nqversion[5] = ReadByte (m);
|
nqversionlength = 2+3*4;
|
||||||
nqversion[6] = ReadByte (m);nqversion[7] = ReadByte (m);
|
else
|
||||||
nqversionlength = 8;
|
nqversionlength = 2+3*2;
|
||||||
|
for (i = 2; i < nqversionlength; i++)
|
||||||
|
nqversion[i] = ReadByte (m);
|
||||||
break;
|
break;
|
||||||
case TE_EXPLOSION:
|
case TE_EXPLOSION:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_TAREXPLOSION:
|
case TE_TAREXPLOSION:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_LIGHTNING1:
|
case TE_LIGHTNING1:
|
||||||
|
@ -1379,50 +1517,50 @@ static void ParseTempEntity(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||||
case TE_LIGHTNING3:
|
case TE_LIGHTNING3:
|
||||||
ReadShort (m);
|
ReadShort (m);
|
||||||
|
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
|
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_WIZSPIKE:
|
case TE_WIZSPIKE:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_KNIGHTSPIKE:
|
case TE_KNIGHTSPIKE:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_LAVASPLASH:
|
case TE_LAVASPLASH:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_TELEPORT:
|
case TE_TELEPORT:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
dest |= NQ;
|
dest |= NQ;
|
||||||
break;
|
break;
|
||||||
case TE_BLOOD:
|
case TE_BLOOD:
|
||||||
ReadByte (m);
|
ReadByte (m);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
//FIXME: generate svc_particle for nq
|
//FIXME: generate svc_particle for nq
|
||||||
break;
|
break;
|
||||||
case TE_LIGHTNINGBLOOD:
|
case TE_LIGHTNINGBLOOD:
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
ReadCoord (m, tv->pext);
|
ReadCoord (m, tv->pext1);
|
||||||
//FIXME: generate svc_particle for nq
|
//FIXME: generate svc_particle for nq
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1542,6 +1680,8 @@ void ParseDownload(sv_t *tv, netmsg_t *m)
|
||||||
|
|
||||||
void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
||||||
{
|
{
|
||||||
|
int lastsvc;
|
||||||
|
int svc = -1;
|
||||||
int i;
|
int i;
|
||||||
netmsg_t buf;
|
netmsg_t buf;
|
||||||
qboolean clearoldplayers = true;
|
qboolean clearoldplayers = true;
|
||||||
|
@ -1552,18 +1692,20 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
||||||
buf.startpos = 0;
|
buf.startpos = 0;
|
||||||
while(buf.readpos < buf.cursize)
|
while(buf.readpos < buf.cursize)
|
||||||
{
|
{
|
||||||
|
lastsvc = svc;
|
||||||
if (buf.readpos > buf.cursize)
|
if (buf.readpos > buf.cursize)
|
||||||
{
|
{
|
||||||
Sys_Printf(tv->cluster, "Read past end of parse buffer\n");
|
Sys_Printf(tv->cluster, "Read past end of parse buffer\n, last was %i\n", lastsvc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// printf("%i\n", buf.buffer[0]);
|
|
||||||
buf.startpos = buf.readpos;
|
buf.startpos = buf.readpos;
|
||||||
switch (ReadByte(&buf))
|
svc = ReadByte(&buf);
|
||||||
|
// printf("%i\n", svc);
|
||||||
|
switch (svc)
|
||||||
{
|
{
|
||||||
case svc_bad:
|
case svc_bad:
|
||||||
ParseError(&buf);
|
ParseError(&buf);
|
||||||
Sys_Printf(tv->cluster, "ParseMessage: svc_bad\n");
|
Sys_Printf(tv->cluster, "ParseMessage: svc_bad, last was %i\n", lastsvc);
|
||||||
return;
|
return;
|
||||||
case svc_nop: //quakeworld isn't meant to send these.
|
case svc_nop: //quakeworld isn't meant to send these.
|
||||||
QTV_Printf(tv, "nop\n");
|
QTV_Printf(tv, "nop\n");
|
||||||
|
@ -1621,21 +1763,21 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
||||||
case svc_setangle:
|
case svc_setangle:
|
||||||
if (!tv->usequakeworldprotocols)
|
if (!tv->usequakeworldprotocols)
|
||||||
ReadByte(&buf);
|
ReadByte(&buf);
|
||||||
tv->proxyplayerangles[0] = ReadAngle(&buf, tv->pext);
|
tv->proxyplayerangles[0] = ReadAngle(&buf, tv->pext1);
|
||||||
tv->proxyplayerangles[1] = ReadAngle(&buf, tv->pext);
|
tv->proxyplayerangles[1] = ReadAngle(&buf, tv->pext1);
|
||||||
tv->proxyplayerangles[2] = ReadAngle(&buf, tv->pext);
|
tv->proxyplayerangles[2] = ReadAngle(&buf, tv->pext1);
|
||||||
|
|
||||||
if (tv->usequakeworldprotocols && tv->controller)
|
if (tv->usequakeworldprotocols && tv->controller)
|
||||||
SendBufferToViewer(tv->controller, (char*)buf.data+buf.startpos, buf.readpos - buf.startpos, true);
|
SendBufferToViewer(tv->controller, (char*)buf.data+buf.startpos, buf.readpos - buf.startpos, true);
|
||||||
|
|
||||||
{
|
/*{
|
||||||
char nq[4];
|
char nq[7];
|
||||||
nq[0] = svc_setangle;
|
nq[0] = svc_setangle;
|
||||||
nq[1] = tv->proxyplayerangles[0];
|
nq[1] = tv->proxyplayerangles[0];
|
||||||
nq[2] = tv->proxyplayerangles[1];
|
nq[2] = tv->proxyplayerangles[1];
|
||||||
nq[3] = tv->proxyplayerangles[2];
|
nq[3] = tv->proxyplayerangles[2];
|
||||||
// Multicast(tv, nq, 4, to, mask, Q1);
|
// Multicast(tv, nq, 4, to, mask, Q1);
|
||||||
}
|
}*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case svc_serverdata:
|
case svc_serverdata:
|
||||||
|
@ -1657,9 +1799,9 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
||||||
//#define svc_updatecolors 17 // [qbyte] [qbyte] [qbyte]
|
//#define svc_updatecolors 17 // [qbyte] [qbyte] [qbyte]
|
||||||
|
|
||||||
case svc_particle:
|
case svc_particle:
|
||||||
ReadCoord(&buf, tv->pext);
|
ReadCoord(&buf, tv->pext1);
|
||||||
ReadCoord(&buf, tv->pext);
|
ReadCoord(&buf, tv->pext1);
|
||||||
ReadCoord(&buf, tv->pext);
|
ReadCoord(&buf, tv->pext1);
|
||||||
ReadByte(&buf);
|
ReadByte(&buf);
|
||||||
ReadByte(&buf);
|
ReadByte(&buf);
|
||||||
ReadByte(&buf);
|
ReadByte(&buf);
|
||||||
|
@ -1673,12 +1815,24 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case svc_spawnstatic:
|
case svc_spawnstatic:
|
||||||
ParseSpawnStatic(tv, &buf, to, mask);
|
ParseSpawnStatic(tv, &buf, to, mask, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case svcfte_spawnstatic2:
|
||||||
|
if (tv->pext1 & PEXT_SPAWNSTATIC2)
|
||||||
|
ParseSpawnStatic(tv, &buf, to, mask, true);
|
||||||
|
else
|
||||||
|
goto badsvc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//#define svc_spawnstatic2 21
|
|
||||||
case svc_spawnbaseline:
|
case svc_spawnbaseline:
|
||||||
ParseBaseline(tv, &buf, to, mask);
|
ParseBaseline(tv, &buf, to, mask, false);
|
||||||
|
break;
|
||||||
|
case svcfte_spawnbaseline2:
|
||||||
|
if (tv->pext1 & PEXT_SPAWNSTATIC2)
|
||||||
|
ParseBaseline(tv, &buf, to, mask, true);
|
||||||
|
else
|
||||||
|
goto badsvc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case svc_temp_entity:
|
case svc_temp_entity:
|
||||||
|
@ -1762,8 +1916,9 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
||||||
ReadByte(&buf);
|
ReadByte(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case svcfte_modellistshort:
|
||||||
case svc_modellist:
|
case svc_modellist:
|
||||||
i = ParseList(tv, &buf, tv->map.modellist, to, mask);
|
i = ParseList(tv, &buf, tv->map.modellist, to, mask, svc==svcfte_modellistshort);
|
||||||
if (!i)
|
if (!i)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
@ -1837,8 +1992,9 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case svcfte_soundlistshort:
|
||||||
case svc_soundlist:
|
case svc_soundlist:
|
||||||
i = ParseList(tv, &buf, tv->map.soundlist, to, mask);
|
i = ParseList(tv, &buf, tv->map.soundlist, to, mask, svc==svcfte_soundlistshort);
|
||||||
if (!i)
|
if (!i)
|
||||||
strcpy(tv->status, "Receiving modellist\n");
|
strcpy(tv->status, "Receiving modellist\n");
|
||||||
ConnectionData(tv, (void*)((char*)buf.data+buf.startpos), buf.readpos - buf.startpos, to, mask, QW);
|
ConnectionData(tv, (void*)((char*)buf.data+buf.startpos), buf.readpos - buf.startpos, to, mask, QW);
|
||||||
|
@ -1888,8 +2044,9 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
badsvc:
|
||||||
buf.readpos = buf.startpos;
|
buf.readpos = buf.startpos;
|
||||||
Sys_Printf(tv->cluster, "Can't handle svc %i\n", (unsigned int)ReadByte(&buf));
|
Sys_Printf(tv->cluster, "Can't handle svc %i, last was %i\n", (unsigned int)ReadByte(&buf), lastsvc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,9 +149,9 @@ void PM_PlayerMove (pmove_t *pmove)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// take angles directly from command
|
// take angles directly from command
|
||||||
pmove->angles[0] = SHORT2ANGLE(pmove->cmd.angles[0]);
|
pmove->angles[0] = pmove->cmd.angles[0];
|
||||||
pmove->angles[1] = SHORT2ANGLE(pmove->cmd.angles[1]);
|
pmove->angles[1] = pmove->cmd.angles[1];
|
||||||
pmove->angles[2] = SHORT2ANGLE(pmove->cmd.angles[2]);
|
pmove->angles[2] = pmove->cmd.angles[2];
|
||||||
|
|
||||||
AngleVectors (pmove->angles, pmove->forward, pmove->right, pmove->up);
|
AngleVectors (pmove->angles, pmove->forward, pmove->right, pmove->up);
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,7 @@ enum {
|
||||||
|
|
||||||
#define svc_spawnstatic 20
|
#define svc_spawnstatic 20
|
||||||
//#define svc_spawnstatic2 21 (not used anywhere)
|
//#define svc_spawnstatic2 21 (not used anywhere)
|
||||||
|
#define svcfte_spawnstatic2 21
|
||||||
#define svc_spawnbaseline 22
|
#define svc_spawnbaseline 22
|
||||||
|
|
||||||
#define svc_temp_entity 23 // variable
|
#define svc_temp_entity 23 // variable
|
||||||
|
@ -184,7 +185,9 @@ enum {
|
||||||
#define svc_updatepl 53 // [qbyte] [qbyte]
|
#define svc_updatepl 53 // [qbyte] [qbyte]
|
||||||
#define svc_nails2 54 //mvd only - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8
|
#define svc_nails2 54 //mvd only - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8
|
||||||
|
|
||||||
|
#define svcfte_soundlistshort 56
|
||||||
|
#define svcfte_modellistshort 60
|
||||||
|
#define svcfte_spawnbaseline2 66
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,7 +255,8 @@ enum {
|
||||||
#define PEXT2_SETANGLEDELTA 0x00000004
|
#define PEXT2_SETANGLEDELTA 0x00000004
|
||||||
#define PEXT2_OLDREPLACEMENTDELTAS 0x00000008 //weaponframe was part of the entity state. that flag is now the player's v_angle.
|
#define PEXT2_OLDREPLACEMENTDELTAS 0x00000008 //weaponframe was part of the entity state. that flag is now the player's v_angle.
|
||||||
#define PEXT2_MAXPLAYERS 0x00000010 //Client is able to cope with more players than 32. abs max becomes 255, due to colormap issues.
|
#define PEXT2_MAXPLAYERS 0x00000010 //Client is able to cope with more players than 32. abs max becomes 255, due to colormap issues.
|
||||||
#define PEXT2_REPLACEMENTDELTAS 0x00000040
|
#define PEXT2_PREDINFO 0x00000020 //movevar stats, NQ input sequences+acks.
|
||||||
|
#define PEXT2_NEWSIZEENCODING 0x00000040 //richer size encoding.
|
||||||
//#define PEXT2_PK3DOWNLOADS 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs)
|
//#define PEXT2_PK3DOWNLOADS 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,8 +277,24 @@ enum {
|
||||||
#define U_SKIN (1<<4)
|
#define U_SKIN (1<<4)
|
||||||
#define U_EFFECTS (1<<5)
|
#define U_EFFECTS (1<<5)
|
||||||
#define U_SOLID (1<<6) // the entity should be solid for prediction
|
#define U_SOLID (1<<6) // the entity should be solid for prediction
|
||||||
|
#define UX_EVENMORE (1<<7)
|
||||||
|
|
||||||
|
#define UX_SCALE (1<<16) //scaler of alias models
|
||||||
|
#define UX_ALPHA (1<<17) //transparency value
|
||||||
|
#define UX_FATNESS (1<<18) //qbyte describing how fat an alias model should be. (moves verticies along normals). Useful for vacuum chambers...
|
||||||
|
#define UX_MODELDBL (1<<19) //extra bit for modelindexes
|
||||||
|
#define UX_UNUSED1 (1<<20)
|
||||||
|
#define UX_ENTITYDBL (1<<21) //use an extra qbyte for origin parts, cos one of them is off
|
||||||
|
#define UX_ENTITYDBL2 (1<<22) //use an extra qbyte for origin parts, cos one of them is off
|
||||||
|
#define UX_YETMORE (1<<23) //even more extension info stuff.
|
||||||
|
#define UX_DRAWFLAGS (1<<24) //use an extra qbyte for origin parts, cos one of them is off
|
||||||
|
#define UX_ABSLIGHT (1<<25) //Force a lightlevel
|
||||||
|
#define UX_COLOURMOD (1<<26) //rgb
|
||||||
|
#define UX_DPFLAGS (1<<27)
|
||||||
|
#define UX_TAGINFO (1<<28)
|
||||||
|
#define UX_LIGHT (1<<29)
|
||||||
|
#define UX_EFFECTS16 (1<<30)
|
||||||
|
#define UX_FARMORE (1<<31)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
66
fteqtv/qtv.h
66
fteqtv/qtv.h
|
@ -229,12 +229,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||||
|
|
||||||
|
size_t SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen);
|
||||||
|
|
||||||
|
|
||||||
#ifdef LIBQTV
|
#ifdef LIBQTV
|
||||||
#define Sys_Printf QTVSys_Printf
|
#define Sys_Printf QTVSys_Printf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VERSION "0.01" //this will be added to the serverinfo
|
#ifdef SVNREVISION
|
||||||
|
#define QTV_VERSION_STRING SVNREVISION
|
||||||
|
#else
|
||||||
|
//#include "../engine/common/bothdefs.h"
|
||||||
|
//#define QTV_VERSION_STRING STRINGIFY(FTE_VER_MAJOR)"."STRINGIFY(FTE_VER_MINOR)
|
||||||
|
#define QTV_VERSION_STRING "v?""?""?"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PROX_DEFAULTSERVERPORT 27500
|
#define PROX_DEFAULTSERVERPORT 27500
|
||||||
#define PROX_DEFAULTLISTENPORT 27501
|
#define PROX_DEFAULTLISTENPORT 27501
|
||||||
|
@ -332,22 +340,35 @@ typedef struct {
|
||||||
} filename_t;
|
} filename_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char frame;
|
unsigned char frame;
|
||||||
unsigned char modelindex;
|
unsigned short modelindex;
|
||||||
unsigned char colormap;
|
unsigned char colormap;
|
||||||
unsigned char skinnum;
|
unsigned char skinnum;
|
||||||
float origin[3];
|
float origin[3];
|
||||||
float angles[3];
|
float angles[3];
|
||||||
unsigned char effects;
|
unsigned short effects;
|
||||||
|
unsigned char alpha;
|
||||||
|
unsigned char scale;
|
||||||
|
// unsigned char fatness;
|
||||||
|
// unsigned char abslight;
|
||||||
|
// unsigned char h2flags;
|
||||||
|
// unsigned char colormod[3];
|
||||||
|
// unsigned short light[4];
|
||||||
|
// unsigned char lightstyle;
|
||||||
|
// unsigned char lightpflags;
|
||||||
|
// unsigned char tagentity;
|
||||||
|
// unsigned char tagindex;
|
||||||
} entity_state_t;
|
} entity_state_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char frame;
|
unsigned char frame;
|
||||||
unsigned char modelindex;
|
unsigned char modelindex;
|
||||||
|
//colormap
|
||||||
unsigned char skinnum;
|
unsigned char skinnum;
|
||||||
float origin[3];
|
float origin[3];
|
||||||
short velocity[3];
|
float angles[3];
|
||||||
short angles[3];
|
|
||||||
unsigned char effects;
|
unsigned char effects;
|
||||||
|
|
||||||
|
short velocity[3];
|
||||||
unsigned char weaponframe;
|
unsigned char weaponframe;
|
||||||
} player_state_t;
|
} player_state_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -378,7 +399,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char msec;
|
unsigned char msec;
|
||||||
unsigned short angles[3];
|
float angles[3];
|
||||||
short forwardmove, sidemove, upmove;
|
short forwardmove, sidemove, upmove;
|
||||||
unsigned char buttons;
|
unsigned char buttons;
|
||||||
unsigned char impulse;
|
unsigned char impulse;
|
||||||
|
@ -415,10 +436,18 @@ typedef struct {
|
||||||
} pmove_t;
|
} pmove_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define MBTN_UP (1u<<0)
|
||||||
|
#define MBTN_DOWN (1u<<1)
|
||||||
|
#define MBTN_LEFT (1u<<2)
|
||||||
|
#define MBTN_RIGHT (1u<<3)
|
||||||
|
#define MBTN_ENTER (1u<<4)
|
||||||
|
|
||||||
#define MAX_BACK_BUFFERS 16
|
#define MAX_BACK_BUFFERS 16
|
||||||
typedef struct sv_s sv_t;
|
typedef struct sv_s sv_t;
|
||||||
typedef struct cluster_s cluster_t;
|
typedef struct cluster_s cluster_t;
|
||||||
typedef struct viewer_s {
|
typedef struct viewer_s {
|
||||||
|
//viewers are regular clients connected over udp.
|
||||||
|
//they may be watching a communal stream, or they might themselves be playing through the proxy, directly controlling the stream.
|
||||||
qboolean drop;
|
qboolean drop;
|
||||||
unsigned int timeout;
|
unsigned int timeout;
|
||||||
unsigned int nextpacket; //for nq clients
|
unsigned int nextpacket; //for nq clients
|
||||||
|
@ -451,6 +480,7 @@ typedef struct viewer_s {
|
||||||
int lost; //packets
|
int lost; //packets
|
||||||
usercmd_t ucmds[3];
|
usercmd_t ucmds[3];
|
||||||
unsigned int lasttime;
|
unsigned int lasttime;
|
||||||
|
unsigned int menubuttons;
|
||||||
|
|
||||||
|
|
||||||
int settime; //the time that we last told the client.
|
int settime; //the time that we last told the client.
|
||||||
|
@ -519,8 +549,8 @@ typedef struct tcpconnect_s
|
||||||
} tcpconnect_t;
|
} tcpconnect_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
short origin[3];
|
float origin[3];
|
||||||
unsigned char soundindex;
|
unsigned short soundindex;
|
||||||
unsigned char volume;
|
unsigned char volume;
|
||||||
unsigned char attenuation;
|
unsigned char attenuation;
|
||||||
} staticsound_t;
|
} staticsound_t;
|
||||||
|
@ -588,9 +618,6 @@ struct sv_s { //details about a server connection (also known as stream)
|
||||||
qboolean upstreamacceptsdownload;
|
qboolean upstreamacceptsdownload;
|
||||||
//
|
//
|
||||||
|
|
||||||
unsigned char buffer[MAX_PROXY_BUFFER]; //this doesn't cycle.
|
|
||||||
int buffersize; //it memmoves down
|
|
||||||
int forwardpoint; //the point in the stream that we've forwarded up to.
|
|
||||||
qboolean parsingqtvheader;
|
qboolean parsingqtvheader;
|
||||||
|
|
||||||
unsigned char upstreambuffer[2048];
|
unsigned char upstreambuffer[2048];
|
||||||
|
@ -607,7 +634,8 @@ struct sv_s { //details about a server connection (also known as stream)
|
||||||
qboolean silentstream;
|
qboolean silentstream;
|
||||||
|
|
||||||
qboolean usequakeworldprotocols;
|
qboolean usequakeworldprotocols;
|
||||||
unsigned int pext;
|
unsigned int pext1;
|
||||||
|
unsigned int pext2;
|
||||||
int challenge;
|
int challenge;
|
||||||
unsigned short qport;
|
unsigned short qport;
|
||||||
int isconnected;
|
int isconnected;
|
||||||
|
@ -708,10 +736,14 @@ struct sv_s { //details about a server connection (also known as stream)
|
||||||
int thisplayer;
|
int thisplayer;
|
||||||
qboolean ispaused;
|
qboolean ispaused;
|
||||||
} map;
|
} map;
|
||||||
|
|
||||||
|
unsigned char buffer[MAX_PROXY_BUFFER]; //this doesn't cycle.
|
||||||
|
int buffersize; //it memmoves down
|
||||||
|
int forwardpoint; //the point in the stream that we've forwarded up to.
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char name[64];
|
char name[128];
|
||||||
int size;
|
int size;
|
||||||
int time, smalltime;
|
int time, smalltime;
|
||||||
} availdemo_t;
|
} availdemo_t;
|
||||||
|
@ -761,8 +793,6 @@ struct cluster_s {
|
||||||
|
|
||||||
int maxviewers;
|
int maxviewers;
|
||||||
|
|
||||||
int buildnumber;
|
|
||||||
|
|
||||||
int numproxies;
|
int numproxies;
|
||||||
int maxproxies;
|
int maxproxies;
|
||||||
|
|
||||||
|
|
317
fteqtv/qw.c
317
fteqtv/qw.c
|
@ -67,11 +67,11 @@ void ReadDeltaUsercmd (netmsg_t *m, const usercmd_t *from, usercmd_t *move)
|
||||||
|
|
||||||
// read current angles
|
// read current angles
|
||||||
if (bits & CM_ANGLE1)
|
if (bits & CM_ANGLE1)
|
||||||
move->angles[0] = ReadShort (m);
|
move->angles[0] = (ReadShort (m)/(float)0x10000)*360;
|
||||||
if (bits & CM_ANGLE2)
|
if (bits & CM_ANGLE2)
|
||||||
move->angles[1] = ReadShort (m);
|
move->angles[1] = (ReadShort (m)/(float)0x10000)*360;
|
||||||
if (bits & CM_ANGLE3)
|
if (bits & CM_ANGLE3)
|
||||||
move->angles[2] = ReadShort (m);
|
move->angles[2] = (ReadShort (m)/(float)0x10000)*360;
|
||||||
|
|
||||||
// read movement
|
// read movement
|
||||||
if (bits & CM_FORWARD)
|
if (bits & CM_FORWARD)
|
||||||
|
@ -120,11 +120,11 @@ void WriteDeltaUsercmd (netmsg_t *m, const usercmd_t *from, usercmd_t *move)
|
||||||
|
|
||||||
// read current angles
|
// read current angles
|
||||||
if (bits & CM_ANGLE1)
|
if (bits & CM_ANGLE1)
|
||||||
WriteShort (m, move->angles[0]);
|
WriteShort (m, (move->angles[0]/360.0)*0x10000);
|
||||||
if (bits & CM_ANGLE2)
|
if (bits & CM_ANGLE2)
|
||||||
WriteShort (m, move->angles[1]);
|
WriteShort (m, (move->angles[1]/360.0)*0x10000);
|
||||||
if (bits & CM_ANGLE3)
|
if (bits & CM_ANGLE3)
|
||||||
WriteShort (m, move->angles[2]);
|
WriteShort (m, (move->angles[2]/360.0)*0x10000);
|
||||||
|
|
||||||
// read movement
|
// read movement
|
||||||
if (bits & CM_FORWARD)
|
if (bits & CM_FORWARD)
|
||||||
|
@ -192,7 +192,7 @@ void BuildServerData(sv_t *tv, netmsg_t *msg, int servercount, viewer_t *viewer)
|
||||||
|
|
||||||
WriteByte(msg, svc_stufftext);
|
WriteByte(msg, svc_stufftext);
|
||||||
WriteString2(msg, "fullserverinfo \"");
|
WriteString2(msg, "fullserverinfo \"");
|
||||||
WriteString2(msg, "\\*QTV\\"VERSION);
|
WriteString2(msg, "\\*QTV\\"QTV_VERSION_STRING);
|
||||||
WriteString(msg, "\"\n");
|
WriteString(msg, "\"\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -236,11 +236,16 @@ void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int playernum)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
WriteByte(msg, svc_serverdata);
|
WriteByte(msg, svc_serverdata);
|
||||||
WriteLong(msg, PROTOCOL_VERSION_NQ);
|
if (tv && tv->pext1 & PEXT_FLOATCOORDS)
|
||||||
|
{
|
||||||
|
WriteLong(msg, 999);
|
||||||
|
WriteLong(msg, (1<<1)|(1<<4)); //short angles, float coords, same as PEXT_FLOATCOORDS
|
||||||
|
}
|
||||||
|
else
|
||||||
|
WriteLong(msg, PROTOCOL_VERSION_NQ);
|
||||||
WriteByte(msg, 16); //MAX_CLIENTS
|
WriteByte(msg, 16); //MAX_CLIENTS
|
||||||
WriteByte(msg, 1); //game type
|
WriteByte(msg, 1); //game type
|
||||||
|
|
||||||
|
|
||||||
if (!tv || tv->parsingconnectiondata )
|
if (!tv || tv->parsingconnectiondata )
|
||||||
{
|
{
|
||||||
//dummy connection, for choosing a game to watch.
|
//dummy connection, for choosing a game to watch.
|
||||||
|
@ -400,7 +405,7 @@ int SendCurrentUserinfos(sv_t *tv, int cursize, netmsg_t *msg, int i, int thispl
|
||||||
{
|
{
|
||||||
WriteByte(msg, svc_updateuserinfo);
|
WriteByte(msg, svc_updateuserinfo);
|
||||||
WriteByte(msg, i);
|
WriteByte(msg, i);
|
||||||
WriteLong(msg, i);
|
WriteLong(msg, i+1);
|
||||||
WriteString2(msg, "\\*spectator\\1\\name\\");
|
WriteString2(msg, "\\*spectator\\1\\name\\");
|
||||||
|
|
||||||
// Print the number of people on QTV along with the hostname
|
// Print the number of people on QTV along with the hostname
|
||||||
|
@ -447,7 +452,7 @@ int SendCurrentUserinfos(sv_t *tv, int cursize, netmsg_t *msg, int i, int thispl
|
||||||
}
|
}
|
||||||
WriteByte(msg, svc_updateuserinfo);
|
WriteByte(msg, svc_updateuserinfo);
|
||||||
WriteByte(msg, i);
|
WriteByte(msg, i);
|
||||||
WriteLong(msg, i);
|
WriteLong(msg, i+1);
|
||||||
WriteString(msg, tv->map.players[i].userinfo);
|
WriteString(msg, tv->map.players[i].userinfo);
|
||||||
|
|
||||||
WriteByte(msg, svc_updatefrags);
|
WriteByte(msg, svc_updatefrags);
|
||||||
|
@ -497,7 +502,7 @@ int SendCurrentBaselines(sv_t *tv, int cursize, netmsg_t *msg, int maxbuffersize
|
||||||
{
|
{
|
||||||
WriteByte(msg, svc_spawnbaseline);
|
WriteByte(msg, svc_spawnbaseline);
|
||||||
WriteShort(msg, i);
|
WriteShort(msg, i);
|
||||||
WriteEntityState(msg, &tv->map.entity[i].baseline, tv->pext);
|
WriteEntityState(msg, &tv->map.entity[i].baseline, tv->pext1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,9 +540,9 @@ int SendStaticSounds(sv_t *tv, int cursize, netmsg_t *msg, int maxbuffersize, in
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
WriteByte(msg, svc_spawnstaticsound);
|
WriteByte(msg, svc_spawnstaticsound);
|
||||||
WriteCoord(msg, tv->map.staticsound[i].origin[0], tv->pext);
|
WriteCoord(msg, tv->map.staticsound[i].origin[0], tv->pext1);
|
||||||
WriteCoord(msg, tv->map.staticsound[i].origin[1], tv->pext);
|
WriteCoord(msg, tv->map.staticsound[i].origin[1], tv->pext1);
|
||||||
WriteCoord(msg, tv->map.staticsound[i].origin[2], tv->pext);
|
WriteCoord(msg, tv->map.staticsound[i].origin[2], tv->pext1);
|
||||||
WriteByte(msg, tv->map.staticsound[i].soundindex);
|
WriteByte(msg, tv->map.staticsound[i].soundindex);
|
||||||
WriteByte(msg, tv->map.staticsound[i].volume);
|
WriteByte(msg, tv->map.staticsound[i].volume);
|
||||||
WriteByte(msg, tv->map.staticsound[i].attenuation);
|
WriteByte(msg, tv->map.staticsound[i].attenuation);
|
||||||
|
@ -560,7 +565,7 @@ int SendStaticEntities(sv_t *tv, int cursize, netmsg_t *msg, int maxbuffersize,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
WriteByte(msg, svc_spawnstatic);
|
WriteByte(msg, svc_spawnstatic);
|
||||||
WriteEntityState(msg, &tv->map.spawnstatic[i], tv->pext);
|
WriteEntityState(msg, &tv->map.spawnstatic[i], tv->pext1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
@ -651,7 +656,8 @@ void QW_SetViewersServer(cluster_t *cluster, viewer_t *viewer, sv_t *sv)
|
||||||
viewer->server->numviewers++;
|
viewer->server->numviewers++;
|
||||||
if (!sv || !sv->parsingconnectiondata)
|
if (!sv || !sv->parsingconnectiondata)
|
||||||
{
|
{
|
||||||
QW_StuffcmdToViewer(viewer, "cmd new\n");
|
if (sv != oldserver)
|
||||||
|
QW_StuffcmdToViewer(viewer, "cmd new\n");
|
||||||
viewer->thinksitsconnected = false;
|
viewer->thinksitsconnected = false;
|
||||||
}
|
}
|
||||||
viewer->servercount++;
|
viewer->servercount++;
|
||||||
|
@ -711,7 +717,7 @@ void NewClient(cluster_t *cluster, viewer_t *viewer)
|
||||||
|
|
||||||
|
|
||||||
#ifndef LIBQTV
|
#ifndef LIBQTV
|
||||||
QW_PrintfToViewer(viewer, "Welcome to FTEQTV build %i\n", cluster->buildnumber);
|
QW_PrintfToViewer(viewer, "Welcome to FTEQTV %s\n", QTV_VERSION_STRING);
|
||||||
QW_StuffcmdToViewer(viewer, "alias admin \"cmd admin\"\n");
|
QW_StuffcmdToViewer(viewer, "alias admin \"cmd admin\"\n");
|
||||||
|
|
||||||
QW_StuffcmdToViewer(viewer, "alias \"proxy:up\" \"say proxy:menu up\"\n");
|
QW_StuffcmdToViewer(viewer, "alias \"proxy:up\" \"say proxy:menu up\"\n");
|
||||||
|
@ -1030,8 +1036,7 @@ void QTV_Status(cluster_t *cluster, netadr_t *from)
|
||||||
WriteByte(&msg, 'n');
|
WriteByte(&msg, 'n');
|
||||||
|
|
||||||
WriteString2(&msg, "\\*QTV\\");
|
WriteString2(&msg, "\\*QTV\\");
|
||||||
sprintf(elem, "%i", cluster->buildnumber);
|
WriteString2(&msg, QTV_VERSION_STRING);
|
||||||
WriteString2(&msg, elem);
|
|
||||||
|
|
||||||
if (cluster->numservers==1)
|
if (cluster->numservers==1)
|
||||||
{ //show this server's info
|
{ //show this server's info
|
||||||
|
@ -1273,13 +1278,33 @@ void SV_WriteDelta(int entnum, const entity_state_t *from, const entity_state_t
|
||||||
if (from->skinnum != to->skinnum)
|
if (from->skinnum != to->skinnum)
|
||||||
bits |= U_SKIN;
|
bits |= U_SKIN;
|
||||||
if (from->modelindex != to->modelindex)
|
if (from->modelindex != to->modelindex)
|
||||||
bits |= U_MODEL;
|
{
|
||||||
|
if (to->modelindex > 0xff)
|
||||||
|
{
|
||||||
|
if (to->modelindex <= 0x1ff)
|
||||||
|
bits |= U_MODEL|UX_MODELDBL; //0x100|byte
|
||||||
|
else
|
||||||
|
bits |= UX_MODELDBL; //short
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bits |= U_MODEL;
|
||||||
|
}
|
||||||
if (from->frame != to->frame)
|
if (from->frame != to->frame)
|
||||||
bits |= U_FRAME;
|
bits |= U_FRAME;
|
||||||
if (from->effects != to->effects)
|
if ((from->effects&0xff) != (to->effects&0xff))
|
||||||
bits |= U_EFFECTS;
|
bits |= U_EFFECTS;
|
||||||
|
if ((from->effects&0xff00) != (to->effects&0xff00))
|
||||||
|
bits |= UX_EFFECTS16;
|
||||||
|
if (from->alpha != to->alpha)
|
||||||
|
bits |= UX_ALPHA;
|
||||||
|
if (from->scale != to->scale)
|
||||||
|
bits |= UX_SCALE;
|
||||||
|
|
||||||
if (bits & 255)
|
if (bits & 0xff000000)
|
||||||
|
bits |= UX_YETMORE;
|
||||||
|
if (bits & 0x00ff0000)
|
||||||
|
bits |= UX_EVENMORE;
|
||||||
|
if (bits & 0x000000ff)
|
||||||
bits |= U_MOREBITS;
|
bits |= U_MOREBITS;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1292,16 +1317,16 @@ void SV_WriteDelta(int entnum, const entity_state_t *from, const entity_state_t
|
||||||
|
|
||||||
if (bits & U_MOREBITS)
|
if (bits & U_MOREBITS)
|
||||||
WriteByte (msg, bits&255);
|
WriteByte (msg, bits&255);
|
||||||
/*
|
|
||||||
#ifdef PROTOCOLEXTENSIONS
|
if (bits & UX_EVENMORE)
|
||||||
if (bits & U_EVENMORE)
|
WriteByte (msg, bits>>16);
|
||||||
WriteByte (msg, evenmorebits&255);
|
if (bits & UX_YETMORE)
|
||||||
if (evenmorebits & U_YETMORE)
|
WriteByte (msg, bits>>24);
|
||||||
WriteByte (msg, (evenmorebits>>8)&255);
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
if (bits & U_MODEL)
|
if (bits & U_MODEL)
|
||||||
WriteByte (msg, to->modelindex&255);
|
WriteByte (msg, to->modelindex&255);
|
||||||
|
else if (bits & UX_MODELDBL)
|
||||||
|
WriteShort(msg, to->modelindex&0xffff);
|
||||||
if (bits & U_FRAME)
|
if (bits & U_FRAME)
|
||||||
WriteByte (msg, to->frame);
|
WriteByte (msg, to->frame);
|
||||||
if (bits & U_COLORMAP)
|
if (bits & U_COLORMAP)
|
||||||
|
@ -1322,6 +1347,43 @@ void SV_WriteDelta(int entnum, const entity_state_t *from, const entity_state_t
|
||||||
WriteCoord(msg, to->origin[2], pext);
|
WriteCoord(msg, to->origin[2], pext);
|
||||||
if (bits & U_ANGLE3)
|
if (bits & U_ANGLE3)
|
||||||
WriteAngle(msg, to->angles[2], pext);
|
WriteAngle(msg, to->angles[2], pext);
|
||||||
|
|
||||||
|
if (bits & UX_SCALE)
|
||||||
|
WriteByte (msg, to->scale);
|
||||||
|
if (bits & UX_ALPHA)
|
||||||
|
WriteByte (msg, to->alpha);
|
||||||
|
/* if (bits & UX_FATNESS)
|
||||||
|
WriteByte (msg, to->fatness);
|
||||||
|
if (bits & UX_DRAWFLAGS)
|
||||||
|
WriteByte (msg, to->hexen2flags);
|
||||||
|
if (bits & UX_ABSLIGHT)
|
||||||
|
WriteByte (msg, to->abslight);
|
||||||
|
if (bits & UX_COLOURMOD)
|
||||||
|
{
|
||||||
|
WriteByte (msg, to->colormod[0]);
|
||||||
|
WriteByte (msg, to->colormod[1]);
|
||||||
|
WriteByte (msg, to->colormod[2]);
|
||||||
|
}
|
||||||
|
if (bits & UX_DPFLAGS)
|
||||||
|
{ // these are bits for the 'flags' field of the entity_state_t
|
||||||
|
WriteByte (msg, to->dpflags);
|
||||||
|
}
|
||||||
|
if (bits & UX_TAGINFO)
|
||||||
|
{
|
||||||
|
WriteShort (msg, to->tagentity);
|
||||||
|
WriteShort (msg, to->tagindex);
|
||||||
|
}
|
||||||
|
if (bits & UX_LIGHT)
|
||||||
|
{
|
||||||
|
WriteShort (msg, to->light[0]);
|
||||||
|
WriteShort (msg, to->light[1]);
|
||||||
|
WriteShort (msg, to->light[2]);
|
||||||
|
WriteShort (msg, to->light[3]);
|
||||||
|
WriteByte (msg, to->lightstyle);
|
||||||
|
WriteByte (msg, to->lightpflags);
|
||||||
|
}*/
|
||||||
|
if (bits & UX_EFFECTS16)
|
||||||
|
WriteByte (msg, to->effects>>8);
|
||||||
}
|
}
|
||||||
|
|
||||||
const entity_state_t nullentstate = {0};
|
const entity_state_t nullentstate = {0};
|
||||||
|
@ -1365,7 +1427,7 @@ void SV_EmitPacketEntities (const sv_t *qtv, const viewer_t *v, const packet_ent
|
||||||
if (newnum == oldnum)
|
if (newnum == oldnum)
|
||||||
{ // delta update from old position
|
{ // delta update from old position
|
||||||
//Con_Printf ("delta %i\n", newnum);
|
//Con_Printf ("delta %i\n", newnum);
|
||||||
SV_WriteDelta (newnum, &from->ents[oldindex], &to->ents[newindex], msg, false, qtv->pext);
|
SV_WriteDelta (newnum, &from->ents[oldindex], &to->ents[newindex], msg, false, qtv->pext1);
|
||||||
|
|
||||||
oldindex++;
|
oldindex++;
|
||||||
newindex++;
|
newindex++;
|
||||||
|
@ -1376,7 +1438,7 @@ void SV_EmitPacketEntities (const sv_t *qtv, const viewer_t *v, const packet_ent
|
||||||
{ // this is a new entity, send it from the baseline
|
{ // this is a new entity, send it from the baseline
|
||||||
baseline = &qtv->map.entity[newnum].baseline;
|
baseline = &qtv->map.entity[newnum].baseline;
|
||||||
//Con_Printf ("baseline %i\n", newnum);
|
//Con_Printf ("baseline %i\n", newnum);
|
||||||
SV_WriteDelta (newnum, baseline, &to->ents[newindex], msg, true, qtv->pext);
|
SV_WriteDelta (newnum, baseline, &to->ents[newindex], msg, true, qtv->pext1);
|
||||||
|
|
||||||
newindex++;
|
newindex++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1403,7 +1465,7 @@ void Prox_SendInitialEnts(sv_t *qtv, oproxy_t *prox, netmsg_t *msg)
|
||||||
for (i = 0; i < frame->numents; i++)
|
for (i = 0; i < frame->numents; i++)
|
||||||
{
|
{
|
||||||
entnum = frame->entnums[i];
|
entnum = frame->entnums[i];
|
||||||
SV_WriteDelta(entnum, &qtv->map.entity[entnum].baseline, &frame->ents[i], msg, true, qtv->pext);
|
SV_WriteDelta(entnum, &qtv->map.entity[entnum].baseline, &frame->ents[i], msg, true, qtv->pext1);
|
||||||
}
|
}
|
||||||
WriteShort(msg, 0);
|
WriteShort(msg, 0);
|
||||||
}
|
}
|
||||||
|
@ -1413,10 +1475,10 @@ static float InterpolateAngle(float current, float ideal, float fraction)
|
||||||
float move;
|
float move;
|
||||||
|
|
||||||
move = ideal - current;
|
move = ideal - current;
|
||||||
if (move >= 32767)
|
if (move >= 180)
|
||||||
move -= 65535;
|
move -= 360;
|
||||||
else if (move <= -32767)
|
else if (move <= -180)
|
||||||
move += 65535;
|
move += 360;
|
||||||
|
|
||||||
return current + fraction * move;
|
return current + fraction * move;
|
||||||
}
|
}
|
||||||
|
@ -1425,6 +1487,7 @@ void SendLocalPlayerState(sv_t *tv, viewer_t *v, int playernum, netmsg_t *msg)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
int j;
|
int j;
|
||||||
|
unsigned int pext1 = tv?tv->pext1:0;
|
||||||
|
|
||||||
WriteByte(msg, svc_playerinfo);
|
WriteByte(msg, svc_playerinfo);
|
||||||
WriteByte(msg, playernum);
|
WriteByte(msg, playernum);
|
||||||
|
@ -1448,9 +1511,9 @@ void SendLocalPlayerState(sv_t *tv, viewer_t *v, int playernum, netmsg_t *msg)
|
||||||
flags |= (PF_VELOCITY1<<j);
|
flags |= (PF_VELOCITY1<<j);
|
||||||
|
|
||||||
WriteShort(msg, flags);
|
WriteShort(msg, flags);
|
||||||
WriteCoord(msg, tv->map.players[tv->map.thisplayer].current.origin[0], tv->pext);
|
WriteCoord(msg, tv->map.players[tv->map.thisplayer].current.origin[0], tv->pext1);
|
||||||
WriteCoord(msg, tv->map.players[tv->map.thisplayer].current.origin[1], tv->pext);
|
WriteCoord(msg, tv->map.players[tv->map.thisplayer].current.origin[1], tv->pext1);
|
||||||
WriteCoord(msg, tv->map.players[tv->map.thisplayer].current.origin[2], tv->pext);
|
WriteCoord(msg, tv->map.players[tv->map.thisplayer].current.origin[2], tv->pext1);
|
||||||
WriteByte(msg, tv->map.players[tv->map.thisplayer].current.frame);
|
WriteByte(msg, tv->map.players[tv->map.thisplayer].current.frame);
|
||||||
|
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j=0 ; j<3 ; j++)
|
||||||
|
@ -1475,9 +1538,9 @@ void SendLocalPlayerState(sv_t *tv, viewer_t *v, int playernum, netmsg_t *msg)
|
||||||
flags |= (PF_VELOCITY1<<j);
|
flags |= (PF_VELOCITY1<<j);
|
||||||
|
|
||||||
WriteShort(msg, flags);
|
WriteShort(msg, flags);
|
||||||
WriteCoord(msg, v->origin[0], tv->pext);
|
WriteCoord(msg, v->origin[0], pext1);
|
||||||
WriteCoord(msg, v->origin[1], tv->pext);
|
WriteCoord(msg, v->origin[1], pext1);
|
||||||
WriteCoord(msg, v->origin[2], tv->pext);
|
WriteCoord(msg, v->origin[2], pext1);
|
||||||
WriteByte(msg, 0);
|
WriteByte(msg, 0);
|
||||||
|
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j=0 ; j<3 ; j++)
|
||||||
|
@ -1631,11 +1694,13 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
float org[3];
|
float org[3];
|
||||||
entity_t *ent;
|
entity_t *ent;
|
||||||
playerinfo_t *pl;
|
playerinfo_t *pl;
|
||||||
|
unsigned int pext1;
|
||||||
|
|
||||||
memset(&to, 0, sizeof(to));
|
memset(&to, 0, sizeof(to));
|
||||||
|
|
||||||
if (tv)
|
if (tv)
|
||||||
{
|
{
|
||||||
|
pext1 = tv->pext1;
|
||||||
WriteByte(msg, svc_nqtime);
|
WriteByte(msg, svc_nqtime);
|
||||||
WriteFloat(msg, (tv->physicstime - tv->mapstarttime)/1000.0f);
|
WriteFloat(msg, (tv->physicstime - tv->mapstarttime)/1000.0f);
|
||||||
|
|
||||||
|
@ -1653,6 +1718,7 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
WriteFloat(msg, (cluster->curtime)/1000.0f);
|
WriteFloat(msg, (cluster->curtime)/1000.0f);
|
||||||
|
|
||||||
lerp = 1;
|
lerp = 1;
|
||||||
|
pext1 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendNQClientData(tv, v, msg);
|
SendNQClientData(tv, v, msg);
|
||||||
|
@ -1667,9 +1733,9 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
WriteShort(msg, v->trackplayer+1);
|
WriteShort(msg, v->trackplayer+1);
|
||||||
|
|
||||||
WriteByte(msg, svc_setangle);
|
WriteByte(msg, svc_setangle);
|
||||||
WriteByte(msg, (int)InterpolateAngle(tv->map.players[v->trackplayer].old.angles[0], tv->map.players[v->trackplayer].current.angles[0], lerp)>>8);
|
WriteAngle(msg, InterpolateAngle(tv->map.players[v->trackplayer].old.angles[0], tv->map.players[v->trackplayer].current.angles[0], lerp), tv->pext1);
|
||||||
WriteByte(msg, (int)InterpolateAngle(tv->map.players[v->trackplayer].old.angles[1], tv->map.players[v->trackplayer].current.angles[1], lerp)>>8);
|
WriteAngle(msg, InterpolateAngle(tv->map.players[v->trackplayer].old.angles[1], tv->map.players[v->trackplayer].current.angles[1], lerp), tv->pext1);
|
||||||
WriteByte(msg, (int)InterpolateAngle(tv->map.players[v->trackplayer].old.angles[2], tv->map.players[v->trackplayer].current.angles[2], lerp)>>8);
|
WriteAngle(msg, InterpolateAngle(tv->map.players[v->trackplayer].old.angles[2], tv->map.players[v->trackplayer].current.angles[2], lerp), tv->pext1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1688,10 +1754,10 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
bits = UNQ_ORIGIN1 | UNQ_ORIGIN2 | UNQ_ORIGIN3 | UNQ_COLORMAP;
|
bits = UNQ_ORIGIN1 | UNQ_ORIGIN2 | UNQ_ORIGIN3 | UNQ_COLORMAP;
|
||||||
|
|
||||||
|
|
||||||
if (e+1 >= 256)
|
if (e+1 > 255)
|
||||||
bits |= UNQ_LONGENTITY;
|
bits |= UNQ_LONGENTITY;
|
||||||
|
|
||||||
if (bits >= 256)
|
if (bits > 255)
|
||||||
bits |= UNQ_MOREBITS;
|
bits |= UNQ_MOREBITS;
|
||||||
WriteByte (msg,bits | UNQ_SIGNAL);
|
WriteByte (msg,bits | UNQ_SIGNAL);
|
||||||
if (bits & UNQ_MOREBITS)
|
if (bits & UNQ_MOREBITS)
|
||||||
|
@ -1712,29 +1778,27 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
if (bits & UNQ_EFFECTS)
|
if (bits & UNQ_EFFECTS)
|
||||||
WriteByte (msg, 0);
|
WriteByte (msg, 0);
|
||||||
if (bits & UNQ_ORIGIN1)
|
if (bits & UNQ_ORIGIN1)
|
||||||
WriteCoord (msg, v->origin[0], tv->pext);
|
WriteCoord (msg, v->origin[0], tv->pext1);
|
||||||
if (bits & UNQ_ANGLE1)
|
if (bits & UNQ_ANGLE1)
|
||||||
WriteAngle(msg, -(360.0*v->ucmds[2].angles[0])/0x10000, tv->pext);
|
WriteAngle(msg, -v->ucmds[2].angles[0], tv->pext1);
|
||||||
if (bits & UNQ_ORIGIN2)
|
if (bits & UNQ_ORIGIN2)
|
||||||
WriteCoord (msg, v->origin[1], tv->pext);
|
WriteCoord (msg, v->origin[1], tv->pext1);
|
||||||
if (bits & UNQ_ANGLE2)
|
if (bits & UNQ_ANGLE2)
|
||||||
WriteAngle(msg, (360.0*v->ucmds[2].angles[1])/0x10000, tv->pext);
|
WriteAngle(msg, v->ucmds[2].angles[1], tv->pext1);
|
||||||
if (bits & UNQ_ORIGIN3)
|
if (bits & UNQ_ORIGIN3)
|
||||||
WriteCoord (msg, v->origin[2], tv->pext);
|
WriteCoord (msg, v->origin[2], tv->pext1);
|
||||||
if (bits & UNQ_ANGLE3)
|
if (bits & UNQ_ANGLE3)
|
||||||
WriteAngle(msg, (360.0*v->ucmds[2].angles[2])/0x10000, tv->pext);
|
WriteAngle(msg, v->ucmds[2].angles[2], tv->pext1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pl->active)
|
if (!pl->active)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (v != tv->controller)
|
if (v != tv->controller && e != v->trackplayer)
|
||||||
if (pl->current.modelindex >= tv->map.numinlines && !BSP_Visible(tv->map.bsp, pl->leafcount, pl->leafs))
|
if (pl->current.modelindex >= tv->map.numinlines && !BSP_Visible(tv->map.bsp, pl->leafcount, pl->leafs)) //don't cull bsp objects, like nq...
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pl->current.modelindex = 8;
|
|
||||||
|
|
||||||
// send an update
|
// send an update
|
||||||
bits = 0;
|
bits = 0;
|
||||||
|
|
||||||
|
@ -1744,13 +1808,13 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
bits |= UNQ_ORIGIN1<<i;
|
bits |= UNQ_ORIGIN1<<i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pl->current.angles[0]>>8 != ent->baseline.angles[0] )
|
if ( pl->current.angles[0] != ent->baseline.angles[0] )
|
||||||
bits |= UNQ_ANGLE1;
|
bits |= UNQ_ANGLE1;
|
||||||
|
|
||||||
if ( pl->current.angles[1]>>8 != ent->baseline.angles[1] )
|
if ( pl->current.angles[1] != ent->baseline.angles[1] )
|
||||||
bits |= UNQ_ANGLE2;
|
bits |= UNQ_ANGLE2;
|
||||||
|
|
||||||
if ( pl->current.angles[2]>>8 != ent->baseline.angles[2] )
|
if ( pl->current.angles[2] != ent->baseline.angles[2] )
|
||||||
bits |= UNQ_ANGLE3;
|
bits |= UNQ_ANGLE3;
|
||||||
|
|
||||||
// if (pl->v.movetype == MOVETYPE_STEP)
|
// if (pl->v.movetype == MOVETYPE_STEP)
|
||||||
|
@ -1771,10 +1835,10 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
if (ent->baseline.modelindex != pl->current.modelindex)
|
if (ent->baseline.modelindex != pl->current.modelindex)
|
||||||
bits |= UNQ_MODEL;
|
bits |= UNQ_MODEL;
|
||||||
|
|
||||||
if (e+1 >= 256)
|
if (e+1 > 255)
|
||||||
bits |= UNQ_LONGENTITY;
|
bits |= UNQ_LONGENTITY;
|
||||||
|
|
||||||
if (bits >= 256)
|
if (bits > 255)
|
||||||
bits |= UNQ_MOREBITS;
|
bits |= UNQ_MOREBITS;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1800,17 +1864,17 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
if (bits & UNQ_EFFECTS)
|
if (bits & UNQ_EFFECTS)
|
||||||
WriteByte (msg, pl->current.effects);
|
WriteByte (msg, pl->current.effects);
|
||||||
if (bits & UNQ_ORIGIN1)
|
if (bits & UNQ_ORIGIN1)
|
||||||
WriteCoord (msg, org[0], tv->pext);
|
WriteCoord (msg, org[0], tv->pext1);
|
||||||
if (bits & UNQ_ANGLE1)
|
if (bits & UNQ_ANGLE1)
|
||||||
WriteAngle(msg, -(360.0*pl->current.angles[0])/0x10000, tv->pext);
|
WriteAngle(msg, -pl->current.angles[0], tv->pext1);
|
||||||
if (bits & UNQ_ORIGIN2)
|
if (bits & UNQ_ORIGIN2)
|
||||||
WriteCoord (msg, org[1], tv->pext);
|
WriteCoord (msg, org[1], tv->pext1);
|
||||||
if (bits & UNQ_ANGLE2)
|
if (bits & UNQ_ANGLE2)
|
||||||
WriteAngle(msg, (360.0*pl->current.angles[1])/0x10000, tv->pext);
|
WriteAngle(msg, pl->current.angles[1], tv->pext1);
|
||||||
if (bits & UNQ_ORIGIN3)
|
if (bits & UNQ_ORIGIN3)
|
||||||
WriteCoord (msg, org[2], tv->pext);
|
WriteCoord (msg, org[2], tv->pext1);
|
||||||
if (bits & UNQ_ANGLE3)
|
if (bits & UNQ_ANGLE3)
|
||||||
WriteAngle(msg, (360.0*pl->current.angles[2])/0x10000, tv->pext);
|
WriteAngle(msg, pl->current.angles[2], tv->pext1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1845,8 +1909,8 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
{
|
{
|
||||||
miss = (int)(newstate->origin[i]) - ent->baseline.origin[i];
|
miss = (newstate->origin[i]) - ent->baseline.origin[i];
|
||||||
if ( miss <= -1 || miss >= 1 )
|
if ( miss <= -1/8.0 || miss >= 1/8.0 )
|
||||||
bits |= UNQ_ORIGIN1<<i;
|
bits |= UNQ_ORIGIN1<<i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1906,17 +1970,17 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
if (bits & UNQ_EFFECTS)
|
if (bits & UNQ_EFFECTS)
|
||||||
WriteByte (msg, newstate->effects);
|
WriteByte (msg, newstate->effects);
|
||||||
if (bits & UNQ_ORIGIN1)
|
if (bits & UNQ_ORIGIN1)
|
||||||
WriteShort (msg, newstate->origin[0]);
|
WriteCoord (msg, newstate->origin[0], pext1);
|
||||||
if (bits & UNQ_ANGLE1)
|
if (bits & UNQ_ANGLE1)
|
||||||
WriteByte(msg, newstate->angles[0]);
|
WriteAngle(msg, newstate->angles[0], pext1);
|
||||||
if (bits & UNQ_ORIGIN2)
|
if (bits & UNQ_ORIGIN2)
|
||||||
WriteShort (msg, newstate->origin[1]);
|
WriteCoord (msg, newstate->origin[1], pext1);
|
||||||
if (bits & UNQ_ANGLE2)
|
if (bits & UNQ_ANGLE2)
|
||||||
WriteByte(msg, newstate->angles[1]);
|
WriteAngle(msg, newstate->angles[1], pext1);
|
||||||
if (bits & UNQ_ORIGIN3)
|
if (bits & UNQ_ORIGIN3)
|
||||||
WriteShort (msg, newstate->origin[2]);
|
WriteCoord (msg, newstate->origin[2], pext1);
|
||||||
if (bits & UNQ_ANGLE3)
|
if (bits & UNQ_ANGLE3)
|
||||||
WriteByte(msg, newstate->angles[2]);
|
WriteAngle(msg, newstate->angles[2], pext1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1928,9 +1992,9 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
WriteShort (msg,UNQ_MOREBITS|UNQ_MODEL|UNQ_ORIGIN1 | UNQ_ORIGIN2 | UNQ_ORIGIN3 | UNQ_SIGNAL);
|
WriteShort (msg,UNQ_MOREBITS|UNQ_MODEL|UNQ_ORIGIN1 | UNQ_ORIGIN2 | UNQ_ORIGIN3 | UNQ_SIGNAL);
|
||||||
WriteByte (msg, v->thisplayer+1);
|
WriteByte (msg, v->thisplayer+1);
|
||||||
WriteByte (msg, 2); //model
|
WriteByte (msg, 2); //model
|
||||||
WriteCoord (msg, v->origin[0], tv->pext);
|
WriteCoord (msg, v->origin[0], pext1);
|
||||||
WriteCoord (msg, v->origin[1], tv->pext);
|
WriteCoord (msg, v->origin[1], pext1);
|
||||||
WriteCoord (msg, v->origin[2], tv->pext);
|
WriteCoord (msg, v->origin[2], pext1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2065,18 +2129,18 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
|
||||||
(tv->map.players[i].current.origin[1] - tv->map.players[i].old.origin[1])*(tv->map.players[i].current.origin[1] - tv->map.players[i].old.origin[1]) > snapdist ||
|
(tv->map.players[i].current.origin[1] - tv->map.players[i].old.origin[1])*(tv->map.players[i].current.origin[1] - tv->map.players[i].old.origin[1]) > snapdist ||
|
||||||
(tv->map.players[i].current.origin[2] - tv->map.players[i].old.origin[2])*(tv->map.players[i].current.origin[2] - tv->map.players[i].old.origin[2]) > snapdist)
|
(tv->map.players[i].current.origin[2] - tv->map.players[i].old.origin[2])*(tv->map.players[i].current.origin[2] - tv->map.players[i].old.origin[2]) > snapdist)
|
||||||
{ //teleported (or respawned), so don't interpolate
|
{ //teleported (or respawned), so don't interpolate
|
||||||
WriteCoord(msg, tv->map.players[i].current.origin[0], tv->pext);
|
WriteCoord(msg, tv->map.players[i].current.origin[0], tv->pext1);
|
||||||
WriteCoord(msg, tv->map.players[i].current.origin[1], tv->pext);
|
WriteCoord(msg, tv->map.players[i].current.origin[1], tv->pext1);
|
||||||
WriteCoord(msg, tv->map.players[i].current.origin[2], tv->pext);
|
WriteCoord(msg, tv->map.players[i].current.origin[2], tv->pext1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //send interpolated angles
|
{ //send interpolated angles
|
||||||
interp = (lerp)*tv->map.players[i].current.origin[0] + (1-lerp)*tv->map.players[i].old.origin[0];
|
interp = (lerp)*tv->map.players[i].current.origin[0] + (1-lerp)*tv->map.players[i].old.origin[0];
|
||||||
WriteCoord(msg, interp, tv->pext);
|
WriteCoord(msg, interp, tv->pext1);
|
||||||
interp = (lerp)*tv->map.players[i].current.origin[1] + (1-lerp)*tv->map.players[i].old.origin[1];
|
interp = (lerp)*tv->map.players[i].current.origin[1] + (1-lerp)*tv->map.players[i].old.origin[1];
|
||||||
WriteCoord(msg, interp, tv->pext);
|
WriteCoord(msg, interp, tv->pext1);
|
||||||
interp = (lerp)*tv->map.players[i].current.origin[2] + (1-lerp)*tv->map.players[i].old.origin[2];
|
interp = (lerp)*tv->map.players[i].current.origin[2] + (1-lerp)*tv->map.players[i].old.origin[2];
|
||||||
WriteCoord(msg, interp, tv->pext);
|
WriteCoord(msg, interp, tv->pext1);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteByte(msg, tv->map.players[i].current.frame);
|
WriteByte(msg, tv->map.players[i].current.frame);
|
||||||
|
@ -2968,7 +3032,7 @@ tuiadmin:
|
||||||
QW_StuffcmdToViewer(v, "bind downarrow +proxback\n");
|
QW_StuffcmdToViewer(v, "bind downarrow +proxback\n");
|
||||||
QW_StuffcmdToViewer(v, "bind rightarrow +proxright\n");
|
QW_StuffcmdToViewer(v, "bind rightarrow +proxright\n");
|
||||||
QW_StuffcmdToViewer(v, "bind leftarrow +proxleft\n");
|
QW_StuffcmdToViewer(v, "bind leftarrow +proxleft\n");
|
||||||
QW_PrintfToViewer(v, "Keys bound not recognised\n");
|
QW_PrintfToViewer(v, "Keys bound\n");
|
||||||
}
|
}
|
||||||
else if (!strcmp(command, "bsay"))
|
else if (!strcmp(command, "bsay"))
|
||||||
{
|
{
|
||||||
|
@ -3200,7 +3264,12 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
||||||
WriteByte(&msg, svc_print);
|
WriteByte(&msg, svc_print);
|
||||||
|
|
||||||
if (ov->netchan.isnqprotocol)
|
if (ov->netchan.isnqprotocol)
|
||||||
|
{
|
||||||
WriteByte(&msg, 1);
|
WriteByte(&msg, 1);
|
||||||
|
WriteByte(&msg, '[');
|
||||||
|
WriteString2(&msg, "QTV");
|
||||||
|
WriteByte(&msg, ']');
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ov->conmenussupported)
|
if (ov->conmenussupported)
|
||||||
|
@ -3282,30 +3351,33 @@ void QW_StuffcmdToViewer(viewer_t *v, char *format, ...)
|
||||||
void QW_PositionAtIntermission(sv_t *qtv, viewer_t *v)
|
void QW_PositionAtIntermission(sv_t *qtv, viewer_t *v)
|
||||||
{
|
{
|
||||||
netmsg_t msg;
|
netmsg_t msg;
|
||||||
char buf[4];
|
char buf[7];
|
||||||
const intermission_t *spot;
|
const intermission_t *spot;
|
||||||
|
unsigned int pext1;
|
||||||
|
|
||||||
|
|
||||||
if (qtv)
|
if (qtv)
|
||||||
|
{
|
||||||
spot = BSP_IntermissionSpot(qtv->map.bsp);
|
spot = BSP_IntermissionSpot(qtv->map.bsp);
|
||||||
|
pext1 = qtv->pext1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
spot = &nullstreamspot;
|
spot = &nullstreamspot;
|
||||||
|
pext1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
v->origin[0] = spot->pos[0];
|
v->origin[0] = spot->pos[0];
|
||||||
v->origin[1] = spot->pos[1];
|
v->origin[1] = spot->pos[1];
|
||||||
v->origin[2] = spot->pos[2];
|
v->origin[2] = spot->pos[2];
|
||||||
|
|
||||||
|
InitNetMsg(&msg, buf, sizeof(buf));
|
||||||
msg.data = buf;
|
|
||||||
msg.maxsize = sizeof(buf);
|
|
||||||
msg.cursize = 0;
|
|
||||||
msg.overflowed = 0;
|
|
||||||
|
|
||||||
WriteByte (&msg, svc_setangle);
|
WriteByte (&msg, svc_setangle);
|
||||||
WriteByte (&msg, (spot->angle[0]/360) * 256);
|
WriteAngle(&msg, spot->angle[0], pext1);
|
||||||
WriteByte (&msg, (spot->angle[1]/360) * 256);
|
WriteAngle(&msg, spot->angle[1], pext1);
|
||||||
WriteByte (&msg, 0);//spot->angle[2]);
|
WriteAngle(&msg, 0, pext1);
|
||||||
|
|
||||||
SendBufferToViewer(v, msg.data, msg.cursize, true);
|
SendBufferToViewer(v, msg.data, msg.cursize, true);
|
||||||
}
|
}
|
||||||
|
@ -3451,11 +3523,20 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
v->drop = true;
|
v->drop = true;
|
||||||
return;
|
return;
|
||||||
case clc_move:
|
case clc_move:
|
||||||
|
v->ucmds[0] = v->ucmds[1];
|
||||||
|
v->ucmds[1] = v->ucmds[2];
|
||||||
ReadFloat(m); //time, for pings
|
ReadFloat(m); //time, for pings
|
||||||
//three angles
|
//three angles
|
||||||
v->ucmds[2].angles[0] = ReadByte(m)*256;
|
{
|
||||||
v->ucmds[2].angles[1] = ReadByte(m)*256;
|
unsigned int pext1;
|
||||||
v->ucmds[2].angles[2] = ReadByte(m)*256;
|
if (v->server)
|
||||||
|
pext1 = v->server->pext1;
|
||||||
|
else
|
||||||
|
pext1 = 0;
|
||||||
|
v->ucmds[2].angles[0] = ReadAngle(m, pext1);
|
||||||
|
v->ucmds[2].angles[1] = ReadAngle(m, pext1);
|
||||||
|
v->ucmds[2].angles[2] = ReadAngle(m, pext1);
|
||||||
|
}
|
||||||
//three direction values
|
//three direction values
|
||||||
v->ucmds[2].forwardmove = ReadShort(m);
|
v->ucmds[2].forwardmove = ReadShort(m);
|
||||||
v->ucmds[2].sidemove = ReadShort(m);
|
v->ucmds[2].sidemove = ReadShort(m);
|
||||||
|
@ -3469,6 +3550,29 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
v->ucmds[2].msec = cluster->curtime - v->lasttime;
|
v->ucmds[2].msec = cluster->curtime - v->lasttime;
|
||||||
v->lasttime = cluster->curtime;
|
v->lasttime = cluster->curtime;
|
||||||
|
|
||||||
|
if (v->menunum)
|
||||||
|
{
|
||||||
|
int mb = 0;
|
||||||
|
if (v->ucmds[2].forwardmove > 0) mb = MBTN_UP;
|
||||||
|
if (v->ucmds[2].forwardmove < 0) mb = MBTN_DOWN;
|
||||||
|
if (v->ucmds[2].sidemove > 0) mb = MBTN_RIGHT;
|
||||||
|
if (v->ucmds[2].sidemove < 0) mb = MBTN_LEFT;
|
||||||
|
if (v->ucmds[2].buttons & 2) mb = MBTN_ENTER;
|
||||||
|
if (mb & ~v->menubuttons & MBTN_UP) v->menuop -= 1;
|
||||||
|
if (mb & ~v->menubuttons & MBTN_DOWN) v->menuop += 1;
|
||||||
|
if (mb & ~v->menubuttons & MBTN_RIGHT) Menu_Enter(cluster, v, 1);
|
||||||
|
if (mb & ~v->menubuttons & MBTN_LEFT) Menu_Enter(cluster, v, -1);
|
||||||
|
if (mb & ~v->menubuttons & MBTN_ENTER) Menu_Enter(cluster, v, 0);
|
||||||
|
if (v->menubuttons != mb)
|
||||||
|
v->menuspamtime = cluster->curtime-1;
|
||||||
|
v->ucmds[2].forwardmove = 0;
|
||||||
|
v->ucmds[2].sidemove = 0;
|
||||||
|
v->ucmds[2].buttons = 0;
|
||||||
|
v->menubuttons = mb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
v->menubuttons = ~0; //so nothing gets instantly flagged once we enter a menu.
|
||||||
|
|
||||||
if (v->server && v->server->controller == v)
|
if (v->server && v->server->controller == v)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3498,8 +3602,11 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
*/
|
*/
|
||||||
if (t >= MAX_CLIENTS)
|
if (t >= MAX_CLIENTS)
|
||||||
{
|
{
|
||||||
|
if (v->trackplayer >= 0)
|
||||||
|
QW_PrintfToViewer(v, "Stopped tracking\n");
|
||||||
|
else
|
||||||
|
QW_PrintfToViewer(v, "Not tracking\n");
|
||||||
v->trackplayer = -1; //no trackable players found
|
v->trackplayer = -1; //no trackable players found
|
||||||
QW_PrintfToViewer(v, "Not tracking\n");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3554,9 +3661,9 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
|
|
||||||
if (v->trackplayer > -1 && v->server)
|
if (v->trackplayer > -1 && v->server)
|
||||||
{
|
{
|
||||||
v->origin[0] = v->server->map.players[v->trackplayer].current.origin[0]/8.0;
|
v->origin[0] = v->server->map.players[v->trackplayer].current.origin[0];
|
||||||
v->origin[1] = v->server->map.players[v->trackplayer].current.origin[1]/8.0;
|
v->origin[1] = v->server->map.players[v->trackplayer].current.origin[1];
|
||||||
v->origin[2] = v->server->map.players[v->trackplayer].current.origin[2]/8.0;
|
v->origin[2] = v->server->map.players[v->trackplayer].current.origin[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -3602,7 +3709,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
QW_StuffcmdToViewer(v, "cmd new\n");
|
QW_StuffcmdToViewer(v, "cmd new\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QW_StuffcmdToViewer(v, "//querycmd conmenu\n");
|
// QW_StuffcmdToViewer(v, "//querycmd conmenu\n");
|
||||||
SendServerData(qtv, v);
|
SendServerData(qtv, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qtv.h"
|
#include "qtv.h"
|
||||||
|
#include <time.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#else
|
#else
|
||||||
|
@ -1230,7 +1231,7 @@ void Cmd_Commands(cmdctxt_t *ctx)
|
||||||
const rconcommands_t *cmd;
|
const rconcommands_t *cmd;
|
||||||
consolecommand_t lastfunc = NULL;
|
consolecommand_t lastfunc = NULL;
|
||||||
|
|
||||||
Cmd_Printf(ctx, "Commands:\n");
|
Cmd_Printf(ctx, "Say Commands:\n");
|
||||||
for (cmd = rconcommands; cmd->name; cmd++)
|
for (cmd = rconcommands; cmd->name; cmd++)
|
||||||
{
|
{
|
||||||
if (cmd->func == lastfunc)
|
if (cmd->func == lastfunc)
|
||||||
|
|
|
@ -874,7 +874,8 @@ qboolean Net_ConnectToServer(sv_t *qtv)
|
||||||
char *ip = Net_DiagnoseProtocol(qtv);
|
char *ip = Net_DiagnoseProtocol(qtv);
|
||||||
|
|
||||||
qtv->usequakeworldprotocols = false;
|
qtv->usequakeworldprotocols = false;
|
||||||
qtv->pext = 0;
|
qtv->pext1 = 0;
|
||||||
|
qtv->pext2 = 0;
|
||||||
|
|
||||||
if (qtv->sourcetype == SRC_DEMO || qtv->sourcetype == SRC_DEMODIR)
|
if (qtv->sourcetype == SRC_DEMO || qtv->sourcetype == SRC_DEMODIR)
|
||||||
{
|
{
|
||||||
|
@ -1318,7 +1319,7 @@ qboolean QTV_ConnectStream(sv_t *qtv, char *serverurl)
|
||||||
|
|
||||||
*qtv->map.serverinfo = '\0';
|
*qtv->map.serverinfo = '\0';
|
||||||
Info_SetValueForStarKey(qtv->map.serverinfo, "*version", "FTEQTV", sizeof(qtv->map.serverinfo));
|
Info_SetValueForStarKey(qtv->map.serverinfo, "*version", "FTEQTV", sizeof(qtv->map.serverinfo));
|
||||||
Info_SetValueForStarKey(qtv->map.serverinfo, "*qtv", VERSION, sizeof(qtv->map.serverinfo));
|
Info_SetValueForStarKey(qtv->map.serverinfo, "*qtv", QTV_VERSION_STRING, sizeof(qtv->map.serverinfo));
|
||||||
Info_SetValueForStarKey(qtv->map.serverinfo, "hostname", qtv->cluster->hostname, sizeof(qtv->map.serverinfo));
|
Info_SetValueForStarKey(qtv->map.serverinfo, "hostname", qtv->cluster->hostname, sizeof(qtv->map.serverinfo));
|
||||||
Info_SetValueForStarKey(qtv->map.serverinfo, "maxclients", "99", sizeof(qtv->map.serverinfo));
|
Info_SetValueForStarKey(qtv->map.serverinfo, "maxclients", "99", sizeof(qtv->map.serverinfo));
|
||||||
if (!strncmp(qtv->server, "file:", 5))
|
if (!strncmp(qtv->server, "file:", 5))
|
||||||
|
@ -2011,9 +2012,9 @@ void QTV_Run(sv_t *qtv)
|
||||||
cmd[1] = &qtv->proxyplayerucmds[(qtv->proxyplayerucmdnum-1)%3];
|
cmd[1] = &qtv->proxyplayerucmds[(qtv->proxyplayerucmdnum-1)%3];
|
||||||
cmd[2] = &qtv->proxyplayerucmds[(qtv->proxyplayerucmdnum-0)%3];
|
cmd[2] = &qtv->proxyplayerucmds[(qtv->proxyplayerucmdnum-0)%3];
|
||||||
|
|
||||||
cmd[2]->angles[0] = qtv->proxyplayerangles[0]/360*65535;
|
cmd[2]->angles[0] = (qtv->proxyplayerangles[0]/360)*0x10000;
|
||||||
cmd[2]->angles[1] = qtv->proxyplayerangles[1]/360*65535;
|
cmd[2]->angles[1] = (qtv->proxyplayerangles[1]/360)*0x10000;
|
||||||
cmd[2]->angles[2] = qtv->proxyplayerangles[2]/360*65535;
|
cmd[2]->angles[2] = (qtv->proxyplayerangles[2]/360)*0x10000;
|
||||||
cmd[2]->buttons = qtv->proxyplayerbuttons & 255;
|
cmd[2]->buttons = qtv->proxyplayerbuttons & 255;
|
||||||
cmd[2]->forwardmove = (qtv->proxyplayerbuttons & (1<<8))?800:0 + (qtv->proxyplayerbuttons & (1<<9))?-800:0;
|
cmd[2]->forwardmove = (qtv->proxyplayerbuttons & (1<<8))?800:0 + (qtv->proxyplayerbuttons & (1<<9))?-800:0;
|
||||||
cmd[2]->sidemove = (qtv->proxyplayerbuttons & (1<<11))?800:0 + (qtv->proxyplayerbuttons & (1<<10))?-800:0;
|
cmd[2]->sidemove = (qtv->proxyplayerbuttons & (1<<11))?800:0 + (qtv->proxyplayerbuttons & (1<<10))?-800:0;
|
||||||
|
|
Loading…
Reference in a new issue