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;
|
||||
|
||||
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;
|
||||
numleafs++;
|
||||
|
|
|
@ -13,46 +13,6 @@ Contains the control routines that handle both incoming and outgoing stuff
|
|||
#include <direct.h>
|
||||
#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 {
|
||||
char name[56];
|
||||
int offset;
|
||||
|
@ -517,12 +477,11 @@ int main(int argc, char **argv)
|
|||
cluster->qwlistenportnum = 0;
|
||||
cluster->allownqclients = true;
|
||||
strcpy(cluster->hostname, DEFAULT_HOSTNAME);
|
||||
cluster->buildnumber = build_number();
|
||||
cluster->maxproxies = -1;
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#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..)
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -235,7 +236,7 @@ static void HTTPSV_SendHTMLFooter(cluster_t *cluster, oproxy_t *dest)
|
|||
char buffer[2048];
|
||||
|
||||
/*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));
|
||||
|
||||
#if 0
|
||||
|
@ -1193,7 +1194,7 @@ void HTTPSV_GetMethod(cluster_t *cluster, oproxy_t *pend)
|
|||
unsigned char sha1digest[20];
|
||||
char padkey[512];
|
||||
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),
|
||||
"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)
|
||||
{
|
||||
default:
|
||||
if (buttonnum < 0)
|
||||
QW_SetMenu(viewer, MENU_MAIN); //no other sort of back button...
|
||||
break;
|
||||
|
||||
case MENU_MAIN:
|
||||
|
@ -73,8 +75,25 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
|
|||
break;
|
||||
|
||||
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;
|
||||
|
||||
case MENU_DEMOS:
|
||||
|
@ -115,7 +134,9 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
|
|||
}
|
||||
//fallthrough
|
||||
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");
|
||||
strcpy(viewer->expectcommand, "insecadddemo");
|
||||
|
@ -252,8 +273,7 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
|
|||
|
||||
WriteByte(&m, svc_centerprint);
|
||||
|
||||
sprintf(str, "FTEQTV build %i\n", cluster->buildnumber);
|
||||
WriteString2(&m, str);
|
||||
WriteString2(&m, "/PFTEQTV "QTV_VERSION_STRING"\n");
|
||||
WriteString2(&m, PROXYWEBSITE"\n");
|
||||
WriteString2(&m, "-------------\n");
|
||||
|
||||
|
@ -302,6 +322,11 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
|
|||
int c;
|
||||
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");
|
||||
|
||||
start = viewer->menuop & ~7;
|
||||
|
@ -358,16 +383,13 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
|
|||
start = viewer->menuop & ~7;
|
||||
for (i = start; i < start+8; i++)
|
||||
{
|
||||
if (i == viewer->menuop)
|
||||
{
|
||||
WriteByte(&m, '[');
|
||||
WriteString2(&m, cluster->availdemos[i].name);
|
||||
WriteByte(&m, ']');
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteString2(&m, cluster->availdemos[i].name);
|
||||
}
|
||||
char cleanname[128];
|
||||
char *us;
|
||||
strlcpy(cleanname, cluster->availdemos[i].name, sizeof(cleanname));
|
||||
for (us = cleanname; *us; us++)
|
||||
if (*us == '_')
|
||||
*us = ' ';
|
||||
WriteStringSelection(&m, i == viewer->menuop, cleanname);
|
||||
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
|
||||
;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
else
|
||||
return (ReadByte(b) * 360.0) / 0x100;
|
||||
|
@ -139,7 +139,7 @@ void WriteCoord(netmsg_t *b, float c, unsigned int pext)
|
|||
if (pext & PEXT_FLOATCOORDS)
|
||||
WriteFloat(b, c);
|
||||
else
|
||||
WriteShort(b, c*8);
|
||||
WriteShort(b, (short)(c*8));
|
||||
}
|
||||
void WriteAngle(netmsg_t *b, float a, unsigned int pext)
|
||||
{
|
||||
|
|
|
@ -50,20 +50,20 @@ EXPORT int PUBLIC QTV_Init (void)
|
|||
cluster = malloc(sizeof(*cluster));
|
||||
if (cluster)
|
||||
{
|
||||
memset(cluster, 0, sizeof(*cluster));
|
||||
|
||||
memset(cluster, 0, sizeof(*cluster));
|
||||
|
||||
cluster->qwdsocket[0] = INVALID_SOCKET;
|
||||
cluster->qwdsocket[1] = INVALID_SOCKET;
|
||||
cluster->qwdsocket[1] = INVALID_SOCKET;
|
||||
cluster->tcpsocket[0] = INVALID_SOCKET;
|
||||
cluster->tcpsocket[1] = INVALID_SOCKET;
|
||||
cluster->anticheattime = 1*1000;
|
||||
cluster->tooslowdelay = 100;
|
||||
cluster->qwlistenportnum = 0;
|
||||
cluster->allownqclients = true;
|
||||
strcpy(cluster->hostname, DEFAULT_HOSTNAME);
|
||||
cluster->buildnumber = build_number();
|
||||
cluster->maxproxies = -1;
|
||||
|
||||
cluster->tcpsocket[1] = INVALID_SOCKET;
|
||||
cluster->anticheattime = 1*1000;
|
||||
cluster->tooslowdelay = 100;
|
||||
cluster->qwlistenportnum = 0;
|
||||
cluster->allownqclients = true;
|
||||
strcpy(cluster->hostname, DEFAULT_HOSTNAME);
|
||||
cluster->buildnumber = build_number();
|
||||
cluster->maxproxies = -1;
|
||||
|
||||
strcpy(cluster->demodir, "qw/demos/");
|
||||
return 0;
|
||||
}
|
||||
|
|
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 //
|
||||
|
||||
static const entity_state_t null_entity_state;
|
||||
|
||||
void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean reliable)
|
||||
{
|
||||
if (reliable)
|
||||
|
@ -46,6 +48,7 @@ void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean re
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
//create a new backbuffer
|
||||
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
|
||||
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(;;)
|
||||
{
|
||||
protocol = ReadLong(m);
|
||||
|
@ -132,26 +138,74 @@ static void ParseServerData(sv_t *tv, netmsg_t *m, int to, unsigned int playerma
|
|||
break;
|
||||
case PROTOCOL_VERSION_FTE:
|
||||
protocol = ReadLong(m);
|
||||
tv->pext = protocol;
|
||||
tv->pext1 = protocol;
|
||||
|
||||
//HAVE
|
||||
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_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)
|
||||
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;
|
||||
case PROTOCOL_VERSION_FTE2:
|
||||
protocol = ReadLong(m);
|
||||
tv->pext2 = protocol;
|
||||
supported = 0;
|
||||
// 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)
|
||||
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FTE2 (%x) not supported\n", protocol & ~supported);
|
||||
continue;
|
||||
|
@ -270,7 +324,7 @@ void QTV_UpdatedServerInfo(sv_t *tv)
|
|||
fromproxy = false;
|
||||
|
||||
//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_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)
|
||||
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"))
|
||||
{
|
||||
if (tv->controller)
|
||||
|
@ -363,8 +422,6 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
|||
/*strip trailing quote*/
|
||||
text[strlen(text)-1] = '\0';
|
||||
|
||||
|
||||
|
||||
//copy over the server's 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 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);
|
||||
return;
|
||||
}
|
||||
|
@ -557,11 +616,14 @@ static void ParseCenterprint(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
|||
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;
|
||||
|
||||
first = ReadByte(m)+1;
|
||||
if (big)
|
||||
first = ReadShort(m)+1;
|
||||
else
|
||||
first = ReadByte(m)+1;
|
||||
for (; first < MAX_LIST; first++)
|
||||
{
|
||||
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);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
es->origin[i] = ReadCoord(m, tv->pext);
|
||||
es->angles[i] = ReadAngle(m, tv->pext);
|
||||
es->origin[i] = ReadCoord(m, tv->pext1);
|
||||
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)
|
||||
{
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
tv->map.staticsound[tv->map.staticsound_count].origin[0] = ReadShort(m);
|
||||
tv->map.staticsound[tv->map.staticsound_count].origin[1] = ReadShort(m);
|
||||
tv->map.staticsound[tv->map.staticsound_count].origin[2] = ReadShort(m);
|
||||
tv->map.staticsound[tv->map.staticsound_count].origin[0] = ReadCoord(m, tv->pext1);
|
||||
tv->map.staticsound[tv->map.staticsound_count].origin[1] = ReadCoord(m, tv->pext1);
|
||||
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].volume = 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);
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
tv->map.players[num].current.origin[0] = ReadCoord (m, tv->pext);
|
||||
tv->map.players[num].current.origin[1] = ReadCoord (m, tv->pext);
|
||||
tv->map.players[num].current.origin[2] = 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->pext1);
|
||||
tv->map.players[num].current.origin[2] = ReadCoord (m, tv->pext1);
|
||||
|
||||
tv->map.players[num].current.frame = ReadByte(m);
|
||||
|
||||
|
@ -705,9 +739,9 @@ static void ParsePlayerInfo(sv_t *tv, netmsg_t *m, qboolean clearoldplayers)
|
|||
}
|
||||
else
|
||||
{
|
||||
tv->map.players[num].current.angles[0] = tv->proxyplayerangles[0]/360*65535;
|
||||
tv->map.players[num].current.angles[1] = tv->proxyplayerangles[1]/360*65535;
|
||||
tv->map.players[num].current.angles[2] = tv->proxyplayerangles[2]/360*65535;
|
||||
tv->map.players[num].current.angles[0] = tv->proxyplayerangles[0];
|
||||
tv->map.players[num].current.angles[1] = tv->proxyplayerangles[1];
|
||||
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++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
|
||||
/* if (flags & U_EVENMORE)
|
||||
if (flags & UX_EVENMORE)
|
||||
flags |= ReadByte(m)<<16;
|
||||
if (flags & U_YETMORE)
|
||||
if (flags & UX_YETMORE)
|
||||
flags |= ReadByte(m)<<24;
|
||||
*/ }
|
||||
}
|
||||
|
||||
/* if (flags & U_ENTITYDBL)
|
||||
if (flags & UX_ENTITYDBL)
|
||||
entnum += 512;
|
||||
if (flags & U_ENTITYDBL2)
|
||||
if (flags & UX_ENTITYDBL2)
|
||||
entnum += 1024;
|
||||
*/
|
||||
|
||||
*retflags = flags;
|
||||
|
||||
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));
|
||||
|
||||
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)
|
||||
new->frame = ReadByte(m);
|
||||
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)
|
||||
new->skinnum = ReadByte(m);
|
||||
if (flags & U_EFFECTS)
|
||||
new->effects = ReadByte(m);
|
||||
new->effects = (new->effects&0xff00)|ReadByte(m);
|
||||
|
||||
if (flags & U_ORIGIN1)
|
||||
new->origin[0] = ReadCoord(m, tv->pext);
|
||||
new->origin[0] = ReadCoord(m, tv->pext1);
|
||||
if (flags & U_ANGLE1)
|
||||
new->angles[0] = ReadAngle(m, tv->pext);
|
||||
new->angles[0] = ReadAngle(m, tv->pext1);
|
||||
if (flags & U_ORIGIN2)
|
||||
new->origin[1] = ReadCoord(m, tv->pext);
|
||||
new->origin[1] = ReadCoord(m, tv->pext1);
|
||||
if (flags & U_ANGLE2)
|
||||
new->angles[1] = ReadAngle(m, tv->pext);
|
||||
new->angles[1] = ReadAngle(m, tv->pext1);
|
||||
if (flags & U_ORIGIN3)
|
||||
new->origin[2] = ReadCoord(m, tv->pext);
|
||||
new->origin[2] = ReadCoord(m, tv->pext1);
|
||||
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)))
|
||||
{
|
||||
ent->leafcount =
|
||||
BSP_SphereLeafNums(tv->map.bsp, MAX_ENTITY_LEAFS, ent->leafs,
|
||||
new->origin[0],
|
||||
new->origin[1],
|
||||
new->origin[2], 32);
|
||||
if (ent)
|
||||
ent->leafcount =
|
||||
BSP_SphereLeafNums(tv->map.bsp, MAX_ENTITY_LEAFS, ent->leafs,
|
||||
new->origin[0],
|
||||
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)
|
||||
{
|
||||
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 atten;
|
||||
unsigned char sound_num;
|
||||
short org[3];
|
||||
float org[3];
|
||||
int ent;
|
||||
|
||||
|
||||
unsigned char nqversion[64];
|
||||
int nqlen = 0;
|
||||
netmsg_t nqversion;
|
||||
unsigned char nqbuffer[64];
|
||||
InitNetMsg(&nqversion, nqbuffer, sizeof(nqbuffer));
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
nqversion[0] = svc_sound;
|
||||
nqversion[1] = 0;
|
||||
|
||||
WriteByte(&nqversion, svc_sound);
|
||||
i = 0;
|
||||
if (vol != DEFAULT_SOUND_PACKET_VOLUME)
|
||||
nqversion[1] |= 1;
|
||||
i |= 1;
|
||||
if (atten != DEFAULT_SOUND_PACKET_ATTENUATION)
|
||||
nqversion[1] |= 2;
|
||||
nqlen=2;
|
||||
i |= 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)
|
||||
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);
|
||||
Multicast(tv, nqversion.data, nqversion.cursize, to, mask, NQ);
|
||||
}
|
||||
|
||||
static void ParseDamage(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
||||
{
|
||||
ReadByte (m);
|
||||
ReadByte (m);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
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)
|
||||
{
|
||||
case TE_SPIKE:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
case TE_SUPERSPIKE:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
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[1] = TE_GUNSHOT;
|
||||
nqversion[2] = ReadByte (m);nqversion[3] = ReadByte (m);
|
||||
nqversion[4] = ReadByte (m);nqversion[5] = ReadByte (m);
|
||||
nqversion[6] = ReadByte (m);nqversion[7] = ReadByte (m);
|
||||
nqversionlength = 8;
|
||||
if (tv->pext1 & PEXT_FLOATCOORDS)
|
||||
nqversionlength = 2+3*4;
|
||||
else
|
||||
nqversionlength = 2+3*2;
|
||||
for (i = 2; i < nqversionlength; i++)
|
||||
nqversion[i] = ReadByte (m);
|
||||
break;
|
||||
case TE_EXPLOSION:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
case TE_TAREXPLOSION:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
case TE_LIGHTNING1:
|
||||
|
@ -1379,50 +1517,50 @@ static void ParseTempEntity(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
|
|||
case TE_LIGHTNING3:
|
||||
ReadShort (m);
|
||||
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
case TE_WIZSPIKE:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
case TE_KNIGHTSPIKE:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
case TE_LAVASPLASH:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
case TE_TELEPORT:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
dest |= NQ;
|
||||
break;
|
||||
case TE_BLOOD:
|
||||
ReadByte (m);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
//FIXME: generate svc_particle for nq
|
||||
break;
|
||||
case TE_LIGHTNINGBLOOD:
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
ReadCoord (m, tv->pext1);
|
||||
//FIXME: generate svc_particle for nq
|
||||
break;
|
||||
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)
|
||||
{
|
||||
int lastsvc;
|
||||
int svc = -1;
|
||||
int i;
|
||||
netmsg_t buf;
|
||||
qboolean clearoldplayers = true;
|
||||
|
@ -1552,18 +1692,20 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
|||
buf.startpos = 0;
|
||||
while(buf.readpos < buf.cursize)
|
||||
{
|
||||
lastsvc = svc;
|
||||
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;
|
||||
}
|
||||
// printf("%i\n", buf.buffer[0]);
|
||||
buf.startpos = buf.readpos;
|
||||
switch (ReadByte(&buf))
|
||||
svc = ReadByte(&buf);
|
||||
// printf("%i\n", svc);
|
||||
switch (svc)
|
||||
{
|
||||
case svc_bad:
|
||||
ParseError(&buf);
|
||||
Sys_Printf(tv->cluster, "ParseMessage: svc_bad\n");
|
||||
Sys_Printf(tv->cluster, "ParseMessage: svc_bad, last was %i\n", lastsvc);
|
||||
return;
|
||||
case svc_nop: //quakeworld isn't meant to send these.
|
||||
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:
|
||||
if (!tv->usequakeworldprotocols)
|
||||
ReadByte(&buf);
|
||||
tv->proxyplayerangles[0] = ReadAngle(&buf, tv->pext);
|
||||
tv->proxyplayerangles[1] = ReadAngle(&buf, tv->pext);
|
||||
tv->proxyplayerangles[2] = ReadAngle(&buf, tv->pext);
|
||||
tv->proxyplayerangles[0] = ReadAngle(&buf, tv->pext1);
|
||||
tv->proxyplayerangles[1] = ReadAngle(&buf, tv->pext1);
|
||||
tv->proxyplayerangles[2] = ReadAngle(&buf, tv->pext1);
|
||||
|
||||
if (tv->usequakeworldprotocols && tv->controller)
|
||||
SendBufferToViewer(tv->controller, (char*)buf.data+buf.startpos, buf.readpos - buf.startpos, true);
|
||||
|
||||
{
|
||||
char nq[4];
|
||||
/*{
|
||||
char nq[7];
|
||||
nq[0] = svc_setangle;
|
||||
nq[1] = tv->proxyplayerangles[0];
|
||||
nq[2] = tv->proxyplayerangles[1];
|
||||
nq[3] = tv->proxyplayerangles[2];
|
||||
// Multicast(tv, nq, 4, to, mask, Q1);
|
||||
}
|
||||
}*/
|
||||
break;
|
||||
|
||||
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]
|
||||
|
||||
case svc_particle:
|
||||
ReadCoord(&buf, tv->pext);
|
||||
ReadCoord(&buf, tv->pext);
|
||||
ReadCoord(&buf, tv->pext);
|
||||
ReadCoord(&buf, tv->pext1);
|
||||
ReadCoord(&buf, tv->pext1);
|
||||
ReadCoord(&buf, tv->pext1);
|
||||
ReadByte(&buf);
|
||||
ReadByte(&buf);
|
||||
ReadByte(&buf);
|
||||
|
@ -1673,12 +1815,24 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
|||
break;
|
||||
|
||||
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;
|
||||
|
||||
//#define svc_spawnstatic2 21
|
||||
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;
|
||||
|
||||
case svc_temp_entity:
|
||||
|
@ -1762,8 +1916,9 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
|||
ReadByte(&buf);
|
||||
break;
|
||||
|
||||
case svcfte_modellistshort:
|
||||
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)
|
||||
{
|
||||
int j;
|
||||
|
@ -1837,8 +1992,9 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case svcfte_soundlistshort:
|
||||
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)
|
||||
strcpy(tv->status, "Receiving modellist\n");
|
||||
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;
|
||||
|
||||
default:
|
||||
badsvc:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,9 +149,9 @@ void PM_PlayerMove (pmove_t *pmove)
|
|||
}
|
||||
*/
|
||||
// take angles directly from command
|
||||
pmove->angles[0] = SHORT2ANGLE(pmove->cmd.angles[0]);
|
||||
pmove->angles[1] = SHORT2ANGLE(pmove->cmd.angles[1]);
|
||||
pmove->angles[2] = SHORT2ANGLE(pmove->cmd.angles[2]);
|
||||
pmove->angles[0] = pmove->cmd.angles[0];
|
||||
pmove->angles[1] = pmove->cmd.angles[1];
|
||||
pmove->angles[2] = pmove->cmd.angles[2];
|
||||
|
||||
AngleVectors (pmove->angles, pmove->forward, pmove->right, pmove->up);
|
||||
|
||||
|
|
|
@ -135,6 +135,7 @@ enum {
|
|||
|
||||
#define svc_spawnstatic 20
|
||||
//#define svc_spawnstatic2 21 (not used anywhere)
|
||||
#define svcfte_spawnstatic2 21
|
||||
#define svc_spawnbaseline 22
|
||||
|
||||
#define svc_temp_entity 23 // variable
|
||||
|
@ -184,7 +185,9 @@ enum {
|
|||
#define svc_updatepl 53 // [qbyte] [qbyte]
|
||||
#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_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_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)
|
||||
|
||||
|
||||
|
@ -273,8 +277,24 @@ enum {
|
|||
#define U_SKIN (1<<4)
|
||||
#define U_EFFECTS (1<<5)
|
||||
#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 SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen);
|
||||
|
||||
|
||||
#ifdef LIBQTV
|
||||
#define Sys_Printf QTVSys_Printf
|
||||
#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_DEFAULTLISTENPORT 27501
|
||||
|
@ -332,22 +340,35 @@ typedef struct {
|
|||
} filename_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char frame;
|
||||
unsigned char modelindex;
|
||||
unsigned char colormap;
|
||||
unsigned char skinnum;
|
||||
unsigned char frame;
|
||||
unsigned short modelindex;
|
||||
unsigned char colormap;
|
||||
unsigned char skinnum;
|
||||
float origin[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;
|
||||
typedef struct {
|
||||
unsigned char frame;
|
||||
unsigned char modelindex;
|
||||
//colormap
|
||||
unsigned char skinnum;
|
||||
float origin[3];
|
||||
short velocity[3];
|
||||
short angles[3];
|
||||
float angles[3];
|
||||
unsigned char effects;
|
||||
|
||||
short velocity[3];
|
||||
unsigned char weaponframe;
|
||||
} player_state_t;
|
||||
typedef struct {
|
||||
|
@ -378,7 +399,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
unsigned char msec;
|
||||
unsigned short angles[3];
|
||||
float angles[3];
|
||||
short forwardmove, sidemove, upmove;
|
||||
unsigned char buttons;
|
||||
unsigned char impulse;
|
||||
|
@ -415,10 +436,18 @@ typedef struct {
|
|||
} 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
|
||||
typedef struct sv_s sv_t;
|
||||
typedef struct cluster_s cluster_t;
|
||||
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;
|
||||
unsigned int timeout;
|
||||
unsigned int nextpacket; //for nq clients
|
||||
|
@ -451,6 +480,7 @@ typedef struct viewer_s {
|
|||
int lost; //packets
|
||||
usercmd_t ucmds[3];
|
||||
unsigned int lasttime;
|
||||
unsigned int menubuttons;
|
||||
|
||||
|
||||
int settime; //the time that we last told the client.
|
||||
|
@ -519,8 +549,8 @@ typedef struct tcpconnect_s
|
|||
} tcpconnect_t;
|
||||
|
||||
typedef struct {
|
||||
short origin[3];
|
||||
unsigned char soundindex;
|
||||
float origin[3];
|
||||
unsigned short soundindex;
|
||||
unsigned char volume;
|
||||
unsigned char attenuation;
|
||||
} staticsound_t;
|
||||
|
@ -588,9 +618,6 @@ struct sv_s { //details about a server connection (also known as stream)
|
|||
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;
|
||||
|
||||
unsigned char upstreambuffer[2048];
|
||||
|
@ -607,7 +634,8 @@ struct sv_s { //details about a server connection (also known as stream)
|
|||
qboolean silentstream;
|
||||
|
||||
qboolean usequakeworldprotocols;
|
||||
unsigned int pext;
|
||||
unsigned int pext1;
|
||||
unsigned int pext2;
|
||||
int challenge;
|
||||
unsigned short qport;
|
||||
int isconnected;
|
||||
|
@ -708,10 +736,14 @@ struct sv_s { //details about a server connection (also known as stream)
|
|||
int thisplayer;
|
||||
qboolean ispaused;
|
||||
} 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 {
|
||||
char name[64];
|
||||
char name[128];
|
||||
int size;
|
||||
int time, smalltime;
|
||||
} availdemo_t;
|
||||
|
@ -761,8 +793,6 @@ struct cluster_s {
|
|||
|
||||
int maxviewers;
|
||||
|
||||
int buildnumber;
|
||||
|
||||
int numproxies;
|
||||
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
|
||||
if (bits & CM_ANGLE1)
|
||||
move->angles[0] = ReadShort (m);
|
||||
move->angles[0] = (ReadShort (m)/(float)0x10000)*360;
|
||||
if (bits & CM_ANGLE2)
|
||||
move->angles[1] = ReadShort (m);
|
||||
move->angles[1] = (ReadShort (m)/(float)0x10000)*360;
|
||||
if (bits & CM_ANGLE3)
|
||||
move->angles[2] = ReadShort (m);
|
||||
move->angles[2] = (ReadShort (m)/(float)0x10000)*360;
|
||||
|
||||
// read movement
|
||||
if (bits & CM_FORWARD)
|
||||
|
@ -120,11 +120,11 @@ void WriteDeltaUsercmd (netmsg_t *m, const usercmd_t *from, usercmd_t *move)
|
|||
|
||||
// read current angles
|
||||
if (bits & CM_ANGLE1)
|
||||
WriteShort (m, move->angles[0]);
|
||||
WriteShort (m, (move->angles[0]/360.0)*0x10000);
|
||||
if (bits & CM_ANGLE2)
|
||||
WriteShort (m, move->angles[1]);
|
||||
WriteShort (m, (move->angles[1]/360.0)*0x10000);
|
||||
if (bits & CM_ANGLE3)
|
||||
WriteShort (m, move->angles[2]);
|
||||
WriteShort (m, (move->angles[2]/360.0)*0x10000);
|
||||
|
||||
// read movement
|
||||
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);
|
||||
WriteString2(msg, "fullserverinfo \"");
|
||||
WriteString2(msg, "\\*QTV\\"VERSION);
|
||||
WriteString2(msg, "\\*QTV\\"QTV_VERSION_STRING);
|
||||
WriteString(msg, "\"\n");
|
||||
|
||||
}
|
||||
|
@ -236,11 +236,16 @@ void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int playernum)
|
|||
{
|
||||
int i;
|
||||
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, 1); //game type
|
||||
|
||||
|
||||
if (!tv || tv->parsingconnectiondata )
|
||||
{
|
||||
//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, i);
|
||||
WriteLong(msg, i);
|
||||
WriteLong(msg, i+1);
|
||||
WriteString2(msg, "\\*spectator\\1\\name\\");
|
||||
|
||||
// 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, i);
|
||||
WriteLong(msg, i);
|
||||
WriteLong(msg, i+1);
|
||||
WriteString(msg, tv->map.players[i].userinfo);
|
||||
|
||||
WriteByte(msg, svc_updatefrags);
|
||||
|
@ -497,7 +502,7 @@ int SendCurrentBaselines(sv_t *tv, int cursize, netmsg_t *msg, int maxbuffersize
|
|||
{
|
||||
WriteByte(msg, svc_spawnbaseline);
|
||||
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;
|
||||
|
||||
WriteByte(msg, svc_spawnstaticsound);
|
||||
WriteCoord(msg, tv->map.staticsound[i].origin[0], tv->pext);
|
||||
WriteCoord(msg, tv->map.staticsound[i].origin[1], tv->pext);
|
||||
WriteCoord(msg, tv->map.staticsound[i].origin[2], tv->pext);
|
||||
WriteCoord(msg, tv->map.staticsound[i].origin[0], tv->pext1);
|
||||
WriteCoord(msg, tv->map.staticsound[i].origin[1], tv->pext1);
|
||||
WriteCoord(msg, tv->map.staticsound[i].origin[2], tv->pext1);
|
||||
WriteByte(msg, tv->map.staticsound[i].soundindex);
|
||||
WriteByte(msg, tv->map.staticsound[i].volume);
|
||||
WriteByte(msg, tv->map.staticsound[i].attenuation);
|
||||
|
@ -560,7 +565,7 @@ int SendStaticEntities(sv_t *tv, int cursize, netmsg_t *msg, int maxbuffersize,
|
|||
continue;
|
||||
|
||||
WriteByte(msg, svc_spawnstatic);
|
||||
WriteEntityState(msg, &tv->map.spawnstatic[i], tv->pext);
|
||||
WriteEntityState(msg, &tv->map.spawnstatic[i], tv->pext1);
|
||||
}
|
||||
|
||||
return i;
|
||||
|
@ -651,7 +656,8 @@ void QW_SetViewersServer(cluster_t *cluster, viewer_t *viewer, sv_t *sv)
|
|||
viewer->server->numviewers++;
|
||||
if (!sv || !sv->parsingconnectiondata)
|
||||
{
|
||||
QW_StuffcmdToViewer(viewer, "cmd new\n");
|
||||
if (sv != oldserver)
|
||||
QW_StuffcmdToViewer(viewer, "cmd new\n");
|
||||
viewer->thinksitsconnected = false;
|
||||
}
|
||||
viewer->servercount++;
|
||||
|
@ -711,7 +717,7 @@ void NewClient(cluster_t *cluster, viewer_t *viewer)
|
|||
|
||||
|
||||
#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 \"proxy:up\" \"say proxy:menu up\"\n");
|
||||
|
@ -1030,8 +1036,7 @@ void QTV_Status(cluster_t *cluster, netadr_t *from)
|
|||
WriteByte(&msg, 'n');
|
||||
|
||||
WriteString2(&msg, "\\*QTV\\");
|
||||
sprintf(elem, "%i", cluster->buildnumber);
|
||||
WriteString2(&msg, elem);
|
||||
WriteString2(&msg, QTV_VERSION_STRING);
|
||||
|
||||
if (cluster->numservers==1)
|
||||
{ //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)
|
||||
bits |= U_SKIN;
|
||||
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)
|
||||
bits |= U_FRAME;
|
||||
if (from->effects != to->effects)
|
||||
if ((from->effects&0xff) != (to->effects&0xff))
|
||||
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;
|
||||
|
||||
|
||||
|
@ -1292,16 +1317,16 @@ void SV_WriteDelta(int entnum, const entity_state_t *from, const entity_state_t
|
|||
|
||||
if (bits & U_MOREBITS)
|
||||
WriteByte (msg, bits&255);
|
||||
/*
|
||||
#ifdef PROTOCOLEXTENSIONS
|
||||
if (bits & U_EVENMORE)
|
||||
WriteByte (msg, evenmorebits&255);
|
||||
if (evenmorebits & U_YETMORE)
|
||||
WriteByte (msg, (evenmorebits>>8)&255);
|
||||
#endif
|
||||
*/
|
||||
|
||||
if (bits & UX_EVENMORE)
|
||||
WriteByte (msg, bits>>16);
|
||||
if (bits & UX_YETMORE)
|
||||
WriteByte (msg, bits>>24);
|
||||
|
||||
if (bits & U_MODEL)
|
||||
WriteByte (msg, to->modelindex&255);
|
||||
else if (bits & UX_MODELDBL)
|
||||
WriteShort(msg, to->modelindex&0xffff);
|
||||
if (bits & U_FRAME)
|
||||
WriteByte (msg, to->frame);
|
||||
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);
|
||||
if (bits & U_ANGLE3)
|
||||
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};
|
||||
|
@ -1365,7 +1427,7 @@ void SV_EmitPacketEntities (const sv_t *qtv, const viewer_t *v, const packet_ent
|
|||
if (newnum == oldnum)
|
||||
{ // delta update from old position
|
||||
//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++;
|
||||
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
|
||||
baseline = &qtv->map.entity[newnum].baseline;
|
||||
//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++;
|
||||
continue;
|
||||
|
@ -1403,7 +1465,7 @@ void Prox_SendInitialEnts(sv_t *qtv, oproxy_t *prox, netmsg_t *msg)
|
|||
for (i = 0; i < frame->numents; 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);
|
||||
}
|
||||
|
@ -1413,10 +1475,10 @@ static float InterpolateAngle(float current, float ideal, float fraction)
|
|||
float move;
|
||||
|
||||
move = ideal - current;
|
||||
if (move >= 32767)
|
||||
move -= 65535;
|
||||
else if (move <= -32767)
|
||||
move += 65535;
|
||||
if (move >= 180)
|
||||
move -= 360;
|
||||
else if (move <= -180)
|
||||
move += 360;
|
||||
|
||||
return current + fraction * move;
|
||||
}
|
||||
|
@ -1425,6 +1487,7 @@ void SendLocalPlayerState(sv_t *tv, viewer_t *v, int playernum, netmsg_t *msg)
|
|||
{
|
||||
int flags;
|
||||
int j;
|
||||
unsigned int pext1 = tv?tv->pext1:0;
|
||||
|
||||
WriteByte(msg, svc_playerinfo);
|
||||
WriteByte(msg, playernum);
|
||||
|
@ -1448,9 +1511,9 @@ void SendLocalPlayerState(sv_t *tv, viewer_t *v, int playernum, netmsg_t *msg)
|
|||
flags |= (PF_VELOCITY1<<j);
|
||||
|
||||
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[1], tv->pext);
|
||||
WriteCoord(msg, tv->map.players[tv->map.thisplayer].current.origin[2], 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->pext1);
|
||||
WriteCoord(msg, tv->map.players[tv->map.thisplayer].current.origin[2], tv->pext1);
|
||||
WriteByte(msg, tv->map.players[tv->map.thisplayer].current.frame);
|
||||
|
||||
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);
|
||||
|
||||
WriteShort(msg, flags);
|
||||
WriteCoord(msg, v->origin[0], tv->pext);
|
||||
WriteCoord(msg, v->origin[1], tv->pext);
|
||||
WriteCoord(msg, v->origin[2], tv->pext);
|
||||
WriteCoord(msg, v->origin[0], pext1);
|
||||
WriteCoord(msg, v->origin[1], pext1);
|
||||
WriteCoord(msg, v->origin[2], pext1);
|
||||
WriteByte(msg, 0);
|
||||
|
||||
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];
|
||||
entity_t *ent;
|
||||
playerinfo_t *pl;
|
||||
unsigned int pext1;
|
||||
|
||||
memset(&to, 0, sizeof(to));
|
||||
|
||||
if (tv)
|
||||
{
|
||||
pext1 = tv->pext1;
|
||||
WriteByte(msg, svc_nqtime);
|
||||
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);
|
||||
|
||||
lerp = 1;
|
||||
pext1 = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
WriteByte(msg, (int)InterpolateAngle(tv->map.players[v->trackplayer].old.angles[1], tv->map.players[v->trackplayer].current.angles[1], lerp)>>8);
|
||||
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[0], tv->map.players[v->trackplayer].current.angles[0], lerp), tv->pext1);
|
||||
WriteAngle(msg, InterpolateAngle(tv->map.players[v->trackplayer].old.angles[1], tv->map.players[v->trackplayer].current.angles[1], lerp), tv->pext1);
|
||||
WriteAngle(msg, InterpolateAngle(tv->map.players[v->trackplayer].old.angles[2], tv->map.players[v->trackplayer].current.angles[2], lerp), tv->pext1);
|
||||
}
|
||||
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;
|
||||
|
||||
|
||||
if (e+1 >= 256)
|
||||
if (e+1 > 255)
|
||||
bits |= UNQ_LONGENTITY;
|
||||
|
||||
if (bits >= 256)
|
||||
if (bits > 255)
|
||||
bits |= UNQ_MOREBITS;
|
||||
WriteByte (msg,bits | UNQ_SIGNAL);
|
||||
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)
|
||||
WriteByte (msg, 0);
|
||||
if (bits & UNQ_ORIGIN1)
|
||||
WriteCoord (msg, v->origin[0], tv->pext);
|
||||
WriteCoord (msg, v->origin[0], tv->pext1);
|
||||
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)
|
||||
WriteCoord (msg, v->origin[1], tv->pext);
|
||||
WriteCoord (msg, v->origin[1], tv->pext1);
|
||||
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)
|
||||
WriteCoord (msg, v->origin[2], tv->pext);
|
||||
WriteCoord (msg, v->origin[2], tv->pext1);
|
||||
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;
|
||||
}
|
||||
|
||||
if (!pl->active)
|
||||
continue;
|
||||
|
||||
if (v != tv->controller)
|
||||
if (pl->current.modelindex >= tv->map.numinlines && !BSP_Visible(tv->map.bsp, pl->leafcount, pl->leafs))
|
||||
if (v != tv->controller && e != v->trackplayer)
|
||||
if (pl->current.modelindex >= tv->map.numinlines && !BSP_Visible(tv->map.bsp, pl->leafcount, pl->leafs)) //don't cull bsp objects, like nq...
|
||||
continue;
|
||||
|
||||
pl->current.modelindex = 8;
|
||||
|
||||
// send an update
|
||||
bits = 0;
|
||||
|
||||
|
@ -1744,13 +1808,13 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
|||
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;
|
||||
|
||||
if ( pl->current.angles[1]>>8 != ent->baseline.angles[1] )
|
||||
if ( pl->current.angles[1] != ent->baseline.angles[1] )
|
||||
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;
|
||||
|
||||
// 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)
|
||||
bits |= UNQ_MODEL;
|
||||
|
||||
if (e+1 >= 256)
|
||||
if (e+1 > 255)
|
||||
bits |= UNQ_LONGENTITY;
|
||||
|
||||
if (bits >= 256)
|
||||
if (bits > 255)
|
||||
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)
|
||||
WriteByte (msg, pl->current.effects);
|
||||
if (bits & UNQ_ORIGIN1)
|
||||
WriteCoord (msg, org[0], tv->pext);
|
||||
WriteCoord (msg, org[0], tv->pext1);
|
||||
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)
|
||||
WriteCoord (msg, org[1], tv->pext);
|
||||
WriteCoord (msg, org[1], tv->pext1);
|
||||
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)
|
||||
WriteCoord (msg, org[2], tv->pext);
|
||||
WriteCoord (msg, org[2], tv->pext1);
|
||||
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++)
|
||||
{
|
||||
miss = (int)(newstate->origin[i]) - ent->baseline.origin[i];
|
||||
if ( miss <= -1 || miss >= 1 )
|
||||
miss = (newstate->origin[i]) - ent->baseline.origin[i];
|
||||
if ( miss <= -1/8.0 || miss >= 1/8.0 )
|
||||
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)
|
||||
WriteByte (msg, newstate->effects);
|
||||
if (bits & UNQ_ORIGIN1)
|
||||
WriteShort (msg, newstate->origin[0]);
|
||||
WriteCoord (msg, newstate->origin[0], pext1);
|
||||
if (bits & UNQ_ANGLE1)
|
||||
WriteByte(msg, newstate->angles[0]);
|
||||
WriteAngle(msg, newstate->angles[0], pext1);
|
||||
if (bits & UNQ_ORIGIN2)
|
||||
WriteShort (msg, newstate->origin[1]);
|
||||
WriteCoord (msg, newstate->origin[1], pext1);
|
||||
if (bits & UNQ_ANGLE2)
|
||||
WriteByte(msg, newstate->angles[1]);
|
||||
WriteAngle(msg, newstate->angles[1], pext1);
|
||||
if (bits & UNQ_ORIGIN3)
|
||||
WriteShort (msg, newstate->origin[2]);
|
||||
WriteCoord (msg, newstate->origin[2], pext1);
|
||||
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);
|
||||
WriteByte (msg, v->thisplayer+1);
|
||||
WriteByte (msg, 2); //model
|
||||
WriteCoord (msg, v->origin[0], tv->pext);
|
||||
WriteCoord (msg, v->origin[1], tv->pext);
|
||||
WriteCoord (msg, v->origin[2], tv->pext);
|
||||
WriteCoord (msg, v->origin[0], pext1);
|
||||
WriteCoord (msg, v->origin[1], pext1);
|
||||
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[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
|
||||
WriteCoord(msg, tv->map.players[i].current.origin[0], tv->pext);
|
||||
WriteCoord(msg, tv->map.players[i].current.origin[1], tv->pext);
|
||||
WriteCoord(msg, tv->map.players[i].current.origin[2], tv->pext);
|
||||
WriteCoord(msg, tv->map.players[i].current.origin[0], tv->pext1);
|
||||
WriteCoord(msg, tv->map.players[i].current.origin[1], tv->pext1);
|
||||
WriteCoord(msg, tv->map.players[i].current.origin[2], tv->pext1);
|
||||
}
|
||||
else
|
||||
{ //send interpolated angles
|
||||
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];
|
||||
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];
|
||||
WriteCoord(msg, interp, tv->pext);
|
||||
WriteCoord(msg, interp, tv->pext1);
|
||||
}
|
||||
|
||||
WriteByte(msg, tv->map.players[i].current.frame);
|
||||
|
@ -2968,7 +3032,7 @@ tuiadmin:
|
|||
QW_StuffcmdToViewer(v, "bind downarrow +proxback\n");
|
||||
QW_StuffcmdToViewer(v, "bind rightarrow +proxright\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"))
|
||||
{
|
||||
|
@ -3200,7 +3264,12 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
WriteByte(&msg, svc_print);
|
||||
|
||||
if (ov->netchan.isnqprotocol)
|
||||
{
|
||||
WriteByte(&msg, 1);
|
||||
WriteByte(&msg, '[');
|
||||
WriteString2(&msg, "QTV");
|
||||
WriteByte(&msg, ']');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ov->conmenussupported)
|
||||
|
@ -3282,30 +3351,33 @@ void QW_StuffcmdToViewer(viewer_t *v, char *format, ...)
|
|||
void QW_PositionAtIntermission(sv_t *qtv, viewer_t *v)
|
||||
{
|
||||
netmsg_t msg;
|
||||
char buf[4];
|
||||
char buf[7];
|
||||
const intermission_t *spot;
|
||||
unsigned int pext1;
|
||||
|
||||
|
||||
if (qtv)
|
||||
{
|
||||
spot = BSP_IntermissionSpot(qtv->map.bsp);
|
||||
pext1 = qtv->pext1;
|
||||
}
|
||||
else
|
||||
{
|
||||
spot = &nullstreamspot;
|
||||
pext1 = 0;
|
||||
}
|
||||
|
||||
|
||||
v->origin[0] = spot->pos[0];
|
||||
v->origin[1] = spot->pos[1];
|
||||
v->origin[2] = spot->pos[2];
|
||||
|
||||
|
||||
msg.data = buf;
|
||||
msg.maxsize = sizeof(buf);
|
||||
msg.cursize = 0;
|
||||
msg.overflowed = 0;
|
||||
InitNetMsg(&msg, buf, sizeof(buf));
|
||||
|
||||
WriteByte (&msg, svc_setangle);
|
||||
WriteByte (&msg, (spot->angle[0]/360) * 256);
|
||||
WriteByte (&msg, (spot->angle[1]/360) * 256);
|
||||
WriteByte (&msg, 0);//spot->angle[2]);
|
||||
WriteAngle(&msg, spot->angle[0], pext1);
|
||||
WriteAngle(&msg, spot->angle[1], pext1);
|
||||
WriteAngle(&msg, 0, pext1);
|
||||
|
||||
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;
|
||||
return;
|
||||
case clc_move:
|
||||
v->ucmds[0] = v->ucmds[1];
|
||||
v->ucmds[1] = v->ucmds[2];
|
||||
ReadFloat(m); //time, for pings
|
||||
//three angles
|
||||
v->ucmds[2].angles[0] = ReadByte(m)*256;
|
||||
v->ucmds[2].angles[1] = ReadByte(m)*256;
|
||||
v->ucmds[2].angles[2] = ReadByte(m)*256;
|
||||
{
|
||||
unsigned int pext1;
|
||||
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
|
||||
v->ucmds[2].forwardmove = 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->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)
|
||||
return;
|
||||
|
||||
|
@ -3498,8 +3602,11 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
*/
|
||||
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
|
||||
QW_PrintfToViewer(v, "Not tracking\n");
|
||||
}
|
||||
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)
|
||||
{
|
||||
v->origin[0] = v->server->map.players[v->trackplayer].current.origin[0]/8.0;
|
||||
v->origin[1] = v->server->map.players[v->trackplayer].current.origin[1]/8.0;
|
||||
v->origin[2] = v->server->map.players[v->trackplayer].current.origin[2]/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];
|
||||
v->origin[2] = v->server->map.players[v->trackplayer].current.origin[2];
|
||||
}
|
||||
|
||||
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");
|
||||
else
|
||||
{
|
||||
QW_StuffcmdToViewer(v, "//querycmd conmenu\n");
|
||||
// QW_StuffcmdToViewer(v, "//querycmd conmenu\n");
|
||||
SendServerData(qtv, v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
|
||||
#include "qtv.h"
|
||||
#include <time.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
|
@ -1230,7 +1231,7 @@ void Cmd_Commands(cmdctxt_t *ctx)
|
|||
const rconcommands_t *cmd;
|
||||
consolecommand_t lastfunc = NULL;
|
||||
|
||||
Cmd_Printf(ctx, "Commands:\n");
|
||||
Cmd_Printf(ctx, "Say Commands:\n");
|
||||
for (cmd = rconcommands; cmd->name; cmd++)
|
||||
{
|
||||
if (cmd->func == lastfunc)
|
||||
|
|
|
@ -874,7 +874,8 @@ qboolean Net_ConnectToServer(sv_t *qtv)
|
|||
char *ip = Net_DiagnoseProtocol(qtv);
|
||||
|
||||
qtv->usequakeworldprotocols = false;
|
||||
qtv->pext = 0;
|
||||
qtv->pext1 = 0;
|
||||
qtv->pext2 = 0;
|
||||
|
||||
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';
|
||||
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, "maxclients", "99", sizeof(qtv->map.serverinfo));
|
||||
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[2] = &qtv->proxyplayerucmds[(qtv->proxyplayerucmdnum-0)%3];
|
||||
|
||||
cmd[2]->angles[0] = qtv->proxyplayerangles[0]/360*65535;
|
||||
cmd[2]->angles[1] = qtv->proxyplayerangles[1]/360*65535;
|
||||
cmd[2]->angles[2] = qtv->proxyplayerangles[2]/360*65535;
|
||||
cmd[2]->angles[0] = (qtv->proxyplayerangles[0]/360)*0x10000;
|
||||
cmd[2]->angles[1] = (qtv->proxyplayerangles[1]/360)*0x10000;
|
||||
cmd[2]->angles[2] = (qtv->proxyplayerangles[2]/360)*0x10000;
|
||||
cmd[2]->buttons = qtv->proxyplayerbuttons & 255;
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue