mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
This prepares for moving the net_svc code to a branch allowing both network
code cleanups and general performance work to be developed in relative peace. While cleaning up the networking code /is/ important, fixing QF's perfomance issues is of much higher priority.
This commit is contained in:
parent
f60c39e0bc
commit
c5aec15569
25 changed files with 1371 additions and 1507 deletions
|
@ -62,10 +62,11 @@
|
||||||
#define MAX_LIGHTSTYLES 64
|
#define MAX_LIGHTSTYLES 64
|
||||||
#define MAX_MODELS 256 // these are sent over the net as bytes
|
#define MAX_MODELS 256 // these are sent over the net as bytes
|
||||||
#define MAX_SOUNDS 256 // so they cannot be blindly increased
|
#define MAX_SOUNDS 256 // so they cannot be blindly increased
|
||||||
#define MAX_PROJECTILES 32
|
|
||||||
|
|
||||||
#define SAVEGAME_COMMENT_LENGTH 39
|
#define SAVEGAME_COMMENT_LENGTH 39
|
||||||
|
|
||||||
|
#define MAX_STYLESTRING 64
|
||||||
|
|
||||||
//
|
//
|
||||||
// stats are integers communicated to the client by the server
|
// stats are integers communicated to the client by the server
|
||||||
//
|
//
|
||||||
|
|
|
@ -36,8 +36,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred);
|
||||||
void CL_EmitEntities (void);
|
void CL_EmitEntities (void);
|
||||||
void CL_ClearProjectiles (void);
|
void CL_ClearProjectiles (void);
|
||||||
void CL_ParseProjectiles (void);
|
void CL_ParseProjectiles (void);
|
||||||
void CL_ParsePacketEntities (void);
|
void CL_ParsePacketEntities (qboolean delta);
|
||||||
void CL_ParseDeltaPacketEntities ();
|
|
||||||
void CL_SetSolidEntities (void);
|
void CL_SetSolidEntities (void);
|
||||||
void CL_ParsePlayerinfo (void);
|
void CL_ParsePlayerinfo (void);
|
||||||
void CL_Ents_Init (void);
|
void CL_Ents_Init (void);
|
||||||
|
|
|
@ -338,7 +338,7 @@ void CL_UpdateScreen (double realtime);
|
||||||
|
|
||||||
void CL_SetState (cactive_t state);
|
void CL_SetState (cactive_t state);
|
||||||
|
|
||||||
void CL_ParseDamage (void);
|
void V_ParseDamage (void);
|
||||||
|
|
||||||
void V_PrepBlend (void);
|
void V_PrepBlend (void);
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,6 @@ void Host_InitCommands (void);
|
||||||
void Host_Init (void);
|
void Host_Init (void);
|
||||||
void Host_Shutdown(void);
|
void Host_Shutdown(void);
|
||||||
void Host_Error (const char *error, ...) __attribute__((format(printf,1,2)));
|
void Host_Error (const char *error, ...) __attribute__((format(printf,1,2)));
|
||||||
void Host_NetError (const char *error, ...) __attribute((format(printf,1,2)));
|
|
||||||
void Host_EndGame (const char *message, ...) __attribute__((format(printf,1,2)));
|
void Host_EndGame (const char *message, ...) __attribute__((format(printf,1,2)));
|
||||||
void Host_Frame (float time);
|
void Host_Frame (float time);
|
||||||
void Host_Quit_f (void);
|
void Host_Quit_f (void);
|
||||||
|
|
|
@ -138,8 +138,6 @@ int Net_Log_Init (const char **sound_precache);
|
||||||
void Log_Incoming_Packet (const char *p, int len);
|
void Log_Incoming_Packet (const char *p, int len);
|
||||||
void Log_Outgoing_Packet (const char *p, int len);
|
void Log_Outgoing_Packet (const char *p, int len);
|
||||||
void Net_LogStop (void);
|
void Net_LogStop (void);
|
||||||
void Analyze_Server_Packet (const byte *data, int len);
|
|
||||||
void Analyze_Client_Packet (const byte *data, int len);
|
|
||||||
|
|
||||||
extern struct cvar_s *net_packetlog;
|
extern struct cvar_s *net_packetlog;
|
||||||
|
|
||||||
|
|
|
@ -214,22 +214,6 @@
|
||||||
#define U_UNUSED30 (1<<30) // future expansion
|
#define U_UNUSED30 (1<<30) // future expansion
|
||||||
#define U_EXTEND3 (1<<31) // another byte to follow, future expansion
|
#define U_EXTEND3 (1<<31) // another byte to follow, future expansion
|
||||||
|
|
||||||
|
|
||||||
#define U_GROUP_ORIG (U_ORIGIN1 | U_ORIGIN2 | U_ORIGIN3 | \
|
|
||||||
U_ANGLE2 | U_FRAME | U_REMOVE | U_MOREBITS)
|
|
||||||
#define U_GROUP_MOREBITS (U_ANGLE1 | U_ANGLE3 | U_MODEL | \
|
|
||||||
U_COLORMAP | U_SKIN | U_EFFECTS | \
|
|
||||||
U_SOLID | U_EXTEND1)
|
|
||||||
#define U_GROUP_EXTEND1 (U_ALPHA | U_SCALE | U_EFFECTS2 | \
|
|
||||||
U_GLOWSIZE | U_GLOWCOLOR | U_COLORMOD | \
|
|
||||||
U_EXTEND2)
|
|
||||||
#define U_GROUP_EXTEND2 (U_GLOWTRAIL | U_VIEWMODEL | U_FRAME2)
|
|
||||||
// I skip the UNUSED and EXTEND3 bits because although they exist in
|
|
||||||
// QSG2, they're not usable
|
|
||||||
|
|
||||||
#define U_VERSION_ID ((U_GROUP_ORIG | U_GROUP_MOREBITS) & ~U_EXTEND1)
|
|
||||||
#define U_VERSION_QSG2 (U_VERSION_ID | U_EXTEND1 | U_GROUP_EXTEND1 | \
|
|
||||||
U_GROUP_EFFECTS2)
|
|
||||||
//==============================================
|
//==============================================
|
||||||
|
|
||||||
// a sound with no channel is a local only sound
|
// a sound with no channel is a local only sound
|
||||||
|
|
|
@ -499,7 +499,7 @@ void SV_SendClientMessages (void);
|
||||||
|
|
||||||
void SV_Multicast (vec3_t origin, int to);
|
void SV_Multicast (vec3_t origin, int to);
|
||||||
void SV_StartSound (struct edict_s *entity, int channel, const char *sample,
|
void SV_StartSound (struct edict_s *entity, int channel, const char *sample,
|
||||||
float volume, float attenuation);
|
int volume, float attenuation);
|
||||||
void SV_ClientPrintf (client_t *cl, int level, const char *fmt, ...) __attribute__((format(printf,3,4)));
|
void SV_ClientPrintf (client_t *cl, int level, const char *fmt, ...) __attribute__((format(printf,3,4)));
|
||||||
void SV_BroadcastPrintf (int level, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
void SV_BroadcastPrintf (int level, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
||||||
void SV_BroadcastCommand (const char *fmt, ...) __attribute__((format(printf,1,2)));
|
void SV_BroadcastCommand (const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||||
|
|
|
@ -52,7 +52,7 @@ libasm_la_SOURCES= $(asm_src)
|
||||||
noinst_LTLIBRARIES= libqfnet.la $(asm)
|
noinst_LTLIBRARIES= libqfnet.la $(asm)
|
||||||
|
|
||||||
common_sources= buildnum.c com.c game.c msg_ucmd.c pmove.c pmovetst.c \
|
common_sources= buildnum.c com.c game.c msg_ucmd.c pmove.c pmovetst.c \
|
||||||
net_packetlog.c net_svc.c
|
net_packetlog.c
|
||||||
|
|
||||||
common_ldflags= -export-dynamic
|
common_ldflags= -export-dynamic
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,7 @@ CL_GetDemoMessage (void)
|
||||||
(net_message->message->cursize);
|
(net_message->message->cursize);
|
||||||
// Con_Printf("read: %ld bytes\n", net_message->message->cursize);
|
// Con_Printf("read: %ld bytes\n", net_message->message->cursize);
|
||||||
if (net_message->message->cursize > MAX_MSGLEN + 8) //+8 for header
|
if (net_message->message->cursize > MAX_MSGLEN + 8) //+8 for header
|
||||||
Host_Error ("Demo message > MAX_MSGLEN + 8: %d/%d",
|
Host_EndGame ("Demo message > MAX_MSGLEN + 8: %d/%d",
|
||||||
net_message->message->cursize, MAX_MSGLEN + 8);
|
net_message->message->cursize, MAX_MSGLEN + 8);
|
||||||
r = Qread (cls.demofile, net_message->message->data,
|
r = Qread (cls.demofile, net_message->message->data,
|
||||||
net_message->message->cursize);
|
net_message->message->cursize);
|
||||||
|
|
|
@ -43,7 +43,6 @@ static const char rcsid[] =
|
||||||
#include "QF/render.h"
|
#include "QF/render.h"
|
||||||
#include "QF/skin.h"
|
#include "QF/skin.h"
|
||||||
|
|
||||||
#include "bothdefs.h"
|
|
||||||
#include "cl_cam.h"
|
#include "cl_cam.h"
|
||||||
#include "cl_ents.h"
|
#include "cl_ents.h"
|
||||||
#include "cl_main.h"
|
#include "cl_main.h"
|
||||||
|
@ -54,7 +53,6 @@ static const char rcsid[] =
|
||||||
#include "d_iface.h"
|
#include "d_iface.h"
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "msg_ucmd.h"
|
#include "msg_ucmd.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "pmove.h"
|
#include "pmove.h"
|
||||||
#include "r_cvar.h"
|
#include "r_cvar.h"
|
||||||
#include "r_dynamic.h"
|
#include "r_dynamic.h"
|
||||||
|
@ -71,7 +69,6 @@ entity_t cl_flag_ents[MAX_CLIENTS];
|
||||||
entity_t cl_player_ents[MAX_CLIENTS];
|
entity_t cl_player_ents[MAX_CLIENTS];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CL_ClearEnts ()
|
CL_ClearEnts ()
|
||||||
{
|
{
|
||||||
|
@ -127,168 +124,221 @@ CL_NewDlight (int key, vec3_t org, int effects)
|
||||||
|
|
||||||
int bitcounts[32]; // / just for protocol profiling
|
int bitcounts[32]; // / just for protocol profiling
|
||||||
|
|
||||||
|
/*
|
||||||
|
CL_ParseDelta
|
||||||
|
|
||||||
|
Can go from either a baseline or a previous packet_entity
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
CL_EntityState_Copy (entity_state_t *src, entity_state_t *dest, int bits)
|
CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// set everything to the state we are delta'ing from
|
||||||
|
*to = *from;
|
||||||
|
|
||||||
|
to->number = bits & 511;
|
||||||
|
bits &= ~511;
|
||||||
|
|
||||||
|
if (bits & U_MOREBITS) { // read in the low order bits
|
||||||
|
i = MSG_ReadByte (net_message);
|
||||||
|
bits |= i;
|
||||||
|
}
|
||||||
|
// count the bits for net profiling
|
||||||
|
// for (i=0 ; i<16 ; i++)
|
||||||
|
// if (bits&(1<<i))
|
||||||
|
// bitcounts[i]++;
|
||||||
|
|
||||||
|
// LordHavoc: Endy neglected to mark this as being part of the QSG
|
||||||
|
// version 2 stuff...
|
||||||
|
if (bits & U_EXTEND1) {
|
||||||
|
bits |= MSG_ReadByte (net_message) << 16;
|
||||||
|
if (bits & U_EXTEND2)
|
||||||
|
bits |= MSG_ReadByte (net_message) << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
to->flags = bits;
|
||||||
|
|
||||||
if (bits & U_MODEL)
|
if (bits & U_MODEL)
|
||||||
dest->modelindex = src->modelindex;
|
to->modelindex = MSG_ReadByte (net_message);
|
||||||
|
|
||||||
if (bits & U_FRAME)
|
if (bits & U_FRAME)
|
||||||
dest->frame = (dest->frame & 0xFF00) | (src->frame & 0xFF);
|
to->frame = MSG_ReadByte (net_message);
|
||||||
|
|
||||||
if (bits & U_COLORMAP)
|
if (bits & U_COLORMAP)
|
||||||
dest->colormap = src->colormap;
|
to->colormap = MSG_ReadByte (net_message);
|
||||||
|
|
||||||
if (bits & U_SKIN)
|
if (bits & U_SKIN)
|
||||||
dest->skinnum = src->skinnum;
|
to->skinnum = MSG_ReadByte (net_message);
|
||||||
|
|
||||||
if (bits & U_EFFECTS)
|
if (bits & U_EFFECTS)
|
||||||
dest->effects = (dest->effects & 0xFF00) | (src->effects & 0xFF);
|
to->effects = MSG_ReadByte (net_message);
|
||||||
|
|
||||||
if (bits & U_ORIGIN1)
|
if (bits & U_ORIGIN1)
|
||||||
dest->origin[0] = src->origin[0];
|
to->origin[0] = MSG_ReadCoord (net_message);
|
||||||
if (bits & U_ANGLE1)
|
|
||||||
dest->angles[0] = src->angles[0];
|
|
||||||
if (bits & U_ORIGIN2)
|
|
||||||
dest->origin[1] = src->origin[1];
|
|
||||||
if (bits & U_ANGLE2)
|
|
||||||
dest->angles[1] = src->angles[1];
|
|
||||||
if (bits & U_ORIGIN3)
|
|
||||||
dest->origin[2] = src->origin[2];
|
|
||||||
if (bits & U_ANGLE3)
|
|
||||||
dest->angles[2] = src->angles[2];
|
|
||||||
|
|
||||||
|
if (bits & U_ANGLE1)
|
||||||
|
to->angles[0] = MSG_ReadAngle (net_message);
|
||||||
|
|
||||||
|
if (bits & U_ORIGIN2)
|
||||||
|
to->origin[1] = MSG_ReadCoord (net_message);
|
||||||
|
|
||||||
|
if (bits & U_ANGLE2)
|
||||||
|
to->angles[1] = MSG_ReadAngle (net_message);
|
||||||
|
|
||||||
|
if (bits & U_ORIGIN3)
|
||||||
|
to->origin[2] = MSG_ReadCoord (net_message);
|
||||||
|
|
||||||
|
if (bits & U_ANGLE3)
|
||||||
|
to->angles[2] = MSG_ReadAngle (net_message);
|
||||||
|
|
||||||
|
// LordHavoc: Endy neglected to mark this as being part of the QSG
|
||||||
|
// version 2 stuff... rearranged it and implemented missing effects
|
||||||
|
// Ender (QSG - Begin)
|
||||||
if (bits & U_ALPHA)
|
if (bits & U_ALPHA)
|
||||||
dest->alpha = src->alpha;
|
to->alpha = MSG_ReadByte (net_message);
|
||||||
if (bits & U_SCALE)
|
if (bits & U_SCALE)
|
||||||
dest->scale = src->scale;
|
to->scale = MSG_ReadByte (net_message);
|
||||||
if (bits & U_EFFECTS2)
|
if (bits & U_EFFECTS2)
|
||||||
dest->effects = (dest->effects & 0xFF) | (src->effects & 0xFF00);
|
to->effects = (to->effects & 0xFF) | (MSG_ReadByte (net_message) << 8);
|
||||||
if (bits & U_GLOWSIZE)
|
if (bits & U_GLOWSIZE)
|
||||||
dest->glow_size = src->glow_size;
|
to->glow_size = MSG_ReadByte (net_message);
|
||||||
if (bits & U_GLOWCOLOR)
|
if (bits & U_GLOWCOLOR)
|
||||||
dest->glow_color = src->glow_color;
|
to->glow_color = MSG_ReadByte (net_message);
|
||||||
if (bits & U_COLORMOD)
|
if (bits & U_COLORMOD)
|
||||||
dest->colormod = src->colormod;
|
to->colormod = MSG_ReadByte (net_message);
|
||||||
if (bits & U_FRAME2)
|
if (bits & U_FRAME2)
|
||||||
dest->frame = (dest->frame & 0xFF) | (src->frame & 0xFF00);
|
to->frame = (to->frame & 0xFF) | (MSG_ReadByte (net_message) << 8);
|
||||||
|
// Ender (QSG - End)
|
||||||
|
|
||||||
if (bits & U_SOLID) {
|
if (bits & U_SOLID) {
|
||||||
// FIXME
|
// FIXME
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
if ((!to->alpha) || (!to->colormod))
|
||||||
|
Con_Printf("fa: %d, fc: %d, ta: %d, tc: %d\n",
|
||||||
|
from->alpha, from->colormod, to->alpha, to->colormod);
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
if ((!ent->alpha) || (!ent->colormod[0]) || (!ent->colormod[1]) ||
|
||||||
|
(!ent->colormod[2])) {
|
||||||
|
Con_Printf ("ea: %f, ec0: %f, ec1: %f ec2: %f, sa: %d, sc: %d\n",
|
||||||
|
ent->alpha, ent->colormod[0], ent->colormod[1],
|
||||||
|
ent->colormod[2], s1->alpha, s1->colormod);
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CL_ParsePacketEntities (void)
|
FlushEntityPacket (void)
|
||||||
{
|
{
|
||||||
int index, packetnum;
|
entity_state_t olde, newe;
|
||||||
packet_entities_t *newp;
|
int word;
|
||||||
net_svc_packetentities_t block;
|
|
||||||
|
|
||||||
packetnum = cls.netchan.incoming_sequence & UPDATE_MASK;
|
Con_DPrintf ("FlushEntityPacket\n");
|
||||||
newp = &cl.frames[packetnum].packet_entities;
|
|
||||||
cl.frames[packetnum].invalid = false;
|
|
||||||
|
|
||||||
cl.validsequence = cls.netchan.incoming_sequence;
|
memset (&olde, 0, sizeof (olde));
|
||||||
|
|
||||||
newp->num_entities = 0;
|
cl.validsequence = 0; // can't render a frame
|
||||||
|
cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK].invalid = true;
|
||||||
|
|
||||||
if (NET_SVC_PacketEntities_Parse (&block, net_message)) {
|
// read it all, but ignore it
|
||||||
Host_NetError ("CL_ParsePacketEntities: Bad Read");
|
while (1) {
|
||||||
|
word = (unsigned short) MSG_ReadShort (net_message);
|
||||||
|
if (net_message->badread) { // something didn't parse right...
|
||||||
|
Host_EndGame ("msg_badread in packetentities");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (index = 0; block.words[index]; index++) {
|
if (!word)
|
||||||
if (block.words[index] & U_REMOVE) {
|
break; // done
|
||||||
Host_NetError ("CL_ParsePacketEntities: U_REMOVE on full "
|
|
||||||
"update\n");
|
|
||||||
cl.validsequence = 0; // XXX
|
|
||||||
cl.frames[packetnum].invalid = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= MAX_PACKET_ENTITIES) {
|
CL_ParseDelta (&olde, &newe, word);
|
||||||
Host_NetError ("CL_ParsePacketEntities: index %i >= "
|
|
||||||
"MAX_PACKET_ENTITIES", index);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newp->entities[index] = cl_baselines[block.words[index] & 511];
|
|
||||||
CL_EntityState_Copy (&block.deltas[index],
|
|
||||||
&newp->entities[index],
|
|
||||||
block.deltas[index].flags);
|
|
||||||
newp->entities[index].number = block.deltas[index].number;
|
|
||||||
if (newp->entities[index].modelindex >= MAX_MODELS) {
|
|
||||||
Host_NetError ("CL_ParsePacketEntities: modelindex %i >= "
|
|
||||||
"MAX_MODELS", newp->entities[index].modelindex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
newp->num_entities = index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CL_ParseDeltaPacketEntities
|
CL_ParsePacketEntities
|
||||||
|
|
||||||
An svc_packetentities has just been parsed, deal with the
|
An svc_packetentities has just been parsed, deal with the
|
||||||
rest of the data stream.
|
rest of the data stream.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
CL_ParseDeltaPacketEntities ()
|
CL_ParsePacketEntities (qboolean delta)
|
||||||
{
|
{
|
||||||
int oldindex = 0, newindex = 0;
|
byte from;
|
||||||
int wordindex = 0, deltaindex = 0;
|
int oldindex, newindex, newnum, oldnum, oldpacket, newpacket, word;
|
||||||
int oldnum, newnum;
|
packet_entities_t *oldp, *newp, dummy;
|
||||||
int oldpacket, newpacket;
|
qboolean full;
|
||||||
packet_entities_t *oldp, *newp;
|
|
||||||
net_svc_deltapacketentities_t block;
|
|
||||||
|
|
||||||
if (NET_SVC_DeltaPacketEntities_Parse (&block, net_message)) {
|
|
||||||
Host_NetError ("CL_ParseDeltaPacketEntities: Bad Read");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newpacket = cls.netchan.incoming_sequence & UPDATE_MASK;
|
newpacket = cls.netchan.incoming_sequence & UPDATE_MASK;
|
||||||
newp = &cl.frames[newpacket].packet_entities;
|
newp = &cl.frames[newpacket].packet_entities;
|
||||||
cl.frames[newpacket].invalid = false;
|
cl.frames[newpacket].invalid = false;
|
||||||
|
|
||||||
|
if (delta) {
|
||||||
|
from = MSG_ReadByte (net_message);
|
||||||
|
|
||||||
oldpacket = cl.frames[newpacket].delta_sequence;
|
oldpacket = cl.frames[newpacket].delta_sequence;
|
||||||
|
|
||||||
|
if ((from & UPDATE_MASK) != (oldpacket & UPDATE_MASK))
|
||||||
|
Con_DPrintf ("WARNING: from mismatch\n");
|
||||||
|
} else
|
||||||
|
oldpacket = -1;
|
||||||
|
|
||||||
|
full = false;
|
||||||
|
if (oldpacket != -1) {
|
||||||
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) {
|
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) {
|
||||||
// we can't use this, it is too old
|
// we can't use this, it is too old
|
||||||
Con_DPrintf ("CL_ParseDeltaPacketEntities: old packet\n");
|
FlushEntityPacket ();
|
||||||
cl.validsequence = 0; // can't render a frame
|
|
||||||
cl.frames[newpacket].invalid = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((block.from & UPDATE_MASK) != (oldpacket & UPDATE_MASK)) {
|
|
||||||
Con_DPrintf ("CL_ParseDeltaPacketEntities: from mismatch\n");
|
|
||||||
cl.validsequence = 0;
|
|
||||||
cl.frames[newpacket].invalid = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (oldpacket == -1) {
|
|
||||||
Host_NetError ("Cl_ParseDeltaPacketEntities: invalid "
|
|
||||||
"delta_sequence\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cl.validsequence = cls.netchan.incoming_sequence;
|
cl.validsequence = cls.netchan.incoming_sequence;
|
||||||
oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities;
|
oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities;
|
||||||
|
} else { // a full update that we can start delta compressing from now
|
||||||
|
oldp = &dummy;
|
||||||
|
dummy.num_entities = 0;
|
||||||
|
cl.validsequence = cls.netchan.incoming_sequence;
|
||||||
|
full = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
oldindex = 0;
|
||||||
|
newindex = 0;
|
||||||
newp->num_entities = 0;
|
newp->num_entities = 0;
|
||||||
|
|
||||||
for (; block.words[wordindex];) {
|
while (1) {
|
||||||
newnum = block.words[wordindex] & 511;
|
word = (unsigned short) MSG_ReadShort (net_message);
|
||||||
|
if (net_message->badread) { // something didn't parse right...
|
||||||
|
Host_EndGame ("msg_badread in packetentities");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!word) { // copy rest of ents from old packet
|
||||||
|
while (oldindex < oldp->num_entities) {
|
||||||
|
// Con_Printf ("copy %i\n", oldp->entities[oldindex].number);
|
||||||
|
if (newindex >= MAX_PACKET_ENTITIES)
|
||||||
|
Host_EndGame ("CL_ParsePacketEntities: newindex == "
|
||||||
|
"MAX_PACKET_ENTITIES");
|
||||||
|
newp->entities[newindex] = oldp->entities[oldindex];
|
||||||
|
newindex++;
|
||||||
|
oldindex++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
newnum = word & 511;
|
||||||
oldnum = oldindex >= oldp->num_entities ? 9999 :
|
oldnum = oldindex >= oldp->num_entities ? 9999 :
|
||||||
oldp->entities[oldindex].number;
|
oldp->entities[oldindex].number;
|
||||||
|
|
||||||
while (newnum > oldnum) { // copy one of the old entities
|
while (newnum > oldnum) {
|
||||||
// over to the new packet unchanged
|
if (full) {
|
||||||
// Con_Printf ("copy %i\n", oldnum);
|
Con_Printf ("WARNING: oldcopy on full update");
|
||||||
if (newindex >= MAX_PACKET_ENTITIES) {
|
FlushEntityPacket ();
|
||||||
Host_NetError ("CL_ParseDeltaPacketEntities: newindex >= "
|
|
||||||
"MAX_PACKET_ENTITIES (1st)");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Con_Printf ("copy %i\n", oldnum);
|
||||||
|
// copy one of the old entities over to the new packet unchanged
|
||||||
|
if (newindex >= MAX_PACKET_ENTITIES)
|
||||||
|
Host_EndGame ("CL_ParsePacketEntities: newindex == "
|
||||||
|
"MAX_PACKET_ENTITIES");
|
||||||
newp->entities[newindex] = oldp->entities[oldindex];
|
newp->entities[newindex] = oldp->entities[oldindex];
|
||||||
newindex++;
|
newindex++;
|
||||||
oldindex++;
|
oldindex++;
|
||||||
|
@ -298,74 +348,44 @@ CL_ParseDeltaPacketEntities ()
|
||||||
|
|
||||||
if (newnum < oldnum) { // new from baseline
|
if (newnum < oldnum) { // new from baseline
|
||||||
// Con_Printf ("baseline %i\n", newnum);
|
// Con_Printf ("baseline %i\n", newnum);
|
||||||
if (block.words[wordindex] & U_REMOVE) {
|
if (word & U_REMOVE) {
|
||||||
wordindex++;
|
if (full) {
|
||||||
|
cl.validsequence = 0;
|
||||||
|
Con_Printf ("WARNING: U_REMOVE on full update\n");
|
||||||
|
FlushEntityPacket ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newindex >= MAX_PACKET_ENTITIES) {
|
if (newindex >= MAX_PACKET_ENTITIES)
|
||||||
Host_NetError ("CL_ParseDeltaPacketEntities: newindex >= "
|
Host_EndGame ("CL_ParsePacketEntities: newindex == "
|
||||||
"MAX_PACKET_ENTITIES (2nd)");
|
"MAX_PACKET_ENTITIES");
|
||||||
return;
|
CL_ParseDelta (&cl_baselines[newnum], &newp->entities[newindex],
|
||||||
}
|
word);
|
||||||
newp->entities[newindex] = cl_baselines[newnum];
|
|
||||||
CL_EntityState_Copy (&block.deltas[deltaindex],
|
|
||||||
&newp->entities[newindex],
|
|
||||||
block.deltas[deltaindex].flags);
|
|
||||||
newp->entities[newindex].number
|
|
||||||
= block.deltas[deltaindex].number;
|
|
||||||
if (newp->entities[newindex].modelindex >= MAX_MODELS) {
|
|
||||||
Host_NetError ("CL_ParsePacketEntities: modelindex %i >= "
|
|
||||||
"MAX_MODELS",
|
|
||||||
newp->entities[newindex].modelindex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wordindex++;
|
|
||||||
deltaindex++;
|
|
||||||
newindex++;
|
newindex++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newnum == oldnum) { // delta from previous
|
if (newnum == oldnum) { // delta from previous
|
||||||
// Con_Printf ("delta %i\n", newnum);
|
if (full) {
|
||||||
if (block.words[wordindex] & U_REMOVE) { // Clear the entity
|
cl.validsequence = 0;
|
||||||
memset (&cl_packet_ents[newnum], 0, sizeof (entity_t));
|
Con_Printf ("WARNING: delta on full update");
|
||||||
wordindex++;
|
}
|
||||||
|
if (word & U_REMOVE) { // Clear the entity
|
||||||
|
entity_t *ent = &cl_packet_ents[newnum];
|
||||||
|
memset (ent, 0, sizeof (entity_t));
|
||||||
oldindex++;
|
oldindex++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
newp->entities[newindex] = oldp->entities[oldindex];
|
// Con_Printf ("delta %i\n", newnum);
|
||||||
CL_EntityState_Copy (&block.deltas[deltaindex],
|
CL_ParseDelta (&oldp->entities[oldindex],
|
||||||
&newp->entities[newindex],
|
&newp->entities[newindex], word);
|
||||||
block.deltas[deltaindex].flags);
|
|
||||||
newp->entities[newindex].number
|
|
||||||
= block.deltas[deltaindex].number;
|
|
||||||
if (newp->entities[newindex].modelindex >= MAX_MODELS) {
|
|
||||||
Host_NetError ("CL_ParsePacketEntities: modelindex %i >= "
|
|
||||||
"MAX_MODELS",
|
|
||||||
newp->entities[newindex].modelindex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wordindex++;
|
|
||||||
deltaindex++;
|
|
||||||
newindex++;
|
newindex++;
|
||||||
oldindex++;
|
oldindex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (oldindex < oldp->num_entities) { // copy rest of ents from old packet
|
|
||||||
// Con_Printf ("copy %i\n", oldp->entities[oldindex].number);
|
|
||||||
if (newindex >= MAX_PACKET_ENTITIES) {
|
|
||||||
Host_NetError ("CL_ParseDeltaPacketEntities: newindex >= "
|
|
||||||
"MAX_PACKET_ENTITIES (3rd)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
newp->entities[newindex] = oldp->entities[oldindex];
|
|
||||||
newindex++;
|
|
||||||
oldindex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
newp->num_entities = newindex;
|
newp->num_entities = newindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +543,7 @@ typedef struct {
|
||||||
entity_t ent;
|
entity_t ent;
|
||||||
} projectile_t;
|
} projectile_t;
|
||||||
|
|
||||||
|
#define MAX_PROJECTILES 32
|
||||||
projectile_t cl_projectiles[MAX_PROJECTILES];
|
projectile_t cl_projectiles[MAX_PROJECTILES];
|
||||||
int cl_num_projectiles;
|
int cl_num_projectiles;
|
||||||
|
|
||||||
|
@ -540,25 +561,27 @@ CL_ClearProjectiles (void)
|
||||||
void
|
void
|
||||||
CL_ParseProjectiles (void)
|
CL_ParseProjectiles (void)
|
||||||
{
|
{
|
||||||
int i;
|
byte bits[6];
|
||||||
|
int i, c, j;
|
||||||
projectile_t *pr;
|
projectile_t *pr;
|
||||||
net_svc_nails_t block;
|
|
||||||
|
|
||||||
if (NET_SVC_Nails_Parse (&block, net_message)) {
|
c = MSG_ReadByte (net_message);
|
||||||
Host_NetError ("CL_ParseProjectiles: Bad Read\n");
|
for (i = 0; i < c; i++) {
|
||||||
return;
|
for (j = 0; j < 6; j++)
|
||||||
}
|
bits[j] = MSG_ReadByte (net_message);
|
||||||
|
|
||||||
for (i = 0; i < block.numnails; i++) {
|
|
||||||
if (cl_num_projectiles == MAX_PROJECTILES)
|
if (cl_num_projectiles == MAX_PROJECTILES)
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
pr = &cl_projectiles[cl_num_projectiles];
|
pr = &cl_projectiles[cl_num_projectiles];
|
||||||
cl_num_projectiles++;
|
cl_num_projectiles++;
|
||||||
|
|
||||||
pr->modelindex = cl_spikeindex;
|
pr->modelindex = cl_spikeindex;
|
||||||
VectorCopy (block.nails[i].origin, pr->ent.origin);
|
pr->ent.origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
|
||||||
VectorCopy (block.nails[i].angles, pr->ent.angles);
|
pr->ent.origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096;
|
||||||
|
pr->ent.origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096;
|
||||||
|
pr->ent.angles[0] = 360 * (bits[4] >> 4) / 16;
|
||||||
|
pr->ent.angles[1] = 360 * bits[5] / 256;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,57 +617,66 @@ CL_LinkProjectiles (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CL_ParsePlayerinfo (void)
|
CL_ParsePlayerinfo (void)
|
||||||
{
|
{
|
||||||
|
int flags, msec, num, i;
|
||||||
player_state_t *state;
|
player_state_t *state;
|
||||||
net_svc_playerinfo_t block;
|
|
||||||
|
|
||||||
if (NET_SVC_Playerinfo_Parse (&block, net_message)) {
|
num = MSG_ReadByte (net_message);
|
||||||
Host_NetError ("CL_ParsePlayerinfo: Bad Read\n");
|
if (num > MAX_CLIENTS)
|
||||||
return;
|
// Sys_Error ("CL_ParsePlayerinfo: bad num");
|
||||||
}
|
Host_EndGame ("CL_ParsePlayerinfo: bad num");
|
||||||
|
|
||||||
if (block.playernum >= MAX_CLIENTS) {
|
state = &cl.frames[parsecountmod].playerstate[num];
|
||||||
Host_NetError ("CL_ParsePlayerinfo: playernum %i >= MAX_CLIENTS",
|
|
||||||
block.playernum);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (block.modelindex >= MAX_MODELS) {
|
|
||||||
Host_NetError ("CL_ParsePlayerinfo: modelindex %i >= MAX_MODELS",
|
|
||||||
block.modelindex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = &cl.frames[parsecountmod].playerstate[block.playernum];
|
state->number = num;
|
||||||
|
flags = state->flags = MSG_ReadShort (net_message);
|
||||||
state->number = block.playernum;
|
|
||||||
state->flags = block.flags;
|
|
||||||
|
|
||||||
state->messagenum = cl.parsecount;
|
state->messagenum = cl.parsecount;
|
||||||
VectorCopy (block.origin, state->origin);
|
state->origin[0] = MSG_ReadCoord (net_message);
|
||||||
|
state->origin[1] = MSG_ReadCoord (net_message);
|
||||||
|
state->origin[2] = MSG_ReadCoord (net_message);
|
||||||
|
|
||||||
state->frame = block.frame;
|
state->frame = MSG_ReadByte (net_message);
|
||||||
|
|
||||||
// the other player's last move was likely some time
|
// the other player's last move was likely some time
|
||||||
// before the packet was sent out, so accurately track
|
// before the packet was sent out, so accurately track
|
||||||
// the exact time it was valid at
|
// the exact time it was valid at
|
||||||
state->state_time = parsecounttime - block.msec * 0.001;
|
if (flags & PF_MSEC) {
|
||||||
|
msec = MSG_ReadByte (net_message);
|
||||||
|
state->state_time = parsecounttime - msec * 0.001;
|
||||||
|
} else
|
||||||
|
state->state_time = parsecounttime;
|
||||||
|
|
||||||
if (block.flags & PF_COMMAND)
|
if (flags & PF_COMMAND)
|
||||||
memcpy (&state->command, &block.usercmd, sizeof (state->command));
|
MSG_ReadDeltaUsercmd (&nullcmd, &state->command);
|
||||||
|
|
||||||
VectorCopy (block.velocity, state->velocity);
|
for (i = 0; i < 3; i++) {
|
||||||
|
if (flags & (PF_VELOCITY1 << i))
|
||||||
if (block.flags & PF_MODEL)
|
state->velocity[i] = MSG_ReadShort (net_message);
|
||||||
state->modelindex = block.modelindex;
|
else
|
||||||
|
state->velocity[i] = 0;
|
||||||
|
}
|
||||||
|
if (flags & PF_MODEL)
|
||||||
|
state->modelindex = MSG_ReadByte (net_message);
|
||||||
else
|
else
|
||||||
state->modelindex = cl_playerindex;
|
state->modelindex = cl_playerindex;
|
||||||
|
|
||||||
state->skinnum = block.skinnum;
|
if (flags & PF_SKINNUM)
|
||||||
state->effects = block.effects;
|
state->skinnum = MSG_ReadByte (net_message);
|
||||||
state->weaponframe = block.weaponframe;
|
else
|
||||||
|
state->skinnum = 0;
|
||||||
|
|
||||||
|
if (flags & PF_EFFECTS)
|
||||||
|
state->effects = MSG_ReadByte (net_message);
|
||||||
|
else
|
||||||
|
state->effects = 0;
|
||||||
|
|
||||||
|
if (flags & PF_WEAPONFRAME)
|
||||||
|
state->weaponframe = MSG_ReadByte (net_message);
|
||||||
|
else
|
||||||
|
state->weaponframe = 0;
|
||||||
|
|
||||||
VectorCopy (state->command.angles, state->viewangles);
|
VectorCopy (state->command.angles, state->viewangles);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1318,34 +1318,6 @@ Host_EndGame (const char *message, ...)
|
||||||
longjmp (host_abort, 1);
|
longjmp (host_abort, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Host_NetError
|
|
||||||
|
|
||||||
Used for networking errors that disconnect, but don't exit the
|
|
||||||
client
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
Host_NetError (const char *message, ...)
|
|
||||||
{
|
|
||||||
va_list argptr;
|
|
||||||
int old = 0;
|
|
||||||
|
|
||||||
old = net_packetlog->int_val;
|
|
||||||
if (net_packetlog->int_val)
|
|
||||||
Cvar_Set (net_packetlog, "0");
|
|
||||||
Log_Incoming_Packet (net_message->message->data,
|
|
||||||
net_message->message->cursize);
|
|
||||||
if (old)
|
|
||||||
Cvar_SetValue (net_packetlog, old);
|
|
||||||
|
|
||||||
va_start (argptr, message);
|
|
||||||
Host_EndGame (message, argptr);
|
|
||||||
Con_Printf ("%s", "Please report this to "
|
|
||||||
"quake-devel@lists.sourceforge.net, including the "
|
|
||||||
"packet log printed out above\n");
|
|
||||||
va_end (argptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Host_Error
|
Host_Error
|
||||||
|
|
||||||
|
|
1230
qw/source/cl_parse.c
1230
qw/source/cl_parse.c
File diff suppressed because it is too large
Load diff
|
@ -206,7 +206,7 @@ CL_NewTranslation (int slot, skin_t *skin)
|
||||||
player_info_t *player;
|
player_info_t *player;
|
||||||
|
|
||||||
if (slot > MAX_CLIENTS)
|
if (slot > MAX_CLIENTS)
|
||||||
Host_NetError ("CL_NewTranslation: slot > MAX_CLIENTS");
|
Host_EndGame ("CL_NewTranslation: slot > MAX_CLIENTS");
|
||||||
|
|
||||||
player = &cl.players[slot];
|
player = &cl.players[slot];
|
||||||
if (!player->name[0])
|
if (!player->name[0])
|
||||||
|
|
|
@ -50,8 +50,6 @@ static const char rcsid[] =
|
||||||
#include "cl_main.h"
|
#include "cl_main.h"
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "host.h"
|
|
||||||
#include "net_svc.h"
|
|
||||||
#include "r_dynamic.h"
|
#include "r_dynamic.h"
|
||||||
|
|
||||||
#define MAX_BEAMS 8
|
#define MAX_BEAMS 8
|
||||||
|
@ -184,37 +182,42 @@ CL_AllocExplosion (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CL_ParseBeam (net_svc_tempentity_t *tempentity, model_t *m)
|
CL_ParseBeam (model_t *m)
|
||||||
{
|
{
|
||||||
beam_t *b;
|
beam_t *b;
|
||||||
int i;
|
int ent, i;
|
||||||
|
vec3_t start, end;
|
||||||
|
|
||||||
if (tempentity->beamentity >= MAX_EDICTS) {
|
ent = MSG_ReadShort (net_message);
|
||||||
Host_NetError ("CL_ParseBeam: beamentity %i >= MAX_EDICTS",
|
|
||||||
tempentity->beamentity);
|
start[0] = MSG_ReadCoord (net_message);
|
||||||
return;
|
start[1] = MSG_ReadCoord (net_message);
|
||||||
}
|
start[2] = MSG_ReadCoord (net_message);
|
||||||
|
|
||||||
|
end[0] = MSG_ReadCoord (net_message);
|
||||||
|
end[1] = MSG_ReadCoord (net_message);
|
||||||
|
end[2] = MSG_ReadCoord (net_message);
|
||||||
|
|
||||||
// override any beam with the same entity
|
// override any beam with the same entity
|
||||||
for (i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++)
|
for (i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++)
|
||||||
if (b->entity == tempentity->beamentity) {
|
if (b->entity == ent) {
|
||||||
b->entity = tempentity->beamentity;
|
b->entity = ent;
|
||||||
b->model = m;
|
b->model = m;
|
||||||
b->endtime = cl.time + 0.2;
|
b->endtime = cl.time + 0.2;
|
||||||
b->seed = rand();
|
b->seed = rand();
|
||||||
VectorCopy (tempentity->position, b->start);
|
VectorCopy (start, b->start);
|
||||||
VectorCopy (tempentity->beamend, b->end);
|
VectorCopy (end, b->end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// find a free beam
|
// find a free beam
|
||||||
for (i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++) {
|
for (i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++) {
|
||||||
if (!b->model || b->endtime < cl.time) {
|
if (!b->model || b->endtime < cl.time) {
|
||||||
b->entity = tempentity->beamentity;
|
b->entity = ent;
|
||||||
b->model = m;
|
b->model = m;
|
||||||
b->endtime = cl.time + 0.2;
|
b->endtime = cl.time + 0.2;
|
||||||
b->seed = rand();
|
b->seed = rand();
|
||||||
VectorCopy (tempentity->position, b->start);
|
VectorCopy (start, b->start);
|
||||||
VectorCopy (tempentity->beamend, b->end);
|
VectorCopy (end, b->end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,66 +227,79 @@ CL_ParseBeam (net_svc_tempentity_t *tempentity, model_t *m)
|
||||||
void
|
void
|
||||||
CL_ParseTEnt (void)
|
CL_ParseTEnt (void)
|
||||||
{
|
{
|
||||||
|
byte type;
|
||||||
dlight_t *dl;
|
dlight_t *dl;
|
||||||
explosion_t *ex;
|
explosion_t *ex;
|
||||||
int rnd;
|
int colorStart, colorLength, rnd;
|
||||||
net_svc_tempentity_t tempentity;
|
int cnt = -1;
|
||||||
|
vec3_t pos;
|
||||||
|
|
||||||
if (NET_SVC_TempEntity_Parse (&tempentity, net_message)) {
|
type = MSG_ReadByte (net_message);
|
||||||
Host_NetError ("CL_ParseTEnt: Bad Read\n");
|
switch (type) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (tempentity.type) {
|
|
||||||
case TE_WIZSPIKE: // spike hitting wall
|
case TE_WIZSPIKE: // spike hitting wall
|
||||||
R_RunSpikeEffect (tempentity.position, prot_to_rend[tempentity.type]);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
S_StartSound (-1, 0, cl_sfx_wizhit, tempentity.position, 1, 1);
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_RunSpikeEffect (pos, prot_to_rend[type]);
|
||||||
|
S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_KNIGHTSPIKE: // spike hitting wall
|
case TE_KNIGHTSPIKE: // spike hitting wall
|
||||||
R_RunSpikeEffect (tempentity.position, prot_to_rend[tempentity.type]);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
S_StartSound (-1, 0, cl_sfx_knighthit, tempentity.position, 1, 1);
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_RunSpikeEffect (pos, prot_to_rend[type]);
|
||||||
|
S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_SPIKE: // spike hitting wall
|
case TE_SPIKE: // spike hitting wall
|
||||||
R_RunSpikeEffect (tempentity.position, prot_to_rend[tempentity.type]);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_RunSpikeEffect (pos, prot_to_rend[type]);
|
||||||
|
|
||||||
if (rand () % 5)
|
if (rand () % 5)
|
||||||
S_StartSound (-1, 0, cl_sfx_tink1, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
|
||||||
else {
|
else {
|
||||||
rnd = rand () & 3;
|
rnd = rand () & 3;
|
||||||
if (rnd == 1)
|
if (rnd == 1)
|
||||||
S_StartSound (-1, 0, cl_sfx_ric1, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
|
||||||
else if (rnd == 2)
|
else if (rnd == 2)
|
||||||
S_StartSound (-1, 0, cl_sfx_ric2, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
|
||||||
else
|
else
|
||||||
S_StartSound (-1, 0, cl_sfx_ric3, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_SUPERSPIKE: // super spike hitting wall
|
case TE_SUPERSPIKE: // super spike hitting wall
|
||||||
R_RunSpikeEffect (tempentity.position, prot_to_rend[tempentity.type]);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_RunSpikeEffect (pos, prot_to_rend[type]);
|
||||||
|
|
||||||
if (rand () % 5)
|
if (rand () % 5)
|
||||||
S_StartSound (-1, 0, cl_sfx_tink1, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
|
||||||
else {
|
else {
|
||||||
rnd = rand () & 3;
|
rnd = rand () & 3;
|
||||||
if (rnd == 1)
|
if (rnd == 1)
|
||||||
S_StartSound (-1, 0, cl_sfx_ric1, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
|
||||||
else if (rnd == 2)
|
else if (rnd == 2)
|
||||||
S_StartSound (-1, 0, cl_sfx_ric2, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
|
||||||
else
|
else
|
||||||
S_StartSound (-1, 0, cl_sfx_ric3, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_EXPLOSION: // rocket explosion
|
case TE_EXPLOSION: // rocket explosion
|
||||||
// particles
|
// particles
|
||||||
R_ParticleExplosion (tempentity.position);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_ParticleExplosion (pos);
|
||||||
|
|
||||||
// light
|
// light
|
||||||
dl = R_AllocDlight (0);
|
dl = R_AllocDlight (0);
|
||||||
VectorCopy (tempentity.position, dl->origin);
|
VectorCopy (pos, dl->origin);
|
||||||
dl->radius = 350;
|
dl->radius = 350;
|
||||||
dl->die = cl.time + 0.5;
|
dl->die = cl.time + 0.5;
|
||||||
dl->decay = 300;
|
dl->decay = 300;
|
||||||
|
@ -292,78 +308,94 @@ CL_ParseTEnt (void)
|
||||||
dl->color[2] = 0.24;
|
dl->color[2] = 0.24;
|
||||||
|
|
||||||
// sound
|
// sound
|
||||||
S_StartSound (-1, 0, cl_sfx_r_exp3, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
|
||||||
|
|
||||||
// sprite
|
// sprite
|
||||||
ex = CL_AllocExplosion ();
|
ex = CL_AllocExplosion ();
|
||||||
VectorCopy (tempentity.position, ex->ent.origin);
|
VectorCopy (pos, ex->ent.origin);
|
||||||
ex->start = cl.time;
|
ex->start = cl.time;
|
||||||
ex->ent.model = cl_spr_explod;
|
ex->ent.model = cl_spr_explod;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_TAREXPLOSION: // tarbaby explosion
|
case TE_TAREXPLOSION: // tarbaby explosion
|
||||||
R_BlobExplosion (tempentity.position);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_BlobExplosion (pos);
|
||||||
|
|
||||||
S_StartSound (-1, 0, cl_sfx_r_exp3, tempentity.position, 1, 1);
|
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_LIGHTNING1: // lightning bolts
|
case TE_LIGHTNING1: // lightning bolts
|
||||||
CL_ParseBeam (&tempentity, cl_mod_bolt);
|
CL_ParseBeam (cl_mod_bolt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_LIGHTNING2: // lightning bolts
|
case TE_LIGHTNING2: // lightning bolts
|
||||||
CL_ParseBeam (&tempentity, cl_mod_bolt2);
|
CL_ParseBeam (cl_mod_bolt2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_LIGHTNING3: // lightning bolts
|
case TE_LIGHTNING3: // lightning bolts
|
||||||
CL_ParseBeam (&tempentity, cl_mod_bolt3);
|
CL_ParseBeam (cl_mod_bolt3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// PGM 01/21/97
|
// PGM 01/21/97
|
||||||
case TE_BEAM: // grappling hook beam
|
case TE_BEAM: // grappling hook beam
|
||||||
CL_ParseBeam (&tempentity, Mod_ForName ("progs/beam.mdl", true));
|
CL_ParseBeam (Mod_ForName ("progs/beam.mdl", true));
|
||||||
break;
|
break;
|
||||||
// PGM 01/21/97
|
// PGM 01/21/97
|
||||||
|
|
||||||
case TE_LAVASPLASH:
|
case TE_LAVASPLASH:
|
||||||
R_LavaSplash (tempentity.position);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_LavaSplash (pos);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_TELEPORT:
|
case TE_TELEPORT:
|
||||||
R_TeleportSplash (tempentity.position);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_TeleportSplash (pos);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_EXPLOSION2: // color mapped explosion
|
case TE_EXPLOSION2: // color mapped explosion
|
||||||
R_ParticleExplosion2 (tempentity.position,
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
tempentity.colorstart,
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
tempentity.colorlength);
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
colorStart = MSG_ReadByte (net_message);
|
||||||
|
colorLength = MSG_ReadByte (net_message);
|
||||||
|
R_ParticleExplosion2 (pos, colorStart, colorLength);
|
||||||
dl = R_AllocDlight (0);
|
dl = R_AllocDlight (0);
|
||||||
VectorCopy (tempentity.position, dl->origin);
|
VectorCopy (pos, dl->origin);
|
||||||
dl->radius = 350;
|
dl->radius = 350;
|
||||||
dl->die = cl.time + 0.5;
|
dl->die = cl.time + 0.5;
|
||||||
dl->decay = 300;
|
dl->decay = 300;
|
||||||
dl->color[0] = vid_basepal[(tempentity.colorstart
|
dl->color[0] = vid_basepal[(colorStart + (rand() % colorLength)) *
|
||||||
+ (rand() % tempentity.colorlength))
|
3] * (1.0 / 255.0);
|
||||||
* 3] * (1.0 / 255.0);
|
dl->color[1] = vid_basepal[(colorStart + (rand() % colorLength)) *
|
||||||
dl->color[1] = vid_basepal[(tempentity.colorstart
|
3 + 1] * (1.0 / 255.0);
|
||||||
+ (rand() % tempentity.colorlength))
|
dl->color[2] = vid_basepal[(colorStart + (rand() % colorLength)) *
|
||||||
* 3 + 1] * (1.0 / 255.0);
|
3 + 2] * (1.0 / 255.0);
|
||||||
dl->color[2] = vid_basepal[(tempentity.colorstart
|
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
|
||||||
+ (rand() % tempentity.colorlength))
|
|
||||||
* 3 + 2] * (1.0 / 255.0);
|
|
||||||
S_StartSound (-1, 0, cl_sfx_r_exp3, tempentity.position, 1, 1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_GUNSHOT: // bullet hitting wall
|
case TE_GUNSHOT: // bullet hitting wall
|
||||||
case TE_BLOOD: // bullets hitting body
|
case TE_BLOOD: // bullets hitting body
|
||||||
R_RunPuffEffect (tempentity.position, prot_to_rend[tempentity.type],
|
cnt = MSG_ReadByte (net_message) * 20;
|
||||||
tempentity.gunshotcount * 20);
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
R_RunPuffEffect (pos, prot_to_rend[type], cnt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_LIGHTNINGBLOOD: // lightning hitting body
|
case TE_LIGHTNINGBLOOD: // lightning hitting body
|
||||||
|
pos[0] = MSG_ReadCoord (net_message);
|
||||||
|
pos[1] = MSG_ReadCoord (net_message);
|
||||||
|
pos[2] = MSG_ReadCoord (net_message);
|
||||||
|
|
||||||
// light
|
// light
|
||||||
dl = R_AllocDlight (0);
|
dl = R_AllocDlight (0);
|
||||||
VectorCopy (tempentity.position, dl->origin);
|
VectorCopy (pos, dl->origin);
|
||||||
dl->radius = 150;
|
dl->radius = 150;
|
||||||
dl->die = cl.time + 0.1;
|
dl->die = cl.time + 0.1;
|
||||||
dl->decay = 200;
|
dl->decay = 200;
|
||||||
|
@ -371,11 +403,11 @@ CL_ParseTEnt (void)
|
||||||
dl->color[1] = 0.40;
|
dl->color[1] = 0.40;
|
||||||
dl->color[2] = 0.65;
|
dl->color[2] = 0.65;
|
||||||
|
|
||||||
R_RunPuffEffect (tempentity.position, prot_to_rend[tempentity.type], 0);
|
R_RunPuffEffect (pos, prot_to_rend[type], cnt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Sys_Error ("CL_ParseTEnt: bad tempentity.type %i", tempentity.type);
|
Sys_Error ("CL_ParseTEnt: bad type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ static const char rcsid[] =
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "pmove.h"
|
#include "pmove.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
|
||||||
|
@ -241,18 +240,18 @@ V_DriftPitch (void)
|
||||||
/* PALETTE FLASHES */
|
/* PALETTE FLASHES */
|
||||||
|
|
||||||
void
|
void
|
||||||
CL_ParseDamage (void)
|
V_ParseDamage (void)
|
||||||
{
|
{
|
||||||
float count, side;
|
float count, side;
|
||||||
vec3_t forward, right, up;
|
int armor, blood, i;
|
||||||
net_svc_damage_t damage;
|
vec3_t forward, from, right, up;
|
||||||
|
|
||||||
if (NET_SVC_Damage_Parse (&damage, net_message)) {
|
armor = MSG_ReadByte (net_message);
|
||||||
Host_NetError ("CL_ParseDamage: Bad Read\n");
|
blood = MSG_ReadByte (net_message);
|
||||||
return;
|
for (i = 0; i < 3; i++)
|
||||||
}
|
from[i] = MSG_ReadCoord (net_message);
|
||||||
|
|
||||||
count = damage.blood * 0.5 + damage.armor * 0.5;
|
count = blood * 0.5 + armor * 0.5;
|
||||||
if (count < 10)
|
if (count < 10)
|
||||||
count = 10;
|
count = 10;
|
||||||
|
|
||||||
|
@ -266,11 +265,11 @@ CL_ParseDamage (void)
|
||||||
cl.cshifts[CSHIFT_DAMAGE].percent =
|
cl.cshifts[CSHIFT_DAMAGE].percent =
|
||||||
bound (0, cl.cshifts[CSHIFT_DAMAGE].percent, 150);
|
bound (0, cl.cshifts[CSHIFT_DAMAGE].percent, 150);
|
||||||
|
|
||||||
if (damage.armor > damage.blood) {
|
if (armor > blood) {
|
||||||
cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200;
|
cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200;
|
||||||
cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100;
|
cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100;
|
||||||
cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100;
|
cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100;
|
||||||
} else if (damage.armor) {
|
} else if (armor) {
|
||||||
cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220;
|
cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220;
|
||||||
cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50;
|
cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50;
|
||||||
cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50;
|
cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50;
|
||||||
|
@ -282,15 +281,15 @@ CL_ParseDamage (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate view angle kicks
|
// calculate view angle kicks
|
||||||
VectorSubtract (damage.from, cl.simorg, damage.from);
|
VectorSubtract (from, cl.simorg, from);
|
||||||
VectorNormalize (damage.from);
|
VectorNormalize (from);
|
||||||
|
|
||||||
AngleVectors (cl.simangles, forward, right, up);
|
AngleVectors (cl.simangles, forward, right, up);
|
||||||
|
|
||||||
side = DotProduct (damage.from, right);
|
side = DotProduct (from, right);
|
||||||
v_dmg_roll = count * side * v_kickroll->value;
|
v_dmg_roll = count * side * v_kickroll->value;
|
||||||
|
|
||||||
side = DotProduct (damage.from, forward);
|
side = DotProduct (from, forward);
|
||||||
v_dmg_pitch = count * side * v_kickpitch->value;
|
v_dmg_pitch = count * side * v_kickpitch->value;
|
||||||
|
|
||||||
v_dmg_time = v_kicktime->value;
|
v_dmg_time = v_kicktime->value;
|
||||||
|
|
|
@ -56,7 +56,6 @@ static const char rcsid[] =
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
|
@ -71,6 +70,81 @@ void Parse_Server_Packet (void);
|
||||||
void Parse_Client_Packet (void);
|
void Parse_Client_Packet (void);
|
||||||
void Net_LogStop (void);
|
void Net_LogStop (void);
|
||||||
|
|
||||||
|
// note: this is SUPPOSED to be duplicate, like many others
|
||||||
|
const char *svc_string[] = {
|
||||||
|
"svc_bad",
|
||||||
|
"svc_nop",
|
||||||
|
"svc_disconnect",
|
||||||
|
"svc_updatestat",
|
||||||
|
"svc_version", // [long] server version
|
||||||
|
"svc_setview", // [short] entity number
|
||||||
|
"svc_sound", // <see code>
|
||||||
|
"svc_time", // [float] server time
|
||||||
|
"svc_print", // [string] null terminated string
|
||||||
|
"svc_stufftext", // [string] stuffed into client's
|
||||||
|
// console buffer the string
|
||||||
|
// should be \n terminated
|
||||||
|
"svc_setangle", // [vec3] set the view angle to this
|
||||||
|
// absolute value
|
||||||
|
"svc_serverdata", // [long] version ...
|
||||||
|
"svc_lightstyle", // [byte] [string]
|
||||||
|
"svc_updatename", // [byte] [string]
|
||||||
|
"svc_updatefrags", // [byte] [short]
|
||||||
|
"svc_clientdata", // <shortbits + data>
|
||||||
|
"svc_stopsound", // <see code>
|
||||||
|
"svc_updatecolors", // [byte] [byte]
|
||||||
|
"svc_particle", // [vec3] <variable>
|
||||||
|
"svc_damage", // [byte] impact [byte] blood [vec3]
|
||||||
|
// from
|
||||||
|
"svc_spawnstatic",
|
||||||
|
"svc_spawnbinary",
|
||||||
|
"svc_spawnbaseline",
|
||||||
|
"svc_temp_entity", // <variable>
|
||||||
|
"svc_setpause",
|
||||||
|
"svc_signonnum",
|
||||||
|
"svc_centerprint",
|
||||||
|
"svc_killedmonster",
|
||||||
|
"svc_foundsecret",
|
||||||
|
"svc_spawnstaticsound",
|
||||||
|
"svc_intermission",
|
||||||
|
"svc_finale", // [string] music [string] text
|
||||||
|
"svc_cdtrack", // [byte] track [byte] looptrack
|
||||||
|
"svc_sellscreen",
|
||||||
|
"svc_smallkick", // Quake svc_cutscene
|
||||||
|
"svc_bigkick",
|
||||||
|
"svc_updateping",
|
||||||
|
"svc_updateentertime",
|
||||||
|
"svc_updatestatlong",
|
||||||
|
"svc_muzzleflash",
|
||||||
|
"svc_updateuserinfo",
|
||||||
|
"svc_download",
|
||||||
|
"svc_playerinfo",
|
||||||
|
"svc_nails",
|
||||||
|
"svc_chokecount",
|
||||||
|
"svc_modellist",
|
||||||
|
"svc_soundlist",
|
||||||
|
"svc_packetentities",
|
||||||
|
"svc_deltapacketentities",
|
||||||
|
"svc_maxspeed",
|
||||||
|
"svc_entgravity",
|
||||||
|
"svc_setinfo",
|
||||||
|
"svc_serverinfo",
|
||||||
|
"svc_updatepl",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL",
|
||||||
|
"NEW PROTOCOL"
|
||||||
|
};
|
||||||
|
|
||||||
const char *clc_string[] = {
|
const char *clc_string[] = {
|
||||||
"clc_bad",
|
"clc_bad",
|
||||||
"clc_nop",
|
"clc_nop",
|
||||||
|
@ -95,6 +169,7 @@ const char *clc_string[] = {
|
||||||
#define svc_particle 18 // [vec3] <variable>
|
#define svc_particle 18 // [vec3] <variable>
|
||||||
#define svc_signonnum 25 // [byte] used for the signon
|
#define svc_signonnum 25 // [byte] used for the signon
|
||||||
// sequence
|
// sequence
|
||||||
|
static VFile *_stdout;
|
||||||
static VFile *Net_PacketLog;
|
static VFile *Net_PacketLog;
|
||||||
static const char **Net_sound_precache;
|
static const char **Net_sound_precache;
|
||||||
static sizebuf_t _packet;
|
static sizebuf_t _packet;
|
||||||
|
@ -115,12 +190,11 @@ Net_LogPrintf (char *fmt, ...)
|
||||||
va_start (argptr, fmt);
|
va_start (argptr, fmt);
|
||||||
vsnprintf (text, sizeof (text), fmt, argptr);
|
vsnprintf (text, sizeof (text), fmt, argptr);
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
if (!Net_PacketLog)
|
||||||
|
return;
|
||||||
|
|
||||||
if (Net_PacketLog) {
|
|
||||||
Qprintf (Net_PacketLog, "%s", text);
|
Qprintf (Net_PacketLog, "%s", text);
|
||||||
Qflush (Net_PacketLog);
|
Qflush (Net_PacketLog);
|
||||||
} else
|
|
||||||
Con_Printf ("%s", text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -230,43 +304,30 @@ Log_Outgoing_Packet (const char *p, int len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean
|
void
|
||||||
Log_Delta(int bits)
|
Log_Delta(int bits)
|
||||||
{
|
{
|
||||||
entity_state_t to;
|
entity_state_t to;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Net_LogPrintf ("\n\t<%06x> ", MSG_GetReadCount (&packet) - 2);
|
Net_LogPrintf ("\n\t");
|
||||||
if (!bits) {
|
|
||||||
Net_LogPrintf ("End");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set everything to the state we are delta'ing from
|
// set everything to the state we are delta'ing from
|
||||||
|
|
||||||
to.number = bits & 511;
|
to.number = bits & 511;
|
||||||
bits &= ~511;
|
bits &= ~511;
|
||||||
|
|
||||||
Net_LogPrintf ("Ent: %d", to.number);
|
|
||||||
|
|
||||||
if (bits & U_REMOVE)
|
|
||||||
Net_LogPrintf (" U_REMOVE");
|
|
||||||
|
|
||||||
if (bits & U_MOREBITS) { // read in the low order bits
|
if (bits & U_MOREBITS) { // read in the low order bits
|
||||||
i = MSG_ReadByte (&packet);
|
i = MSG_ReadByte (&packet);
|
||||||
bits |= i;
|
bits |= i;
|
||||||
Net_LogPrintf (" U_MOREBITS");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LordHavoc: Endy neglected to mark this as being part of the QSG
|
// LordHavoc: Endy neglected to mark this as being part of the QSG
|
||||||
// version 2 stuff...
|
// version 2 stuff...
|
||||||
if (bits & U_EXTEND1) {
|
if (bits & U_EXTEND1) {
|
||||||
bits |= MSG_ReadByte (&packet) << 16;
|
bits |= MSG_ReadByte (&packet) << 16;
|
||||||
Net_LogPrintf (" U_EXTEND1");
|
if (bits & U_EXTEND2)
|
||||||
if (bits & U_EXTEND2) {
|
|
||||||
bits |= MSG_ReadByte (&packet) << 24;
|
bits |= MSG_ReadByte (&packet) << 24;
|
||||||
Net_LogPrintf (" U_EXTEND2");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
to.flags = bits;
|
to.flags = bits;
|
||||||
|
@ -325,7 +386,7 @@ Log_Delta(int bits)
|
||||||
Net_LogPrintf(" Uframe2: %d", ((to.frame & 0xFF) | (MSG_ReadByte (&packet) << 8)));
|
Net_LogPrintf(" Uframe2: %d", ((to.frame & 0xFF) | (MSG_ReadByte (&packet) << 8)));
|
||||||
// Ender (QSG - End)
|
// Ender (QSG - End)
|
||||||
|
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,10 +394,14 @@ Log_Delta(int bits)
|
||||||
void
|
void
|
||||||
Analyze_Server_Packet (const byte * data, int len)
|
Analyze_Server_Packet (const byte * data, int len)
|
||||||
{
|
{
|
||||||
|
if (!Net_PacketLog)
|
||||||
|
Net_PacketLog = _stdout;
|
||||||
packet.message->data = (byte*)data;
|
packet.message->data = (byte*)data;
|
||||||
packet.message->cursize = len;
|
packet.message->cursize = len;
|
||||||
MSG_BeginReading (&packet);
|
MSG_BeginReading (&packet);
|
||||||
Parse_Server_Packet ();
|
Parse_Server_Packet ();
|
||||||
|
if (Net_PacketLog == _stdout)
|
||||||
|
Net_PacketLog = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -373,11 +438,10 @@ Parse_Server_Packet ()
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
// Net_LogPrintf("\n<%ld,%ld> ",seq1 & 0x7FFFFFFF,seq2 & 0x7FFFFFFF);
|
// Net_LogPrintf("\n<%ld,%ld> ",seq1 & 0x7FFFFFFF,seq2 & 0x7FFFFFFF);
|
||||||
Net_LogPrintf ("<%06x> [0x%02x] ",
|
Net_LogPrintf ("<%06x> [0x%02x] ", MSG_GetReadCount (&packet), c);
|
||||||
MSG_GetReadCount (&packet) - 1, c);
|
|
||||||
|
|
||||||
if (c < 53)
|
if (c < 53)
|
||||||
Net_LogPrintf ("%s: ", NET_SVC_GetString (c));
|
Net_LogPrintf ("%s: ", svc_string[c]);
|
||||||
// else Net_LogPrintf("(UNK: %d): ",c);
|
// else Net_LogPrintf("(UNK: %d): ",c);
|
||||||
|
|
||||||
if (MSG_GetReadCount (&packet) > packet.message->cursize)
|
if (MSG_GetReadCount (&packet) > packet.message->cursize)
|
||||||
|
@ -559,7 +623,7 @@ Parse_Server_Packet ()
|
||||||
Net_LogPrintf ("**QW OBSOLETE**");
|
Net_LogPrintf ("**QW OBSOLETE**");
|
||||||
break;
|
break;
|
||||||
case svc_centerprint:
|
case svc_centerprint:
|
||||||
Net_LogPrintf ("%s", MSG_ReadString (&packet));
|
Net_LogPrintf ("%s\n", MSG_ReadString (&packet));
|
||||||
break;
|
break;
|
||||||
case svc_killedmonster:
|
case svc_killedmonster:
|
||||||
break;
|
break;
|
||||||
|
@ -730,9 +794,6 @@ Parse_Server_Packet ()
|
||||||
else
|
else
|
||||||
Net_LogPrintf ("\n\t*End of sound list*");
|
Net_LogPrintf ("\n\t*End of sound list*");
|
||||||
break;
|
break;
|
||||||
case svc_deltapacketentities:
|
|
||||||
Net_LogPrintf ("from: %d", MSG_ReadByte (&packet));
|
|
||||||
// intentional fallthrough
|
|
||||||
case svc_packetentities:
|
case svc_packetentities:
|
||||||
while (1) {
|
while (1) {
|
||||||
mask1 = (unsigned short) MSG_ReadShort(&packet);
|
mask1 = (unsigned short) MSG_ReadShort(&packet);
|
||||||
|
@ -740,10 +801,15 @@ Parse_Server_Packet ()
|
||||||
Net_LogPrintf ("Badread\n");
|
Net_LogPrintf ("Badread\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Log_Delta(mask1))
|
if (!mask1) break;
|
||||||
break;
|
if (mask1 & U_REMOVE) Net_LogPrintf("UREMOVE ");
|
||||||
|
Log_Delta(mask1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case svc_deltapacketentities:
|
||||||
|
Net_LogPrintf ("idx: %d", MSG_ReadByte (&packet));
|
||||||
|
return;
|
||||||
|
break;
|
||||||
case svc_maxspeed:
|
case svc_maxspeed:
|
||||||
Net_LogPrintf ("%f", MSG_ReadFloat (&packet));
|
Net_LogPrintf ("%f", MSG_ReadFloat (&packet));
|
||||||
break;
|
break;
|
||||||
|
@ -775,10 +841,14 @@ Parse_Server_Packet ()
|
||||||
void
|
void
|
||||||
Analyze_Client_Packet (const byte * data, int len)
|
Analyze_Client_Packet (const byte * data, int len)
|
||||||
{
|
{
|
||||||
|
if (!Net_PacketLog)
|
||||||
|
Net_PacketLog = _stdout;
|
||||||
packet.message->data = (byte*)data;
|
packet.message->data = (byte*)data;
|
||||||
packet.message->cursize = len;
|
packet.message->cursize = len;
|
||||||
MSG_BeginReading (&packet);
|
MSG_BeginReading (&packet);
|
||||||
Parse_Client_Packet ();
|
Parse_Client_Packet ();
|
||||||
|
if (Net_PacketLog == _stdout)
|
||||||
|
Net_PacketLog = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -892,7 +962,7 @@ Net_PacketLog_f (cvar_t *var)
|
||||||
void
|
void
|
||||||
Net_PacketLog_Zap_f (void)
|
Net_PacketLog_Zap_f (void)
|
||||||
{
|
{
|
||||||
if (Net_PacketLog) {
|
if (Net_PacketLog && Net_PacketLog != _stdout) {
|
||||||
Con_Printf ("truncating packet logfile: %s\n", "qfpacket.log");
|
Con_Printf ("truncating packet logfile: %s\n", "qfpacket.log");
|
||||||
Qseek (Net_PacketLog, 0, 0);
|
Qseek (Net_PacketLog, 0, 0);
|
||||||
Qwrite (Net_PacketLog, 0, 0);
|
Qwrite (Net_PacketLog, 0, 0);
|
||||||
|
@ -910,6 +980,8 @@ Net_Log_Init (const char **sound_precache)
|
||||||
{
|
{
|
||||||
Net_sound_precache = sound_precache;
|
Net_sound_precache = sound_precache;
|
||||||
|
|
||||||
|
_stdout = Qdopen (1, "wt"); // create a QFile of stdout
|
||||||
|
|
||||||
net_packetlog = Cvar_Get ("net_packetlog", "0", CVAR_NONE, Net_PacketLog_f,
|
net_packetlog = Cvar_Get ("net_packetlog", "0", CVAR_NONE, Net_PacketLog_f,
|
||||||
"enable/disable packet logging");
|
"enable/disable packet logging");
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,6 @@ static const char rcsid[] =
|
||||||
|
|
||||||
#include "bothdefs.h"
|
#include "bothdefs.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "sv_progs.h"
|
#include "sv_progs.h"
|
||||||
|
|
||||||
|
@ -830,15 +829,12 @@ SV_Heartbeat_f (void)
|
||||||
void
|
void
|
||||||
SV_SendServerInfoChange (const char *key, const char *value)
|
SV_SendServerInfoChange (const char *key, const char *value)
|
||||||
{
|
{
|
||||||
net_svc_serverinfo_t block;
|
|
||||||
|
|
||||||
if (!sv.state)
|
if (!sv.state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
block.key = key;
|
|
||||||
block.value = value;
|
|
||||||
MSG_WriteByte (&sv.reliable_datagram, svc_serverinfo);
|
MSG_WriteByte (&sv.reliable_datagram, svc_serverinfo);
|
||||||
NET_SVC_ServerInfo_Emit (&block, &sv.reliable_datagram);
|
MSG_WriteString (&sv.reliable_datagram, key);
|
||||||
|
MSG_WriteString (&sv.reliable_datagram, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -42,7 +42,6 @@ static const char rcsid[] =
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "msg_ucmd.h"
|
#include "msg_ucmd.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "sv_progs.h"
|
#include "sv_progs.h"
|
||||||
|
|
||||||
|
@ -126,29 +125,51 @@ SV_AddNailUpdate (edict_t *ent)
|
||||||
void
|
void
|
||||||
SV_EmitNailUpdate (sizebuf_t *msg)
|
SV_EmitNailUpdate (sizebuf_t *msg)
|
||||||
{
|
{
|
||||||
int i;
|
byte bits[6]; // [48 bits] xyzpy 12 12 12 4 8
|
||||||
net_svc_nails_t block;
|
int i, n, p, x, y, z, yaw;
|
||||||
|
edict_t *ent;
|
||||||
|
|
||||||
if (!numnails)
|
if (!numnails)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
block.numnails = numnails;
|
|
||||||
|
|
||||||
for (i = 0; i < numnails; i++) {
|
|
||||||
VectorCopy (SVvector (nails[i], origin), block.nails[i].origin);
|
|
||||||
VectorCopy (SVvector (nails[i], angles), block.nails[i].angles);
|
|
||||||
}
|
|
||||||
|
|
||||||
MSG_WriteByte (msg, svc_nails);
|
MSG_WriteByte (msg, svc_nails);
|
||||||
NET_SVC_Nails_Emit (&block, msg);
|
MSG_WriteByte (msg, numnails);
|
||||||
|
|
||||||
|
for (n = 0; n < numnails; n++) {
|
||||||
|
ent = nails[n];
|
||||||
|
x = (int) (SVvector (ent, origin)[0] + 4096) >> 1;
|
||||||
|
y = (int) (SVvector (ent, origin)[1] + 4096) >> 1;
|
||||||
|
z = (int) (SVvector (ent, origin)[2] + 4096) >> 1;
|
||||||
|
p = (int) (16 * SVvector (ent, angles)[0] / 360) & 15;
|
||||||
|
yaw = (int) (256 * SVvector (ent, angles)[1] / 360) & 255;
|
||||||
|
|
||||||
|
bits[0] = x;
|
||||||
|
bits[1] = (x >> 8) | (y << 4);
|
||||||
|
bits[2] = (y >> 4);
|
||||||
|
bits[3] = z;
|
||||||
|
bits[4] = (z >> 8) | (p << 4);
|
||||||
|
bits[5] = yaw;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
MSG_WriteByte (msg, bits[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
/*
|
||||||
SV_EntityState_Diff (entity_state_t *from, entity_state_t *to)
|
SV_WriteDelta
|
||||||
|
|
||||||
|
Writes part of a packetentities message.
|
||||||
|
Can delta from either a baseline or a previous packet_entity
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
|
||||||
|
qboolean force, int stdver)
|
||||||
{
|
{
|
||||||
int i;
|
int bits, i;
|
||||||
float miss;
|
float miss;
|
||||||
unsigned int bits = 0;
|
|
||||||
|
// send an update
|
||||||
|
bits = 0;
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
miss = to->origin[i] - from->origin[i];
|
miss = to->origin[i] - from->origin[i];
|
||||||
|
@ -182,7 +203,7 @@ SV_EntityState_Diff (entity_state_t *from, entity_state_t *to)
|
||||||
|
|
||||||
// LordHavoc: cleaned up Endy's coding style, and added missing effects
|
// LordHavoc: cleaned up Endy's coding style, and added missing effects
|
||||||
// Ender (QSG - Begin)
|
// Ender (QSG - Begin)
|
||||||
// if (stdver > 1) {
|
if (stdver > 1) {
|
||||||
if (to->alpha != from->alpha)
|
if (to->alpha != from->alpha)
|
||||||
bits |= U_ALPHA;
|
bits |= U_ALPHA;
|
||||||
|
|
||||||
|
@ -197,44 +218,20 @@ SV_EntityState_Diff (entity_state_t *from, entity_state_t *to)
|
||||||
|
|
||||||
if (to->colormod != from->colormod)
|
if (to->colormod != from->colormod)
|
||||||
bits |= U_COLORMOD;
|
bits |= U_COLORMOD;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if (bits >= 16777216)
|
if (bits >= 16777216)
|
||||||
if (bits & U_GROUP_EXTEND2)
|
|
||||||
bits |= U_EXTEND2;
|
bits |= U_EXTEND2;
|
||||||
|
|
||||||
// if (bits >= 65536)
|
if (bits >= 65536)
|
||||||
if (bits & U_GROUP_EXTEND1)
|
|
||||||
bits |= U_EXTEND1;
|
bits |= U_EXTEND1;
|
||||||
// Ender (QSG - End)
|
// Ender (QSG - End)
|
||||||
|
if (bits & 511)
|
||||||
// if (bits & 511)
|
|
||||||
if (bits & U_GROUP_MOREBITS)
|
|
||||||
bits |= U_MOREBITS;
|
bits |= U_MOREBITS;
|
||||||
|
|
||||||
if (to->flags & U_SOLID)
|
if (to->flags & U_SOLID)
|
||||||
bits |= U_SOLID;
|
bits |= U_SOLID;
|
||||||
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
SV_WriteDelta
|
|
||||||
|
|
||||||
Writes part of a packetentities message.
|
|
||||||
Can delta from either a baseline or a previous packet_entity
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
|
|
||||||
qboolean force, int stdver)
|
|
||||||
{
|
|
||||||
unsigned int bits;
|
|
||||||
|
|
||||||
// send an update
|
|
||||||
bits = SV_EntityState_Diff (from, to);
|
|
||||||
if (stdver <= 1)
|
|
||||||
bits &= U_VERSION_ID; // use old the original fields, no extensions
|
|
||||||
|
|
||||||
// write the message
|
// write the message
|
||||||
if (!to->number)
|
if (!to->number)
|
||||||
SV_Error ("Unset entity number");
|
SV_Error ("Unset entity number");
|
||||||
|
@ -243,7 +240,10 @@ SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
|
||||||
|
|
||||||
if (!bits && !force)
|
if (!bits && !force)
|
||||||
return; // nothing to send!
|
return; // nothing to send!
|
||||||
MSG_WriteShort (msg, to->number | (bits & ~511));
|
i = to->number | (bits & ~511);
|
||||||
|
if (i & U_REMOVE)
|
||||||
|
Sys_Error ("U_REMOVE");
|
||||||
|
MSG_WriteShort (msg, i);
|
||||||
|
|
||||||
if (bits & U_MOREBITS)
|
if (bits & U_MOREBITS)
|
||||||
MSG_WriteByte (msg, bits & 255);
|
MSG_WriteByte (msg, bits & 255);
|
||||||
|
@ -302,118 +302,80 @@ SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
|
||||||
/*
|
/*
|
||||||
SV_EmitPacketEntities
|
SV_EmitPacketEntities
|
||||||
|
|
||||||
Writes an update of a packet_entities_t to the message.
|
Writes a delta update of a packet_entities_t to the message.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
|
SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
|
||||||
{
|
{
|
||||||
int index;
|
int newindex, oldindex, newnum, oldnum, oldmax;
|
||||||
entity_state_t *baseline;
|
edict_t *ent;
|
||||||
net_svc_packetentities_t block;
|
client_frame_t *fromframe;
|
||||||
|
|
||||||
block.numwords = block.numdeltas = to->num_entities;
|
|
||||||
|
|
||||||
for (index = 0; index < to->num_entities; index++) {
|
|
||||||
baseline = EDICT_NUM (&sv_pr_state,
|
|
||||||
to->entities[index].number)->data;
|
|
||||||
block.deltas[index] = to->entities[index];
|
|
||||||
block.deltas[index].flags =
|
|
||||||
SV_EntityState_Diff (baseline, &to->entities[index]);
|
|
||||||
|
|
||||||
// check if it's a client that doesn't support QSG2
|
|
||||||
if (client->stdver <= 1)
|
|
||||||
block.deltas[index].flags &= U_VERSION_ID;
|
|
||||||
|
|
||||||
block.words[index] = to->entities[index].number |
|
|
||||||
(block.deltas[index].flags & ~511);
|
|
||||||
}
|
|
||||||
|
|
||||||
block.words[index] = 0;
|
|
||||||
MSG_WriteByte (msg, svc_packetentities);
|
|
||||||
NET_SVC_PacketEntities_Emit (&block, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
SV_EmitDeltaPacketEntities
|
|
||||||
|
|
||||||
Writes a delta update of a packet_entities_t to the message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SV_EmitDeltaPacketEntities (client_t *client, packet_entities_t *to,
|
|
||||||
sizebuf_t *msg)
|
|
||||||
{
|
|
||||||
int newindex, oldindex, newnum, oldnum;
|
|
||||||
int word;
|
|
||||||
entity_state_t *baseline;
|
|
||||||
packet_entities_t *from;
|
packet_entities_t *from;
|
||||||
net_svc_deltapacketentities_t block;
|
|
||||||
|
|
||||||
// this is the frame that we are going to delta update from
|
// this is the frame that we are going to delta update from
|
||||||
from = &client->frames[client->delta_sequence & UPDATE_MASK].entities;
|
if (client->delta_sequence != -1) {
|
||||||
|
fromframe = &client->frames[client->delta_sequence & UPDATE_MASK];
|
||||||
|
from = &fromframe->entities;
|
||||||
|
oldmax = from->num_entities;
|
||||||
|
|
||||||
block.from = client->delta_sequence;
|
MSG_WriteByte (msg, svc_deltapacketentities);
|
||||||
|
MSG_WriteByte (msg, client->delta_sequence);
|
||||||
|
} else {
|
||||||
|
oldmax = 0; // no delta update
|
||||||
|
from = NULL;
|
||||||
|
|
||||||
|
MSG_WriteByte (msg, svc_packetentities);
|
||||||
|
}
|
||||||
|
|
||||||
|
newindex = 0;
|
||||||
|
oldindex = 0;
|
||||||
// SV_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK,
|
// SV_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK,
|
||||||
// client->netchan.outgoing_sequence & UPDATE_MASK);
|
// client->netchan.outgoing_sequence & UPDATE_MASK);
|
||||||
for (newindex = 0, oldindex = 0, word = 0;
|
while (newindex < to->num_entities || oldindex < oldmax) {
|
||||||
newindex < to->num_entities || oldindex < from->num_entities;
|
newnum =
|
||||||
word++) {
|
newindex >= to->num_entities ? 9999 :
|
||||||
newnum = newindex >= to->num_entities ?
|
to->entities[newindex].number;
|
||||||
9999 : to->entities[newindex].number;
|
oldnum = oldindex >= oldmax ? 9999 : from->entities[oldindex].number;
|
||||||
oldnum = oldindex >= from->num_entities ?
|
|
||||||
9999 : from->entities[oldindex].number;
|
|
||||||
|
|
||||||
if (newnum == oldnum) { // delta update from old position
|
if (newnum == oldnum) { // delta update from old position
|
||||||
// SV_Printf ("delta %i\n", newnum);
|
// SV_Printf ("delta %i\n", newnum);
|
||||||
block.deltas[newindex] = to->entities[newindex];
|
SV_WriteDelta (&from->entities[oldindex], &to->entities[newindex],
|
||||||
block.deltas[newindex].flags =
|
msg, false, client->stdver);
|
||||||
SV_EntityState_Diff (&from->entities[oldindex],
|
|
||||||
&to->entities[newindex]);
|
|
||||||
|
|
||||||
// check if it's a client that doesn't support QSG2
|
|
||||||
if (client->stdver <= 1)
|
|
||||||
block.deltas[newindex].flags &= U_VERSION_ID;
|
|
||||||
|
|
||||||
block.words[word] = newnum | (block.deltas[newindex].flags & ~511);
|
|
||||||
|
|
||||||
oldindex++;
|
oldindex++;
|
||||||
newindex++;
|
newindex++;
|
||||||
} else if (newnum < oldnum) { // this is a new entity, send
|
continue;
|
||||||
// it from the baseline
|
}
|
||||||
baseline = EDICT_NUM (&sv_pr_state, newnum)->data;
|
|
||||||
|
if (newnum < oldnum) { // this is a new entity, send it from
|
||||||
|
// the baseline
|
||||||
|
ent = EDICT_NUM (&sv_pr_state, newnum);
|
||||||
// SV_Printf ("baseline %i\n", newnum);
|
// SV_Printf ("baseline %i\n", newnum);
|
||||||
block.deltas[newindex] = to->entities[newindex];
|
SV_WriteDelta (ent->data, &to->entities[newindex], msg, true,
|
||||||
block.deltas[newindex].flags =
|
client->stdver);
|
||||||
SV_EntityState_Diff (baseline, &to->entities[newindex]);
|
|
||||||
|
|
||||||
// check if it's a client that doesn't support QSG2
|
|
||||||
if (client->stdver <= 1)
|
|
||||||
block.deltas[newindex].flags &= U_VERSION_ID;
|
|
||||||
|
|
||||||
block.words[word] = newnum | (block.deltas[newindex].flags & ~511);
|
|
||||||
|
|
||||||
newindex++;
|
newindex++;
|
||||||
} else if (newnum > oldnum) { // the old entity isn't
|
continue;
|
||||||
// present in the new message
|
}
|
||||||
|
|
||||||
|
if (newnum > oldnum) { // the old entity isn't present in
|
||||||
|
// the new message
|
||||||
// SV_Printf ("remove %i\n", oldnum);
|
// SV_Printf ("remove %i\n", oldnum);
|
||||||
block.words[word] = oldnum | U_REMOVE;
|
MSG_WriteShort (msg, oldnum | U_REMOVE);
|
||||||
oldindex++;
|
oldindex++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block.words[word] = 0;
|
MSG_WriteShort (msg, 0); // end of packetentities
|
||||||
MSG_WriteByte (msg, svc_deltapacketentities);
|
|
||||||
NET_SVC_DeltaPacketEntities_Emit (&block, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
|
SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
|
||||||
sizebuf_t *msg)
|
sizebuf_t *msg)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j, msec, pflags;
|
||||||
client_t *cl;
|
client_t *cl;
|
||||||
edict_t *ent;
|
edict_t *ent;
|
||||||
net_svc_playerinfo_t block;
|
usercmd_t cmd;
|
||||||
|
|
||||||
for (j = 0, cl = svs.clients; j < MAX_CLIENTS; j++, cl++) {
|
for (j = 0, cl = svs.clients; j < MAX_CLIENTS; j++, cl++) {
|
||||||
if (cl->state != cs_spawned)
|
if (cl->state != cs_spawned)
|
||||||
|
@ -435,63 +397,82 @@ SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
|
||||||
continue; // not visible
|
continue; // not visible
|
||||||
}
|
}
|
||||||
|
|
||||||
block.flags = PF_MSEC | PF_COMMAND;
|
pflags = PF_MSEC | PF_COMMAND;
|
||||||
|
|
||||||
if (SVfloat (ent, modelindex) != sv_playermodel)
|
if (SVfloat (ent, modelindex) != sv_playermodel)
|
||||||
block.flags |= PF_MODEL;
|
pflags |= PF_MODEL;
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
if (SVvector (ent, velocity)[i])
|
if (SVvector (ent, velocity)[i])
|
||||||
block.flags |= PF_VELOCITY1 << i;
|
pflags |= PF_VELOCITY1 << i;
|
||||||
if (SVfloat (ent, effects))
|
if (SVfloat (ent, effects))
|
||||||
block.flags |= PF_EFFECTS;
|
pflags |= PF_EFFECTS;
|
||||||
if (SVfloat (ent, skin))
|
if (SVfloat (ent, skin))
|
||||||
block.flags |= PF_SKINNUM;
|
pflags |= PF_SKINNUM;
|
||||||
if (SVfloat (ent, health) <= 0)
|
if (SVfloat (ent, health) <= 0)
|
||||||
block.flags |= PF_DEAD;
|
pflags |= PF_DEAD;
|
||||||
if (SVvector (ent, mins)[2] != -24)
|
if (SVvector (ent, mins)[2] != -24)
|
||||||
block.flags |= PF_GIB;
|
pflags |= PF_GIB;
|
||||||
|
|
||||||
if (cl->spectator) { // only sent origin and velocity to
|
if (cl->spectator) { // only sent origin and velocity to
|
||||||
// spectators
|
// spectators
|
||||||
block.flags &= PF_VELOCITY1 | PF_VELOCITY2 | PF_VELOCITY3;
|
pflags &= PF_VELOCITY1 | PF_VELOCITY2 | PF_VELOCITY3;
|
||||||
} else if (ent == clent) { // don't send a lot of data on
|
} else if (ent == clent) { // don't send a lot of data on
|
||||||
// personal entity
|
// personal entity
|
||||||
block.flags &= ~(PF_MSEC | PF_COMMAND);
|
pflags &= ~(PF_MSEC | PF_COMMAND);
|
||||||
if (SVfloat (ent, weaponframe))
|
if (SVfloat (ent, weaponframe))
|
||||||
block.flags |= PF_WEAPONFRAME;
|
pflags |= PF_WEAPONFRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->spec_track && client->spec_track - 1 == j &&
|
if (client->spec_track && client->spec_track - 1 == j &&
|
||||||
SVfloat (ent, weaponframe))
|
SVfloat (ent, weaponframe)) pflags |= PF_WEAPONFRAME;
|
||||||
block.flags |= PF_WEAPONFRAME;
|
|
||||||
|
|
||||||
block.playernum = j;
|
|
||||||
|
|
||||||
VectorCopy (SVvector (ent, origin), block.origin);
|
|
||||||
block.frame = SVfloat (ent, frame);
|
|
||||||
|
|
||||||
block.msec = 1000 * (sv.time - cl->localtime);
|
|
||||||
if (block.msec > 255)
|
|
||||||
block.msec = 255;
|
|
||||||
|
|
||||||
block.usercmd = cl->lastcmd;
|
|
||||||
if (SVfloat (ent, health) <= 0) { // don't show the corpse
|
|
||||||
// looking around...
|
|
||||||
block.usercmd.angles[0] = 0;
|
|
||||||
block.usercmd.angles[1] = SVvector (ent, angles)[1];
|
|
||||||
block.usercmd.angles[0] = 0;
|
|
||||||
}
|
|
||||||
block.usercmd.buttons = 0; // never send buttons
|
|
||||||
block.usercmd.impulse = 0; // never send impulses
|
|
||||||
|
|
||||||
VectorCopy (SVvector (ent, velocity), block.velocity);
|
|
||||||
block.modelindex = SVfloat (ent, modelindex);
|
|
||||||
block.skinnum = SVfloat (ent, skin);
|
|
||||||
block.effects = SVfloat (ent, effects);
|
|
||||||
block.weaponframe = SVfloat (ent, weaponframe);
|
|
||||||
|
|
||||||
MSG_WriteByte (msg, svc_playerinfo);
|
MSG_WriteByte (msg, svc_playerinfo);
|
||||||
NET_SVC_Playerinfo_Emit (&block, msg);
|
MSG_WriteByte (msg, j);
|
||||||
|
MSG_WriteShort (msg, pflags);
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
MSG_WriteCoord (msg, SVvector (ent, origin)[i]);
|
||||||
|
|
||||||
|
MSG_WriteByte (msg, SVfloat (ent, frame));
|
||||||
|
|
||||||
|
if (pflags & PF_MSEC) {
|
||||||
|
msec = 1000 * (sv.time - cl->localtime);
|
||||||
|
if (msec > 255)
|
||||||
|
msec = 255;
|
||||||
|
MSG_WriteByte (msg, msec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pflags & PF_COMMAND) {
|
||||||
|
cmd = cl->lastcmd;
|
||||||
|
|
||||||
|
if (SVfloat (ent, health) <= 0) { // don't show the corpse
|
||||||
|
// looking around...
|
||||||
|
cmd.angles[0] = 0;
|
||||||
|
cmd.angles[1] = SVvector (ent, angles)[1];
|
||||||
|
cmd.angles[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.buttons = 0; // never send buttons
|
||||||
|
cmd.impulse = 0; // never send impulses
|
||||||
|
|
||||||
|
MSG_WriteDeltaUsercmd (msg, &nullcmd, &cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
if (pflags & (PF_VELOCITY1 << i))
|
||||||
|
MSG_WriteShort (msg, SVvector (ent, velocity)[i]);
|
||||||
|
|
||||||
|
if (pflags & PF_MODEL)
|
||||||
|
MSG_WriteByte (msg, SVfloat (ent, modelindex));
|
||||||
|
|
||||||
|
if (pflags & PF_SKINNUM)
|
||||||
|
MSG_WriteByte (msg, SVfloat (ent, skin));
|
||||||
|
|
||||||
|
if (pflags & PF_EFFECTS)
|
||||||
|
MSG_WriteByte (msg, SVfloat (ent, effects));
|
||||||
|
|
||||||
|
if (pflags & PF_WEAPONFRAME)
|
||||||
|
MSG_WriteByte (msg, SVfloat (ent, weaponframe));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,9 +591,7 @@ SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
|
||||||
|
|
||||||
// encode the packet entities as a delta from the
|
// encode the packet entities as a delta from the
|
||||||
// last packetentities acknowledged by the client
|
// last packetentities acknowledged by the client
|
||||||
if (client->delta_sequence != -1)
|
|
||||||
SV_EmitDeltaPacketEntities (client, pack, msg);
|
|
||||||
else
|
|
||||||
SV_EmitPacketEntities (client, pack, msg);
|
SV_EmitPacketEntities (client, pack, msg);
|
||||||
|
|
||||||
// now add the specialized nail update
|
// now add the specialized nail update
|
||||||
|
|
|
@ -46,7 +46,6 @@ static const char rcsid[] =
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "crudefile.h"
|
#include "crudefile.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "sv_progs.h"
|
#include "sv_progs.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
|
@ -105,9 +104,8 @@ SV_FlushSignon (void)
|
||||||
void
|
void
|
||||||
SV_CreateBaseline (void)
|
SV_CreateBaseline (void)
|
||||||
{
|
{
|
||||||
int entnum;
|
int i, entnum;
|
||||||
edict_t *svent;
|
edict_t *svent;
|
||||||
net_svc_spawnbaseline_t block;
|
|
||||||
|
|
||||||
for (entnum = 0; entnum < sv.num_edicts; entnum++) {
|
for (entnum = 0; entnum < sv.num_edicts; entnum++) {
|
||||||
svent = EDICT_NUM (&sv_pr_state, entnum);
|
svent = EDICT_NUM (&sv_pr_state, entnum);
|
||||||
|
@ -145,15 +143,19 @@ SV_CreateBaseline (void)
|
||||||
SV_FlushSignon ();
|
SV_FlushSignon ();
|
||||||
|
|
||||||
// add to the message
|
// add to the message
|
||||||
block.num = entnum;
|
|
||||||
block.modelindex = ((entity_state_t*)svent->data)->modelindex;
|
|
||||||
block.frame = ((entity_state_t*)svent->data)->frame;
|
|
||||||
block.colormap = ((entity_state_t*)svent->data)->colormap;
|
|
||||||
block.skinnum = ((entity_state_t*)svent->data)->skinnum;
|
|
||||||
VectorCopy (((entity_state_t*)svent->data)->origin, block.origin);
|
|
||||||
VectorCopy (((entity_state_t*)svent->data)->angles, block.angles);
|
|
||||||
MSG_WriteByte (&sv.signon, svc_spawnbaseline);
|
MSG_WriteByte (&sv.signon, svc_spawnbaseline);
|
||||||
NET_SVC_SpawnBaseline_Emit (&block, &sv.signon);
|
MSG_WriteShort (&sv.signon, entnum);
|
||||||
|
|
||||||
|
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->modelindex);
|
||||||
|
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->frame);
|
||||||
|
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->colormap);
|
||||||
|
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->skinnum);
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
MSG_WriteCoord (&sv.signon,
|
||||||
|
((entity_state_t*)svent->data)->origin[i]);
|
||||||
|
MSG_WriteAngle (&sv.signon,
|
||||||
|
((entity_state_t*)svent->data)->angles[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,6 @@ static const char rcsid[] =
|
||||||
#include "crudefile.h"
|
#include "crudefile.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "pmove.h"
|
#include "pmove.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "sv_progs.h"
|
#include "sv_progs.h"
|
||||||
|
@ -261,14 +260,11 @@ SV_FinalMessage (const char *message)
|
||||||
{
|
{
|
||||||
client_t *cl;
|
client_t *cl;
|
||||||
int i;
|
int i;
|
||||||
net_svc_print_t block;
|
|
||||||
|
|
||||||
block.level = PRINT_HIGH;
|
|
||||||
block.message = message;
|
|
||||||
|
|
||||||
SZ_Clear (net_message->message);
|
SZ_Clear (net_message->message);
|
||||||
MSG_WriteByte (net_message->message, svc_print);
|
MSG_WriteByte (net_message->message, svc_print);
|
||||||
NET_SVC_Print_Emit (&block, net_message->message);
|
MSG_WriteByte (net_message->message, PRINT_HIGH);
|
||||||
|
MSG_WriteString (net_message->message, message);
|
||||||
MSG_WriteByte (net_message->message, svc_disconnect);
|
MSG_WriteByte (net_message->message, svc_disconnect);
|
||||||
|
|
||||||
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
|
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
|
||||||
|
@ -373,7 +369,6 @@ SV_FullClientUpdate (client_t *client, sizebuf_t *buf)
|
||||||
{
|
{
|
||||||
char *info;
|
char *info;
|
||||||
int i;
|
int i;
|
||||||
net_svc_updateuserinfo_t block;
|
|
||||||
|
|
||||||
i = client - svs.clients;
|
i = client - svs.clients;
|
||||||
|
|
||||||
|
@ -398,11 +393,10 @@ SV_FullClientUpdate (client_t *client, sizebuf_t *buf)
|
||||||
info = client->userinfo ? Info_MakeString (client->userinfo,
|
info = client->userinfo ? Info_MakeString (client->userinfo,
|
||||||
make_info_string_filter) : "";
|
make_info_string_filter) : "";
|
||||||
|
|
||||||
block.slot = i;
|
|
||||||
block.userid = client->userid;
|
|
||||||
block.userinfo = info;
|
|
||||||
MSG_WriteByte (buf, svc_updateuserinfo);
|
MSG_WriteByte (buf, svc_updateuserinfo);
|
||||||
NET_SVC_UpdateUserInfo_Emit (&block, buf);
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteLong (buf, client->userid);
|
||||||
|
MSG_WriteString (buf, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2177,7 +2171,6 @@ Master_Shutdown (void)
|
||||||
static inline qboolean
|
static inline qboolean
|
||||||
iswhitespace (char c)
|
iswhitespace (char c)
|
||||||
{
|
{
|
||||||
c &= 127;
|
|
||||||
return c == ' ' || c == '\r' || c == '\n' || c == '\t';
|
return c == ' ' || c == '\r' || c == '\n' || c == '\t';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2207,9 +2200,9 @@ SV_ExtractFromUserinfo (client_t *cl)
|
||||||
for (r = newname; *p && r != newname + sizeof (newname) - 1; p++) {
|
for (r = newname; *p && r != newname + sizeof (newname) - 1; p++) {
|
||||||
if (iswhitespace (*p)) {
|
if (iswhitespace (*p)) {
|
||||||
if (!iswhitespace (p[1]) && p[1] != '\0')
|
if (!iswhitespace (p[1]) && p[1] != '\0')
|
||||||
*r++ = ' '; // get rid of any special chars
|
*r++ = *p;
|
||||||
} else
|
} else
|
||||||
*r++ = *p & 127; // get rid of bold
|
*r++ = *p;
|
||||||
}
|
}
|
||||||
*r = '\0';
|
*r = '\0';
|
||||||
|
|
||||||
|
@ -2217,14 +2210,6 @@ SV_ExtractFromUserinfo (client_t *cl)
|
||||||
if (!*newname)
|
if (!*newname)
|
||||||
badname = true;
|
badname = true;
|
||||||
|
|
||||||
// ':' is used in chat messages
|
|
||||||
if (strchr (newname, ':'))
|
|
||||||
badname = true;
|
|
||||||
|
|
||||||
// I dunno if this is possible, but better safe than sorry
|
|
||||||
if (strchr (newname, '"'))
|
|
||||||
badname = true;
|
|
||||||
|
|
||||||
// impersonating an user-xxx name. if they're using it
|
// impersonating an user-xxx name. if they're using it
|
||||||
// legitimately it'll be a no-op later on
|
// legitimately it'll be a no-op later on
|
||||||
if (!strncasecmp (newname, "user-", 5))
|
if (!strncasecmp (newname, "user-", 5))
|
||||||
|
@ -2283,10 +2268,9 @@ SV_ExtractFromUserinfo (client_t *cl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally, report it to all our friends, but only if more
|
// finally, report it to all our friends
|
||||||
// than whitespace changed
|
|
||||||
// if (cl->state >= cs_spawned && !cl->spectator)
|
// if (cl->state >= cs_spawned && !cl->spectator)
|
||||||
if (*cl->name && strcmp (cl->name, newname))
|
if (*cl->name)
|
||||||
SV_BroadcastPrintf (PRINT_HIGH, "%s changed name to %s\n",
|
SV_BroadcastPrintf (PRINT_HIGH, "%s changed name to %s\n",
|
||||||
cl->name, newname);
|
cl->name, newname);
|
||||||
strcpy (cl->name, newname);
|
strcpy (cl->name, newname);
|
||||||
|
|
|
@ -36,6 +36,7 @@ static const char rcsid[] =
|
||||||
#include "QF/model.h"
|
#include "QF/model.h"
|
||||||
|
|
||||||
const int mod_lightmap_bytes = 1;
|
const int mod_lightmap_bytes = 1;
|
||||||
|
cvar_t *gl_sky_divide; // not used but needed for linking
|
||||||
|
|
||||||
void Mod_LoadBrushModel (model_t *mod, void *buffer);
|
void Mod_LoadBrushModel (model_t *mod, void *buffer);
|
||||||
|
|
||||||
|
|
|
@ -607,14 +607,14 @@ SV_CheckWaterTransition (edict_t *ent)
|
||||||
if (cont <= CONTENTS_WATER) {
|
if (cont <= CONTENTS_WATER) {
|
||||||
if (SVfloat (ent, watertype) == CONTENTS_EMPTY) {
|
if (SVfloat (ent, watertype) == CONTENTS_EMPTY) {
|
||||||
// just crossed into water
|
// just crossed into water
|
||||||
SV_StartSound (ent, 0, "misc/h2ohit1.wav", 1, 1);
|
SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
|
||||||
}
|
}
|
||||||
SVfloat (ent, watertype) = cont;
|
SVfloat (ent, watertype) = cont;
|
||||||
SVfloat (ent, waterlevel) = 1;
|
SVfloat (ent, waterlevel) = 1;
|
||||||
} else {
|
} else {
|
||||||
if (SVfloat (ent, watertype) != CONTENTS_EMPTY) {
|
if (SVfloat (ent, watertype) != CONTENTS_EMPTY) {
|
||||||
// just crossed into water
|
// just crossed into water
|
||||||
SV_StartSound (ent, 0, "misc/h2ohit1.wav", 1, 1);
|
SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
|
||||||
}
|
}
|
||||||
SVfloat (ent, watertype) = CONTENTS_EMPTY;
|
SVfloat (ent, watertype) = CONTENTS_EMPTY;
|
||||||
SVfloat (ent, waterlevel) = cont;
|
SVfloat (ent, waterlevel) = cont;
|
||||||
|
@ -717,7 +717,7 @@ SV_Physics_Step (edict_t *ent)
|
||||||
if ((int) SVfloat (ent, flags) & FL_ONGROUND) // just hit ground
|
if ((int) SVfloat (ent, flags) & FL_ONGROUND) // just hit ground
|
||||||
{
|
{
|
||||||
if (hitsound)
|
if (hitsound)
|
||||||
SV_StartSound (ent, 0, "demon/dland2.wav", 1, 1);
|
SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// regular thinking
|
// regular thinking
|
||||||
|
|
|
@ -45,7 +45,6 @@ static const char rcsid[] =
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "crudefile.h"
|
#include "crudefile.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "sv_pr_cmds.h"
|
#include "sv_pr_cmds.h"
|
||||||
#include "sv_progs.h"
|
#include "sv_progs.h"
|
||||||
|
@ -280,16 +279,17 @@ PF_ambientsound (progs_t *pr)
|
||||||
{
|
{
|
||||||
const char **check;
|
const char **check;
|
||||||
const char *samp;
|
const char *samp;
|
||||||
net_svc_spawnstaticsound_t block;
|
float *pos;
|
||||||
|
float vol, attenuation;
|
||||||
|
int i, soundnum;
|
||||||
|
|
||||||
VectorCopy (G_VECTOR (pr, OFS_PARM0), block.position);
|
pos = G_VECTOR (pr, OFS_PARM0);
|
||||||
samp = G_STRING (pr, OFS_PARM1);
|
samp = G_STRING (pr, OFS_PARM1);
|
||||||
block.volume = G_FLOAT (pr, OFS_PARM2) * 255;
|
vol = G_FLOAT (pr, OFS_PARM2);
|
||||||
block.attenuation = G_FLOAT (pr, OFS_PARM3) * 64;
|
attenuation = G_FLOAT (pr, OFS_PARM3);
|
||||||
|
|
||||||
// check to see if samp was properly precached
|
// check to see if samp was properly precached
|
||||||
for (block.sound_num = 0, check = sv.sound_precache; *check;
|
for (soundnum = 0, check = sv.sound_precache; *check; check++, soundnum++)
|
||||||
check++, block.sound_num++)
|
|
||||||
if (!strcmp (*check, samp))
|
if (!strcmp (*check, samp))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -300,7 +300,14 @@ PF_ambientsound (progs_t *pr)
|
||||||
|
|
||||||
// add an svc_spawnambient command to the level signon packet
|
// add an svc_spawnambient command to the level signon packet
|
||||||
MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
|
MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
|
||||||
NET_SVC_SpawnStaticSound_Emit (&block, &sv.signon);
|
for (i = 0; i < 3; i++)
|
||||||
|
MSG_WriteCoord (&sv.signon, pos[i]);
|
||||||
|
|
||||||
|
MSG_WriteByte (&sv.signon, soundnum);
|
||||||
|
|
||||||
|
MSG_WriteByte (&sv.signon, vol * 255);
|
||||||
|
MSG_WriteByte (&sv.signon, attenuation * 64);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -320,13 +327,13 @@ PF_sound (progs_t *pr)
|
||||||
{
|
{
|
||||||
const char *sample;
|
const char *sample;
|
||||||
edict_t *entity;
|
edict_t *entity;
|
||||||
float volume, attenuation;
|
float attenuation;
|
||||||
int channel;
|
int channel, volume;
|
||||||
|
|
||||||
entity = G_EDICT (pr, OFS_PARM0);
|
entity = G_EDICT (pr, OFS_PARM0);
|
||||||
channel = G_FLOAT (pr, OFS_PARM1);
|
channel = G_FLOAT (pr, OFS_PARM1);
|
||||||
sample = G_STRING (pr, OFS_PARM2);
|
sample = G_STRING (pr, OFS_PARM2);
|
||||||
volume = G_FLOAT (pr, OFS_PARM3);
|
volume = G_FLOAT (pr, OFS_PARM3) * 255;
|
||||||
attenuation = G_FLOAT (pr, OFS_PARM4);
|
attenuation = G_FLOAT (pr, OFS_PARM4);
|
||||||
|
|
||||||
SV_StartSound (entity, channel, sample, volume, attenuation);
|
SV_StartSound (entity, channel, sample, volume, attenuation);
|
||||||
|
@ -1135,21 +1142,25 @@ int SV_ModelIndex (const char *name);
|
||||||
void
|
void
|
||||||
PF_makestatic (progs_t *pr)
|
PF_makestatic (progs_t *pr)
|
||||||
{
|
{
|
||||||
|
const char *model;
|
||||||
edict_t *ent;
|
edict_t *ent;
|
||||||
net_svc_spawnstatic_t block;
|
int i;
|
||||||
|
|
||||||
ent = G_EDICT (pr, OFS_PARM0);
|
ent = G_EDICT (pr, OFS_PARM0);
|
||||||
|
|
||||||
// SV_Printf ("Model: %d %s\n", SVstring (ent, model), model);
|
|
||||||
block.modelindex = SV_ModelIndex (PR_GetString (pr, SVstring (ent, model)));
|
|
||||||
block.frame = SVfloat (ent, frame);
|
|
||||||
block.colormap = SVfloat (ent, colormap);
|
|
||||||
block.skinnum = SVfloat (ent, skin);
|
|
||||||
VectorCopy (SVvector (ent, origin), block.origin);
|
|
||||||
VectorCopy (SVvector (ent, angles), block.angles);
|
|
||||||
|
|
||||||
MSG_WriteByte (&sv.signon, svc_spawnstatic);
|
MSG_WriteByte (&sv.signon, svc_spawnstatic);
|
||||||
NET_SVC_SpawnStatic_Emit (&block, &sv.signon);
|
|
||||||
|
model = PR_GetString (pr, SVstring (ent, model));
|
||||||
|
// SV_Printf ("Model: %d %s\n", SVstring (ent, model), model);
|
||||||
|
MSG_WriteByte (&sv.signon, SV_ModelIndex (model));
|
||||||
|
|
||||||
|
MSG_WriteByte (&sv.signon, SVfloat (ent, frame));
|
||||||
|
MSG_WriteByte (&sv.signon, SVfloat (ent, colormap));
|
||||||
|
MSG_WriteByte (&sv.signon, SVfloat (ent, skin));
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
MSG_WriteCoord (&sv.signon, SVvector (ent, origin)[i]);
|
||||||
|
MSG_WriteAngle (&sv.signon, SVvector (ent, angles)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// throw the entity away now
|
// throw the entity away now
|
||||||
ED_Free (pr, ent);
|
ED_Free (pr, ent);
|
||||||
|
@ -1358,7 +1369,6 @@ PF_setinfokey (progs_t *pr)
|
||||||
int e1 = NUM_FOR_EDICT (pr, edict);
|
int e1 = NUM_FOR_EDICT (pr, edict);
|
||||||
const char *key = G_STRING (pr, OFS_PARM1);
|
const char *key = G_STRING (pr, OFS_PARM1);
|
||||||
const char *value = G_STRING (pr, OFS_PARM2);
|
const char *value = G_STRING (pr, OFS_PARM2);
|
||||||
net_svc_setinfo_t block;
|
|
||||||
|
|
||||||
if (e1 == 0) {
|
if (e1 == 0) {
|
||||||
if (*value)
|
if (*value)
|
||||||
|
@ -1372,11 +1382,12 @@ PF_setinfokey (progs_t *pr)
|
||||||
SV_ExtractFromUserinfo (&svs.clients[e1 - 1]);
|
SV_ExtractFromUserinfo (&svs.clients[e1 - 1]);
|
||||||
|
|
||||||
if (Info_FilterForKey (key, client_info_filters)) {
|
if (Info_FilterForKey (key, client_info_filters)) {
|
||||||
block.slot = e1 - 1;
|
|
||||||
block.key = key;
|
|
||||||
block.value = Info_ValueForKey (svs.clients[e1 - 1].userinfo, key);
|
|
||||||
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
|
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
|
||||||
NET_SVC_SetInfo_Emit (&block, &sv.reliable_datagram);
|
MSG_WriteByte (&sv.reliable_datagram, e1 - 1);
|
||||||
|
MSG_WriteString (&sv.reliable_datagram, key);
|
||||||
|
MSG_WriteString (&sv.reliable_datagram,
|
||||||
|
Info_ValueForKey (svs.clients[e1 - 1].userinfo,
|
||||||
|
key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ static const char rcsid[] =
|
||||||
|
|
||||||
#include "bothdefs.h"
|
#include "bothdefs.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "sv_progs.h"
|
#include "sv_progs.h"
|
||||||
|
|
||||||
|
@ -70,7 +69,6 @@ void
|
||||||
SV_FlushRedirect (void)
|
SV_FlushRedirect (void)
|
||||||
{
|
{
|
||||||
char send[8000 + 6];
|
char send[8000 + 6];
|
||||||
net_svc_print_t block;
|
|
||||||
|
|
||||||
if (sv_redirected == RD_PACKET) {
|
if (sv_redirected == RD_PACKET) {
|
||||||
send[0] = 0xff;
|
send[0] = 0xff;
|
||||||
|
@ -82,15 +80,10 @@ SV_FlushRedirect (void)
|
||||||
|
|
||||||
NET_SendPacket (strlen (send) + 1, send, net_from);
|
NET_SendPacket (strlen (send) + 1, send, net_from);
|
||||||
} else if (sv_redirected == RD_CLIENT) {
|
} else if (sv_redirected == RD_CLIENT) {
|
||||||
block.level = PRINT_HIGH;
|
|
||||||
block.message = outputbuf;
|
|
||||||
ClientReliableWrite_Begin (host_client, svc_print,
|
ClientReliableWrite_Begin (host_client, svc_print,
|
||||||
strlen (outputbuf) + 3);
|
strlen (outputbuf) + 3);
|
||||||
if (host_client->num_backbuf) {
|
ClientReliableWrite_Byte (host_client, PRINT_HIGH);
|
||||||
NET_SVC_Print_Emit (&block, &host_client->backbuf);
|
ClientReliableWrite_String (host_client, outputbuf);
|
||||||
ClientReliable_FinishWrite (host_client);
|
|
||||||
} else
|
|
||||||
NET_SVC_Print_Emit (&block, &host_client->netchan.message);
|
|
||||||
}
|
}
|
||||||
// clear it
|
// clear it
|
||||||
outputbuf[0] = 0;
|
outputbuf[0] = 0;
|
||||||
|
@ -227,7 +220,6 @@ SV_PrintToClient (client_t *cl, int level, const char *string)
|
||||||
unsigned char *b;
|
unsigned char *b;
|
||||||
int size;
|
int size;
|
||||||
static int buffer_size;
|
static int buffer_size;
|
||||||
net_svc_print_t block;
|
|
||||||
|
|
||||||
size = strlen (string) + 1;
|
size = strlen (string) + 1;
|
||||||
if (size > buffer_size) {
|
if (size > buffer_size) {
|
||||||
|
@ -247,14 +239,9 @@ SV_PrintToClient (client_t *cl, int level, const char *string)
|
||||||
if (*b != 0xFF)
|
if (*b != 0xFF)
|
||||||
b++;
|
b++;
|
||||||
|
|
||||||
block.level = level;
|
|
||||||
block.message = buffer;
|
|
||||||
ClientReliableWrite_Begin (cl, svc_print, strlen (buffer) + 3);
|
ClientReliableWrite_Begin (cl, svc_print, strlen (buffer) + 3);
|
||||||
if (cl->num_backbuf) {
|
ClientReliableWrite_Byte (cl, level);
|
||||||
NET_SVC_Print_Emit (&block, &cl->backbuf);
|
ClientReliableWrite_String (cl, buffer);
|
||||||
ClientReliable_FinishWrite (cl);
|
|
||||||
} else
|
|
||||||
NET_SVC_Print_Emit (&block, &cl->netchan.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -429,16 +416,16 @@ SV_Multicast (vec3_t origin, int to)
|
||||||
Larger attenuations will drop off. (max 4 attenuation)
|
Larger attenuations will drop off. (max 4 attenuation)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SV_StartSound (edict_t *entity, int channel, const char *sample,
|
SV_StartSound (edict_t *entity, int channel, const char *sample, int volume,
|
||||||
float volume, float attenuation)
|
float attenuation)
|
||||||
{
|
{
|
||||||
int i, sound_num;
|
int ent, field_mask, sound_num, i;
|
||||||
qboolean use_phs;
|
qboolean use_phs;
|
||||||
qboolean reliable = false;
|
qboolean reliable = false;
|
||||||
net_svc_sound_t block;
|
vec3_t origin;
|
||||||
|
|
||||||
if (volume < 0 || volume > 1)
|
if (volume < 0 || volume > 255)
|
||||||
SV_Error ("SV_StartSound: volume = %f", volume);
|
SV_Error ("SV_StartSound: volume = %i", volume);
|
||||||
|
|
||||||
if (attenuation < 0 || attenuation > 4)
|
if (attenuation < 0 || attenuation > 4)
|
||||||
SV_Error ("SV_StartSound: attenuation = %f", attenuation);
|
SV_Error ("SV_StartSound: attenuation = %f", attenuation);
|
||||||
|
@ -457,9 +444,7 @@ SV_StartSound (edict_t *entity, int channel, const char *sample,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
block.sound_num = sound_num;
|
ent = NUM_FOR_EDICT (&sv_pr_state, entity);
|
||||||
|
|
||||||
block.entity = NUM_FOR_EDICT (&sv_pr_state, entity);
|
|
||||||
|
|
||||||
if ((channel & 8) || !sv_phs->int_val) // no PHS flag
|
if ((channel & 8) || !sv_phs->int_val) // no PHS flag
|
||||||
{
|
{
|
||||||
|
@ -474,34 +459,37 @@ SV_StartSound (edict_t *entity, int channel, const char *sample,
|
||||||
// if (channel == CHAN_BODY || channel == CHAN_VOICE)
|
// if (channel == CHAN_BODY || channel == CHAN_VOICE)
|
||||||
// reliable = true;
|
// reliable = true;
|
||||||
|
|
||||||
block.channel = channel;
|
channel = (ent << 3) | channel;
|
||||||
|
|
||||||
block.volume = volume;
|
field_mask = 0;
|
||||||
// 4 * 64 == 256, which overflows a byte. 4 is the stated max for
|
if (volume != DEFAULT_SOUND_PACKET_VOLUME)
|
||||||
// it, and I don't want to break any progs, so I just nudge it
|
channel |= SND_VOLUME;
|
||||||
// down instead
|
if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
|
||||||
if (attenuation == 4)
|
channel |= SND_ATTENUATION;
|
||||||
attenuation = 3.999;
|
|
||||||
block.attenuation = attenuation;
|
|
||||||
|
|
||||||
// use the entity origin unless it is a bmodel
|
// use the entity origin unless it is a bmodel
|
||||||
if (SVfloat (entity, solid) == SOLID_BSP) {
|
if (SVfloat (entity, solid) == SOLID_BSP) {
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
block.position[i] = SVvector (entity, origin)[i] + 0.5 *
|
origin[i] = SVvector (entity, origin)[i] + 0.5 *
|
||||||
(SVvector (entity, mins)[i] + SVvector (entity, maxs)[i]);
|
(SVvector (entity, mins)[i] + SVvector (entity, maxs)[i]);
|
||||||
} else {
|
} else {
|
||||||
VectorCopy (SVvector (entity, origin), block.position);
|
VectorCopy (SVvector (entity, origin), origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
MSG_WriteByte (&sv.multicast, svc_sound);
|
MSG_WriteByte (&sv.multicast, svc_sound);
|
||||||
NET_SVC_Sound_Emit (&block, &sv.multicast);
|
MSG_WriteShort (&sv.multicast, channel);
|
||||||
|
if (channel & SND_VOLUME)
|
||||||
|
MSG_WriteByte (&sv.multicast, volume);
|
||||||
|
if (channel & SND_ATTENUATION)
|
||||||
|
MSG_WriteByte (&sv.multicast, attenuation * 64);
|
||||||
|
MSG_WriteByte (&sv.multicast, sound_num);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
MSG_WriteCoord (&sv.multicast, origin[i]);
|
||||||
|
|
||||||
if (use_phs)
|
if (use_phs)
|
||||||
SV_Multicast (block.position,
|
SV_Multicast (origin, reliable ? MULTICAST_PHS_R : MULTICAST_PHS);
|
||||||
reliable ? MULTICAST_PHS_R : MULTICAST_PHS);
|
|
||||||
else
|
else
|
||||||
SV_Multicast (block.position,
|
SV_Multicast (origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL);
|
||||||
reliable ? MULTICAST_ALL_R : MULTICAST_ALL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FRAME UPDATES */
|
/* FRAME UPDATES */
|
||||||
|
@ -534,7 +522,6 @@ SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
|
||||||
{
|
{
|
||||||
edict_t *ent, *other;
|
edict_t *ent, *other;
|
||||||
int i;
|
int i;
|
||||||
net_svc_damage_t block;
|
|
||||||
|
|
||||||
ent = client->edict;
|
ent = client->edict;
|
||||||
|
|
||||||
|
@ -547,14 +534,13 @@ SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
|
||||||
// send a damage message if the player got hit this frame
|
// send a damage message if the player got hit this frame
|
||||||
if (SVfloat (ent, dmg_take) || SVfloat (ent, dmg_save)) {
|
if (SVfloat (ent, dmg_take) || SVfloat (ent, dmg_save)) {
|
||||||
other = PROG_TO_EDICT (&sv_pr_state, SVentity (ent, dmg_inflictor));
|
other = PROG_TO_EDICT (&sv_pr_state, SVentity (ent, dmg_inflictor));
|
||||||
block.armor = SVfloat (ent, dmg_save);
|
|
||||||
block.blood = SVfloat (ent, dmg_take);
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
block.from[i] = SVvector (other, origin)[i] + 0.5 *
|
|
||||||
(SVvector (other, mins)[i] +
|
|
||||||
SVvector (other, maxs)[i]);
|
|
||||||
MSG_WriteByte (msg, svc_damage);
|
MSG_WriteByte (msg, svc_damage);
|
||||||
NET_SVC_Damage_Emit (&block, msg);
|
MSG_WriteByte (msg, SVfloat (ent, dmg_save));
|
||||||
|
MSG_WriteByte (msg, SVfloat (ent, dmg_take));
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
MSG_WriteCoord (msg, SVvector (other, origin)[i] + 0.5 *
|
||||||
|
(SVvector (other, mins)[i] +
|
||||||
|
SVvector (other, maxs)[i]));
|
||||||
|
|
||||||
SVfloat (ent, dmg_take) = 0;
|
SVfloat (ent, dmg_take) = 0;
|
||||||
SVfloat (ent, dmg_save) = 0;
|
SVfloat (ent, dmg_save) = 0;
|
||||||
|
@ -794,6 +780,7 @@ SV_SendClientMessages (void)
|
||||||
// if the reliable message overflowed, drop the client
|
// if the reliable message overflowed, drop the client
|
||||||
if (c->netchan.message.overflowed) {
|
if (c->netchan.message.overflowed) {
|
||||||
int i;
|
int i;
|
||||||
|
extern void Analyze_Server_Packet (byte *data, int len);
|
||||||
byte *data = Hunk_TempAlloc (MAX_MSGLEN + 8);
|
byte *data = Hunk_TempAlloc (MAX_MSGLEN + 8);
|
||||||
|
|
||||||
memset (data, 0, 8);
|
memset (data, 0, 8);
|
||||||
|
|
|
@ -54,7 +54,6 @@ static const char rcsid[] =
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "bothdefs.h"
|
#include "bothdefs.h"
|
||||||
#include "msg_ucmd.h"
|
#include "msg_ucmd.h"
|
||||||
#include "net_svc.h"
|
|
||||||
#include "pmove.h"
|
#include "pmove.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "sv_progs.h"
|
#include "sv_progs.h"
|
||||||
|
@ -97,7 +96,7 @@ void
|
||||||
SV_New_f (void)
|
SV_New_f (void)
|
||||||
{
|
{
|
||||||
const char *gamedir;
|
const char *gamedir;
|
||||||
net_svc_serverdata_t block;
|
int playernum;
|
||||||
|
|
||||||
if (host_client->state == cs_spawned)
|
if (host_client->state == cs_spawned)
|
||||||
return;
|
return;
|
||||||
|
@ -116,23 +115,37 @@ SV_New_f (void)
|
||||||
//NOTE: This doesn't go through ClientReliableWrite since it's before the user
|
//NOTE: This doesn't go through ClientReliableWrite since it's before the user
|
||||||
//spawns. These functions are written to not overflow
|
//spawns. These functions are written to not overflow
|
||||||
if (host_client->num_backbuf) {
|
if (host_client->num_backbuf) {
|
||||||
SV_Printf ("WARNING %s: [SV_New] Back buffered (%d), clearing\n",
|
SV_Printf ("WARNING %s: [SV_New] Back buffered (%d0, clearing\n",
|
||||||
host_client->name, host_client->netchan.message.cursize);
|
host_client->name, host_client->netchan.message.cursize);
|
||||||
host_client->num_backbuf = 0;
|
host_client->num_backbuf = 0;
|
||||||
SZ_Clear (&host_client->netchan.message);
|
SZ_Clear (&host_client->netchan.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the serverdata
|
// send the serverdata
|
||||||
block.protocolversion = PROTOCOL_VERSION;
|
|
||||||
block.servercount = svs.spawncount;
|
|
||||||
block.gamedir = gamedir;
|
|
||||||
block.playernum = NUM_FOR_EDICT (&sv_pr_state, host_client->edict) - 1;
|
|
||||||
block.spectator = host_client->spectator;
|
|
||||||
block.levelname = PR_GetString (&sv_pr_state,
|
|
||||||
SVstring (sv.edicts, message));
|
|
||||||
block.movevars = movevars;
|
|
||||||
MSG_WriteByte (&host_client->netchan.message, svc_serverdata);
|
MSG_WriteByte (&host_client->netchan.message, svc_serverdata);
|
||||||
NET_SVC_ServerData_Emit (&block, &host_client->netchan.message);
|
MSG_WriteLong (&host_client->netchan.message, PROTOCOL_VERSION);
|
||||||
|
MSG_WriteLong (&host_client->netchan.message, svs.spawncount);
|
||||||
|
MSG_WriteString (&host_client->netchan.message, gamedir);
|
||||||
|
|
||||||
|
playernum = NUM_FOR_EDICT (&sv_pr_state, host_client->edict) - 1;
|
||||||
|
if (host_client->spectator)
|
||||||
|
playernum |= 128;
|
||||||
|
MSG_WriteByte (&host_client->netchan.message, playernum);
|
||||||
|
|
||||||
|
// send full levelname
|
||||||
|
MSG_WriteString (&host_client->netchan.message,
|
||||||
|
PR_GetString (&sv_pr_state, SVstring (sv.edicts, message)));
|
||||||
|
|
||||||
|
// send the movevars
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.gravity);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.stopspeed);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.maxspeed);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.spectatormaxspeed);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.accelerate);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.airaccelerate);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.wateraccelerate);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.friction);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.waterfriction);
|
||||||
|
MSG_WriteFloat (&host_client->netchan.message, movevars.entgravity);
|
||||||
|
|
||||||
// send music
|
// send music
|
||||||
MSG_WriteByte (&host_client->netchan.message, svc_cdtrack);
|
MSG_WriteByte (&host_client->netchan.message, svc_cdtrack);
|
||||||
|
@ -152,14 +165,12 @@ void
|
||||||
SV_Soundlist_f (void)
|
SV_Soundlist_f (void)
|
||||||
{
|
{
|
||||||
const char **s;
|
const char **s;
|
||||||
int i, size;
|
unsigned n;
|
||||||
net_svc_soundlist_t block;
|
|
||||||
|
|
||||||
if (host_client->state != cs_connected) {
|
if (host_client->state != cs_connected) {
|
||||||
SV_Printf ("soundlist not valid -- already spawned\n");
|
SV_Printf ("soundlist not valid -- already spawned\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the case of a level changing while a client was connecting
|
// handle the case of a level changing while a client was connecting
|
||||||
if (atoi (Cmd_Argv (1)) != svs.spawncount) {
|
if (atoi (Cmd_Argv (1)) != svs.spawncount) {
|
||||||
SV_Printf ("SV_Soundlist_f from different level\n");
|
SV_Printf ("SV_Soundlist_f from different level\n");
|
||||||
|
@ -167,40 +178,34 @@ SV_Soundlist_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
block.startsound = atoi (Cmd_Argv (2));
|
n = atoi (Cmd_Argv (2));
|
||||||
if (block.startsound >= MAX_SOUNDS) {
|
if (n >= MAX_SOUNDS) {
|
||||||
SV_Printf ("SV_Soundlist_f: Invalid soundlist index\n");
|
SV_Printf ("SV_Soundlist_f: Invalid soundlist index\n");
|
||||||
SV_New_f ();
|
SV_New_f ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//NOTE: This doesn't go through ClientReliableWrite since it's before the user
|
||||||
// NOTE: This doesn't go through ClientReliableWrite since it's
|
//spawns. These functions are written to not overflow
|
||||||
// before the user spawns. These functions are written to not
|
|
||||||
// overflow
|
|
||||||
if (host_client->num_backbuf) {
|
if (host_client->num_backbuf) {
|
||||||
SV_Printf ("WARNING %s: [SV_Soundlist] Back buffered (%d), clearing",
|
SV_Printf ("WARNING %s: [SV_Soundlist] Back buffered (%d0, clearing",
|
||||||
host_client->name, host_client->netchan.message.cursize);
|
host_client->name, host_client->netchan.message.cursize);
|
||||||
host_client->num_backbuf = 0;
|
host_client->num_backbuf = 0;
|
||||||
SZ_Clear (&host_client->netchan.message);
|
SZ_Clear (&host_client->netchan.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s = sv.sound_precache + 1 + block.startsound, i = 0, size = 0;
|
MSG_WriteByte (&host_client->netchan.message, svc_soundlist);
|
||||||
*s; i++, s++) {
|
MSG_WriteByte (&host_client->netchan.message, n);
|
||||||
if (host_client->netchan.message.cursize + size >= (MAX_MSGLEN / 2))
|
for (s = sv.sound_precache + 1 + n;
|
||||||
break;
|
*s && host_client->netchan.message.cursize < (MAX_MSGLEN / 2);
|
||||||
size += strlen (*s) + 1;
|
s++, n++) MSG_WriteString (&host_client->netchan.message, *s);
|
||||||
block.sounds[i] = *s;
|
|
||||||
}
|
MSG_WriteByte (&host_client->netchan.message, 0);
|
||||||
block.sounds[i] = "";
|
|
||||||
|
|
||||||
// next msg
|
// next msg
|
||||||
if (*s)
|
if (*s)
|
||||||
block.nextsound = block.startsound + i;
|
MSG_WriteByte (&host_client->netchan.message, n);
|
||||||
else
|
else
|
||||||
block.nextsound = 0;
|
MSG_WriteByte (&host_client->netchan.message, 0);
|
||||||
|
|
||||||
MSG_WriteByte (&host_client->netchan.message, svc_soundlist);
|
|
||||||
NET_SVC_Soundlist_Emit (&block, &host_client->netchan.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -210,14 +215,12 @@ void
|
||||||
SV_Modellist_f (void)
|
SV_Modellist_f (void)
|
||||||
{
|
{
|
||||||
const char **s;
|
const char **s;
|
||||||
int i, size;
|
unsigned n;
|
||||||
net_svc_modellist_t block;
|
|
||||||
|
|
||||||
if (host_client->state != cs_connected) {
|
if (host_client->state != cs_connected) {
|
||||||
SV_Printf ("modellist not valid -- already spawned\n");
|
SV_Printf ("modellist not valid -- already spawned\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the case of a level changing while a client was connecting
|
// handle the case of a level changing while a client was connecting
|
||||||
if (atoi (Cmd_Argv (1)) != svs.spawncount) {
|
if (atoi (Cmd_Argv (1)) != svs.spawncount) {
|
||||||
SV_Printf ("SV_Modellist_f from different level\n");
|
SV_Printf ("SV_Modellist_f from different level\n");
|
||||||
|
@ -225,40 +228,33 @@ SV_Modellist_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
block.startmodel = atoi (Cmd_Argv (2));
|
n = atoi (Cmd_Argv (2));
|
||||||
if (block.startmodel >= MAX_MODELS) {
|
if (n >= MAX_MODELS) {
|
||||||
SV_Printf ("SV_Modellist_f: Invalid modellist index\n");
|
SV_Printf ("SV_Modellist_f: Invalid modellist index\n");
|
||||||
SV_New_f ();
|
SV_New_f ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//NOTE: This doesn't go through ClientReliableWrite since it's before the user
|
||||||
// NOTE: This doesn't go through ClientReliableWrite since it's
|
//spawns. These functions are written to not overflow
|
||||||
// before the user spawns. These functions are written to not
|
|
||||||
// overflow
|
|
||||||
if (host_client->num_backbuf) {
|
if (host_client->num_backbuf) {
|
||||||
SV_Printf ("WARNING %s: [SV_Modellist] Back buffered (%d), clearing",
|
SV_Printf ("WARNING %s: [SV_Modellist] Back buffered (%d0, clearing",
|
||||||
host_client->name, host_client->netchan.message.cursize);
|
host_client->name, host_client->netchan.message.cursize);
|
||||||
host_client->num_backbuf = 0;
|
host_client->num_backbuf = 0;
|
||||||
SZ_Clear (&host_client->netchan.message);
|
SZ_Clear (&host_client->netchan.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s = sv.model_precache + 1 + block.startmodel, i = 0, size = 0;
|
MSG_WriteByte (&host_client->netchan.message, svc_modellist);
|
||||||
*s; i++, s++) {
|
MSG_WriteByte (&host_client->netchan.message, n);
|
||||||
if (host_client->netchan.message.cursize + size >= (MAX_MSGLEN / 2))
|
for (s = sv.model_precache + 1 + n;
|
||||||
break;
|
*s && host_client->netchan.message.cursize < (MAX_MSGLEN / 2);
|
||||||
size += strlen (*s) + 1;
|
s++, n++) MSG_WriteString (&host_client->netchan.message, *s);
|
||||||
block.models[i] = *s;
|
MSG_WriteByte (&host_client->netchan.message, 0);
|
||||||
}
|
|
||||||
block.models[i] = "";
|
|
||||||
|
|
||||||
// next msg
|
// next msg
|
||||||
if (*s)
|
if (*s)
|
||||||
block.nextmodel = block.startmodel + i;
|
MSG_WriteByte (&host_client->netchan.message, n);
|
||||||
else
|
else
|
||||||
block.nextmodel = 0;
|
MSG_WriteByte (&host_client->netchan.message, 0);
|
||||||
|
|
||||||
MSG_WriteByte (&host_client->netchan.message, svc_modellist);
|
|
||||||
NET_SVC_Modellist_Emit (&block, &host_client->netchan.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -566,27 +562,27 @@ void
|
||||||
SV_NextDownload_f (void)
|
SV_NextDownload_f (void)
|
||||||
{
|
{
|
||||||
byte buffer[1024];
|
byte buffer[1024];
|
||||||
net_svc_download_t block;
|
int r;
|
||||||
|
int percent;
|
||||||
|
int size;
|
||||||
|
|
||||||
if (!host_client->download)
|
if (!host_client->download)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
block.size = host_client->downloadsize - host_client->downloadcount;
|
r = host_client->downloadsize - host_client->downloadcount;
|
||||||
if (block.size > 768)
|
if (r > 768)
|
||||||
block.size = 768;
|
r = 768;
|
||||||
block.size = Qread (host_client->download, buffer, block.size);
|
r = Qread (host_client->download, buffer, r);
|
||||||
|
ClientReliableWrite_Begin (host_client, svc_download, 6 + r);
|
||||||
|
ClientReliableWrite_Short (host_client, r);
|
||||||
|
|
||||||
host_client->downloadcount += block.size;
|
host_client->downloadcount += r;
|
||||||
block.percent = host_client->downloadcount * 100 /
|
size = host_client->downloadsize;
|
||||||
(host_client->downloadsize ?: 1);
|
if (!size)
|
||||||
|
size = 1;
|
||||||
block.data = buffer;
|
percent = host_client->downloadcount * 100 / size;
|
||||||
ClientReliableWrite_Begin (host_client, svc_download, 6 + block.size);
|
ClientReliableWrite_Byte (host_client, percent);
|
||||||
if (host_client->num_backbuf) {
|
ClientReliableWrite_SZ (host_client, buffer, r);
|
||||||
NET_SVC_Download_Emit (&block, &host_client->backbuf);
|
|
||||||
ClientReliable_FinishWrite (host_client);
|
|
||||||
} else
|
|
||||||
NET_SVC_Download_Emit (&block, &host_client->netchan.message);
|
|
||||||
|
|
||||||
if (host_client->downloadcount != host_client->downloadsize)
|
if (host_client->downloadcount != host_client->downloadsize)
|
||||||
return;
|
return;
|
||||||
|
@ -695,7 +691,6 @@ SV_BeginDownload_f (void)
|
||||||
int size;
|
int size;
|
||||||
char realname[MAX_OSPATH];
|
char realname[MAX_OSPATH];
|
||||||
int zip;
|
int zip;
|
||||||
net_svc_download_t block;
|
|
||||||
|
|
||||||
name = Cmd_Argv (1);
|
name = Cmd_Argv (1);
|
||||||
// hacked by zoid to allow more conrol over download
|
// hacked by zoid to allow more conrol over download
|
||||||
|
@ -713,14 +708,9 @@ SV_BeginDownload_f (void)
|
||||||
|| (strncmp (name, "maps/", 5) == 0 && !allow_download_maps->int_val)
|
|| (strncmp (name, "maps/", 5) == 0 && !allow_download_maps->int_val)
|
||||||
// MUST be in a subdirectory
|
// MUST be in a subdirectory
|
||||||
|| !strstr (name, "/")) { // don't allow anything with .. path
|
|| !strstr (name, "/")) { // don't allow anything with .. path
|
||||||
block.size = -1;
|
|
||||||
block.percent = 0;
|
|
||||||
ClientReliableWrite_Begin (host_client, svc_download, 4);
|
ClientReliableWrite_Begin (host_client, svc_download, 4);
|
||||||
if (host_client->num_backbuf) {
|
ClientReliableWrite_Short (host_client, -1);
|
||||||
NET_SVC_Download_Emit (&block, &host_client->backbuf);
|
ClientReliableWrite_Byte (host_client, 0);
|
||||||
ClientReliable_FinishWrite (host_client);
|
|
||||||
} else
|
|
||||||
NET_SVC_Download_Emit (&block, &host_client->netchan.message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,30 +746,19 @@ SV_BeginDownload_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_Printf ("Couldn't download %s to %s\n", name, host_client->name);
|
SV_Printf ("Couldn't download %s to %s\n", name, host_client->name);
|
||||||
|
|
||||||
block.size = -1;
|
|
||||||
block.percent = 0;
|
|
||||||
ClientReliableWrite_Begin (host_client, svc_download, 4);
|
ClientReliableWrite_Begin (host_client, svc_download, 4);
|
||||||
if (host_client->num_backbuf) {
|
ClientReliableWrite_Short (host_client, -1);
|
||||||
NET_SVC_Download_Emit (&block, &host_client->backbuf);
|
ClientReliableWrite_Byte (host_client, 0);
|
||||||
ClientReliable_FinishWrite (host_client);
|
|
||||||
} else
|
|
||||||
NET_SVC_Download_Emit (&block, &host_client->netchan.message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zip && strcmp (realname, name)) {
|
if (zip && strcmp (realname, name)) {
|
||||||
SV_Printf ("download renamed to %s\n", realname);
|
SV_Printf ("download renamed to %s\n", realname);
|
||||||
|
|
||||||
block.size = -2;
|
|
||||||
block.percent = 0;
|
|
||||||
block.name = realname;
|
|
||||||
ClientReliableWrite_Begin (host_client, svc_download,
|
ClientReliableWrite_Begin (host_client, svc_download,
|
||||||
strlen (realname) + 5);
|
strlen (realname) + 5);
|
||||||
if (host_client->num_backbuf)
|
ClientReliableWrite_Short (host_client, -2);
|
||||||
NET_SVC_Download_Emit (&block, &host_client->backbuf);
|
ClientReliableWrite_Byte (host_client, 0);
|
||||||
else
|
ClientReliableWrite_String (host_client, realname);
|
||||||
NET_SVC_Download_Emit (&block, &host_client->netchan.message);
|
|
||||||
ClientReliable_FinishWrite (host_client);
|
ClientReliable_FinishWrite (host_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,8 +1115,6 @@ SV_Msg_f (void)
|
||||||
void
|
void
|
||||||
SV_SetInfo_f (void)
|
SV_SetInfo_f (void)
|
||||||
{
|
{
|
||||||
net_svc_setinfo_t block;
|
|
||||||
|
|
||||||
if (Cmd_Argc () == 1) {
|
if (Cmd_Argc () == 1) {
|
||||||
SV_Printf ("User info settings:\n");
|
SV_Printf ("User info settings:\n");
|
||||||
Info_Print (host_client->userinfo);
|
Info_Print (host_client->userinfo);
|
||||||
|
@ -1176,11 +1153,12 @@ SV_SetInfo_f (void)
|
||||||
SV_ExtractFromUserinfo (host_client);
|
SV_ExtractFromUserinfo (host_client);
|
||||||
|
|
||||||
if (Info_FilterForKey (Cmd_Argv (1), client_info_filters)) {
|
if (Info_FilterForKey (Cmd_Argv (1), client_info_filters)) {
|
||||||
block.slot = host_client - svs.clients;
|
|
||||||
block.key = Cmd_Argv (1);
|
|
||||||
block.value = Info_ValueForKey (host_client->userinfo, Cmd_Argv (1));
|
|
||||||
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
|
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
|
||||||
NET_SVC_SetInfo_Emit (&block, &sv.reliable_datagram);
|
MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
|
||||||
|
MSG_WriteString (&sv.reliable_datagram, Cmd_Argv (1));
|
||||||
|
MSG_WriteString (&sv.reliable_datagram,
|
||||||
|
Info_ValueForKey (host_client->userinfo,
|
||||||
|
Cmd_Argv (1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1839,7 +1817,7 @@ SV_UserInit (void)
|
||||||
"Toggles the ability of spectators to talk to players");
|
"Toggles the ability of spectators to talk to players");
|
||||||
sv_mapcheck = Cvar_Get ("sv_mapcheck", "1", CVAR_NONE, NULL,
|
sv_mapcheck = Cvar_Get ("sv_mapcheck", "1", CVAR_NONE, NULL,
|
||||||
"Toggle the use of map checksumming to check for players who edit maps to cheat");
|
"Toggle the use of map checksumming to check for players who edit maps to cheat");
|
||||||
sv_kickfake = Cvar_Get ("sv_kickfake", "0", CVAR_NONE, NULL,
|
sv_kickfake = Cvar_Get ("sv_kickfake", "1", CVAR_NONE, NULL,
|
||||||
"Kick users sending to send fake talk messages");
|
"Kick users sending to send fake talk messages");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue