mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +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_MODELS 256 // these are sent over the net as bytes
|
||||
#define MAX_SOUNDS 256 // so they cannot be blindly increased
|
||||
#define MAX_PROJECTILES 32
|
||||
|
||||
#define SAVEGAME_COMMENT_LENGTH 39
|
||||
|
||||
#define MAX_STYLESTRING 64
|
||||
|
||||
//
|
||||
// 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_ClearProjectiles (void);
|
||||
void CL_ParseProjectiles (void);
|
||||
void CL_ParsePacketEntities (void);
|
||||
void CL_ParseDeltaPacketEntities ();
|
||||
void CL_ParsePacketEntities (qboolean delta);
|
||||
void CL_SetSolidEntities (void);
|
||||
void CL_ParsePlayerinfo (void);
|
||||
void CL_Ents_Init (void);
|
||||
|
|
|
@ -338,7 +338,7 @@ void CL_UpdateScreen (double realtime);
|
|||
|
||||
void CL_SetState (cactive_t state);
|
||||
|
||||
void CL_ParseDamage (void);
|
||||
void V_ParseDamage (void);
|
||||
|
||||
void V_PrepBlend (void);
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ void Host_InitCommands (void);
|
|||
void Host_Init (void);
|
||||
void Host_Shutdown(void);
|
||||
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_Frame (float time);
|
||||
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_Outgoing_Packet (const char *p, int len);
|
||||
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;
|
||||
|
||||
|
|
|
@ -214,22 +214,6 @@
|
|||
#define U_UNUSED30 (1<<30) // 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
|
||||
|
|
|
@ -499,7 +499,7 @@ void SV_SendClientMessages (void);
|
|||
|
||||
void SV_Multicast (vec3_t origin, int to);
|
||||
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_BroadcastPrintf (int level, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -265,8 +265,8 @@ CL_GetDemoMessage (void)
|
|||
(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
|
||||
Host_Error ("Demo message > MAX_MSGLEN + 8: %d/%d",
|
||||
net_message->message->cursize, MAX_MSGLEN + 8);
|
||||
Host_EndGame ("Demo message > MAX_MSGLEN + 8: %d/%d",
|
||||
net_message->message->cursize, MAX_MSGLEN + 8);
|
||||
r = Qread (cls.demofile, net_message->message->data,
|
||||
net_message->message->cursize);
|
||||
if (r != net_message->message->cursize) {
|
||||
|
|
|
@ -43,7 +43,6 @@ static const char rcsid[] =
|
|||
#include "QF/render.h"
|
||||
#include "QF/skin.h"
|
||||
|
||||
#include "bothdefs.h"
|
||||
#include "cl_cam.h"
|
||||
#include "cl_ents.h"
|
||||
#include "cl_main.h"
|
||||
|
@ -54,7 +53,6 @@ static const char rcsid[] =
|
|||
#include "d_iface.h"
|
||||
#include "host.h"
|
||||
#include "msg_ucmd.h"
|
||||
#include "net_svc.h"
|
||||
#include "pmove.h"
|
||||
#include "r_cvar.h"
|
||||
#include "r_dynamic.h"
|
||||
|
@ -71,7 +69,6 @@ entity_t cl_flag_ents[MAX_CLIENTS];
|
|||
entity_t cl_player_ents[MAX_CLIENTS];
|
||||
|
||||
|
||||
|
||||
void
|
||||
CL_ClearEnts ()
|
||||
{
|
||||
|
@ -127,168 +124,221 @@ CL_NewDlight (int key, vec3_t org, int effects)
|
|||
|
||||
int bitcounts[32]; // / just for protocol profiling
|
||||
|
||||
/*
|
||||
CL_ParseDelta
|
||||
|
||||
Can go from either a baseline or a previous packet_entity
|
||||
*/
|
||||
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)
|
||||
dest->modelindex = src->modelindex;
|
||||
to->modelindex = MSG_ReadByte (net_message);
|
||||
|
||||
if (bits & U_FRAME)
|
||||
dest->frame = (dest->frame & 0xFF00) | (src->frame & 0xFF);
|
||||
to->frame = MSG_ReadByte (net_message);
|
||||
|
||||
if (bits & U_COLORMAP)
|
||||
dest->colormap = src->colormap;
|
||||
to->colormap = MSG_ReadByte (net_message);
|
||||
|
||||
if (bits & U_SKIN)
|
||||
dest->skinnum = src->skinnum;
|
||||
to->skinnum = MSG_ReadByte (net_message);
|
||||
|
||||
if (bits & U_EFFECTS)
|
||||
dest->effects = (dest->effects & 0xFF00) | (src->effects & 0xFF);
|
||||
to->effects = MSG_ReadByte (net_message);
|
||||
|
||||
if (bits & U_ORIGIN1)
|
||||
dest->origin[0] = src->origin[0];
|
||||
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];
|
||||
to->origin[0] = MSG_ReadCoord (net_message);
|
||||
|
||||
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)
|
||||
dest->alpha = src->alpha;
|
||||
to->alpha = MSG_ReadByte (net_message);
|
||||
if (bits & U_SCALE)
|
||||
dest->scale = src->scale;
|
||||
to->scale = MSG_ReadByte (net_message);
|
||||
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)
|
||||
dest->glow_size = src->glow_size;
|
||||
to->glow_size = MSG_ReadByte (net_message);
|
||||
if (bits & U_GLOWCOLOR)
|
||||
dest->glow_color = src->glow_color;
|
||||
to->glow_color = MSG_ReadByte (net_message);
|
||||
if (bits & U_COLORMOD)
|
||||
dest->colormod = src->colormod;
|
||||
to->colormod = MSG_ReadByte (net_message);
|
||||
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) {
|
||||
// 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
|
||||
CL_ParsePacketEntities (void)
|
||||
FlushEntityPacket (void)
|
||||
{
|
||||
int index, packetnum;
|
||||
packet_entities_t *newp;
|
||||
net_svc_packetentities_t block;
|
||||
entity_state_t olde, newe;
|
||||
int word;
|
||||
|
||||
packetnum = cls.netchan.incoming_sequence & UPDATE_MASK;
|
||||
newp = &cl.frames[packetnum].packet_entities;
|
||||
cl.frames[packetnum].invalid = false;
|
||||
Con_DPrintf ("FlushEntityPacket\n");
|
||||
|
||||
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)) {
|
||||
Host_NetError ("CL_ParsePacketEntities: Bad Read");
|
||||
return;
|
||||
// read it all, but ignore it
|
||||
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;
|
||||
}
|
||||
|
||||
if (!word)
|
||||
break; // done
|
||||
|
||||
CL_ParseDelta (&olde, &newe, word);
|
||||
}
|
||||
|
||||
for (index = 0; block.words[index]; index++) {
|
||||
if (block.words[index] & U_REMOVE) {
|
||||
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) {
|
||||
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
|
||||
rest of the data stream.
|
||||
*/
|
||||
void
|
||||
CL_ParseDeltaPacketEntities ()
|
||||
CL_ParsePacketEntities (qboolean delta)
|
||||
{
|
||||
int oldindex = 0, newindex = 0;
|
||||
int wordindex = 0, deltaindex = 0;
|
||||
int oldnum, newnum;
|
||||
int oldpacket, newpacket;
|
||||
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;
|
||||
}
|
||||
byte from;
|
||||
int oldindex, newindex, newnum, oldnum, oldpacket, newpacket, word;
|
||||
packet_entities_t *oldp, *newp, dummy;
|
||||
qboolean full;
|
||||
|
||||
newpacket = cls.netchan.incoming_sequence & UPDATE_MASK;
|
||||
newp = &cl.frames[newpacket].packet_entities;
|
||||
cl.frames[newpacket].invalid = false;
|
||||
|
||||
oldpacket = cl.frames[newpacket].delta_sequence;
|
||||
if (delta) {
|
||||
from = MSG_ReadByte (net_message);
|
||||
|
||||
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) {
|
||||
// we can't use this, it is too old
|
||||
Con_DPrintf ("CL_ParseDeltaPacketEntities: old packet\n");
|
||||
cl.validsequence = 0; // can't render a frame
|
||||
cl.frames[newpacket].invalid = true;
|
||||
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;
|
||||
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) {
|
||||
// we can't use this, it is too old
|
||||
FlushEntityPacket ();
|
||||
return;
|
||||
}
|
||||
cl.validsequence = cls.netchan.incoming_sequence;
|
||||
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;
|
||||
}
|
||||
|
||||
cl.validsequence = cls.netchan.incoming_sequence;
|
||||
oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities;
|
||||
|
||||
oldindex = 0;
|
||||
newindex = 0;
|
||||
newp->num_entities = 0;
|
||||
|
||||
for (; block.words[wordindex];) {
|
||||
newnum = block.words[wordindex] & 511;
|
||||
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;
|
||||
}
|
||||
|
||||
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 :
|
||||
oldp->entities[oldindex].number;
|
||||
|
||||
while (newnum > oldnum) { // copy one of the old entities
|
||||
// over to the new packet unchanged
|
||||
// Con_Printf ("copy %i\n", oldnum);
|
||||
if (newindex >= MAX_PACKET_ENTITIES) {
|
||||
Host_NetError ("CL_ParseDeltaPacketEntities: newindex >= "
|
||||
"MAX_PACKET_ENTITIES (1st)");
|
||||
while (newnum > oldnum) {
|
||||
if (full) {
|
||||
Con_Printf ("WARNING: oldcopy on full update");
|
||||
FlushEntityPacket ();
|
||||
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];
|
||||
newindex++;
|
||||
oldindex++;
|
||||
|
@ -298,74 +348,44 @@ CL_ParseDeltaPacketEntities ()
|
|||
|
||||
if (newnum < oldnum) { // new from baseline
|
||||
// Con_Printf ("baseline %i\n", newnum);
|
||||
if (block.words[wordindex] & U_REMOVE) {
|
||||
wordindex++;
|
||||
if (word & U_REMOVE) {
|
||||
if (full) {
|
||||
cl.validsequence = 0;
|
||||
Con_Printf ("WARNING: U_REMOVE on full update\n");
|
||||
FlushEntityPacket ();
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newindex >= MAX_PACKET_ENTITIES) {
|
||||
Host_NetError ("CL_ParseDeltaPacketEntities: newindex >= "
|
||||
"MAX_PACKET_ENTITIES (2nd)");
|
||||
return;
|
||||
}
|
||||
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++;
|
||||
if (newindex >= MAX_PACKET_ENTITIES)
|
||||
Host_EndGame ("CL_ParsePacketEntities: newindex == "
|
||||
"MAX_PACKET_ENTITIES");
|
||||
CL_ParseDelta (&cl_baselines[newnum], &newp->entities[newindex],
|
||||
word);
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newnum == oldnum) { // delta from previous
|
||||
// Con_Printf ("delta %i\n", newnum);
|
||||
if (block.words[wordindex] & U_REMOVE) { // Clear the entity
|
||||
memset (&cl_packet_ents[newnum], 0, sizeof (entity_t));
|
||||
wordindex++;
|
||||
if (full) {
|
||||
cl.validsequence = 0;
|
||||
Con_Printf ("WARNING: delta on full update");
|
||||
}
|
||||
if (word & U_REMOVE) { // Clear the entity
|
||||
entity_t *ent = &cl_packet_ents[newnum];
|
||||
memset (ent, 0, sizeof (entity_t));
|
||||
oldindex++;
|
||||
continue;
|
||||
}
|
||||
newp->entities[newindex] = oldp->entities[oldindex];
|
||||
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++;
|
||||
// Con_Printf ("delta %i\n", newnum);
|
||||
CL_ParseDelta (&oldp->entities[oldindex],
|
||||
&newp->entities[newindex], word);
|
||||
newindex++;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -523,6 +543,7 @@ typedef struct {
|
|||
entity_t ent;
|
||||
} projectile_t;
|
||||
|
||||
#define MAX_PROJECTILES 32
|
||||
projectile_t cl_projectiles[MAX_PROJECTILES];
|
||||
int cl_num_projectiles;
|
||||
|
||||
|
@ -540,25 +561,27 @@ CL_ClearProjectiles (void)
|
|||
void
|
||||
CL_ParseProjectiles (void)
|
||||
{
|
||||
int i;
|
||||
byte bits[6];
|
||||
int i, c, j;
|
||||
projectile_t *pr;
|
||||
net_svc_nails_t block;
|
||||
|
||||
if (NET_SVC_Nails_Parse (&block, net_message)) {
|
||||
Host_NetError ("CL_ParseProjectiles: Bad Read\n");
|
||||
return;
|
||||
}
|
||||
c = MSG_ReadByte (net_message);
|
||||
for (i = 0; i < c; i++) {
|
||||
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)
|
||||
break;
|
||||
continue;
|
||||
|
||||
pr = &cl_projectiles[cl_num_projectiles];
|
||||
cl_num_projectiles++;
|
||||
|
||||
pr->modelindex = cl_spikeindex;
|
||||
VectorCopy (block.nails[i].origin, pr->ent.origin);
|
||||
VectorCopy (block.nails[i].angles, pr->ent.angles);
|
||||
pr->ent.origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
|
||||
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
|
||||
CL_ParsePlayerinfo (void)
|
||||
{
|
||||
int flags, msec, num, i;
|
||||
player_state_t *state;
|
||||
net_svc_playerinfo_t block;
|
||||
|
||||
if (NET_SVC_Playerinfo_Parse (&block, net_message)) {
|
||||
Host_NetError ("CL_ParsePlayerinfo: Bad Read\n");
|
||||
return;
|
||||
}
|
||||
num = MSG_ReadByte (net_message);
|
||||
if (num > MAX_CLIENTS)
|
||||
// Sys_Error ("CL_ParsePlayerinfo: bad num");
|
||||
Host_EndGame ("CL_ParsePlayerinfo: bad num");
|
||||
|
||||
if (block.playernum >= MAX_CLIENTS) {
|
||||
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[num];
|
||||
|
||||
state = &cl.frames[parsecountmod].playerstate[block.playernum];
|
||||
|
||||
state->number = block.playernum;
|
||||
state->flags = block.flags;
|
||||
state->number = num;
|
||||
flags = state->flags = MSG_ReadShort (net_message);
|
||||
|
||||
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
|
||||
// before the packet was sent out, so accurately track
|
||||
// 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)
|
||||
memcpy (&state->command, &block.usercmd, sizeof (state->command));
|
||||
if (flags & PF_COMMAND)
|
||||
MSG_ReadDeltaUsercmd (&nullcmd, &state->command);
|
||||
|
||||
VectorCopy (block.velocity, state->velocity);
|
||||
|
||||
if (block.flags & PF_MODEL)
|
||||
state->modelindex = block.modelindex;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (flags & (PF_VELOCITY1 << i))
|
||||
state->velocity[i] = MSG_ReadShort (net_message);
|
||||
else
|
||||
state->velocity[i] = 0;
|
||||
}
|
||||
if (flags & PF_MODEL)
|
||||
state->modelindex = MSG_ReadByte (net_message);
|
||||
else
|
||||
state->modelindex = cl_playerindex;
|
||||
|
||||
state->skinnum = block.skinnum;
|
||||
state->effects = block.effects;
|
||||
state->weaponframe = block.weaponframe;
|
||||
if (flags & PF_SKINNUM)
|
||||
state->skinnum = MSG_ReadByte (net_message);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1318,34 +1318,6 @@ Host_EndGame (const char *message, ...)
|
|||
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
|
||||
|
||||
|
|
1238
qw/source/cl_parse.c
1238
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;
|
||||
|
||||
if (slot > MAX_CLIENTS)
|
||||
Host_NetError ("CL_NewTranslation: slot > MAX_CLIENTS");
|
||||
Host_EndGame ("CL_NewTranslation: slot > MAX_CLIENTS");
|
||||
|
||||
player = &cl.players[slot];
|
||||
if (!player->name[0])
|
||||
|
|
|
@ -50,8 +50,6 @@ static const char rcsid[] =
|
|||
#include "cl_main.h"
|
||||
#include "cl_tent.h"
|
||||
#include "client.h"
|
||||
#include "host.h"
|
||||
#include "net_svc.h"
|
||||
#include "r_dynamic.h"
|
||||
|
||||
#define MAX_BEAMS 8
|
||||
|
@ -184,37 +182,42 @@ CL_AllocExplosion (void)
|
|||
}
|
||||
|
||||
void
|
||||
CL_ParseBeam (net_svc_tempentity_t *tempentity, model_t *m)
|
||||
CL_ParseBeam (model_t *m)
|
||||
{
|
||||
beam_t *b;
|
||||
int i;
|
||||
int ent, i;
|
||||
vec3_t start, end;
|
||||
|
||||
if (tempentity->beamentity >= MAX_EDICTS) {
|
||||
Host_NetError ("CL_ParseBeam: beamentity %i >= MAX_EDICTS",
|
||||
tempentity->beamentity);
|
||||
return;
|
||||
}
|
||||
ent = MSG_ReadShort (net_message);
|
||||
|
||||
start[0] = MSG_ReadCoord (net_message);
|
||||
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
|
||||
for (i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++)
|
||||
if (b->entity == tempentity->beamentity) {
|
||||
b->entity = tempentity->beamentity;
|
||||
if (b->entity == ent) {
|
||||
b->entity = ent;
|
||||
b->model = m;
|
||||
b->endtime = cl.time + 0.2;
|
||||
b->seed = rand();
|
||||
VectorCopy (tempentity->position, b->start);
|
||||
VectorCopy (tempentity->beamend, b->end);
|
||||
VectorCopy (start, b->start);
|
||||
VectorCopy (end, b->end);
|
||||
return;
|
||||
}
|
||||
// find a free beam
|
||||
for (i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++) {
|
||||
if (!b->model || b->endtime < cl.time) {
|
||||
b->entity = tempentity->beamentity;
|
||||
b->entity = ent;
|
||||
b->model = m;
|
||||
b->endtime = cl.time + 0.2;
|
||||
b->seed = rand();
|
||||
VectorCopy (tempentity->position, b->start);
|
||||
VectorCopy (tempentity->beamend, b->end);
|
||||
VectorCopy (start, b->start);
|
||||
VectorCopy (end, b->end);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -224,66 +227,79 @@ CL_ParseBeam (net_svc_tempentity_t *tempentity, model_t *m)
|
|||
void
|
||||
CL_ParseTEnt (void)
|
||||
{
|
||||
byte type;
|
||||
dlight_t *dl;
|
||||
explosion_t *ex;
|
||||
int rnd;
|
||||
net_svc_tempentity_t tempentity;
|
||||
int colorStart, colorLength, rnd;
|
||||
int cnt = -1;
|
||||
vec3_t pos;
|
||||
|
||||
if (NET_SVC_TempEntity_Parse (&tempentity, net_message)) {
|
||||
Host_NetError ("CL_ParseTEnt: Bad Read\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (tempentity.type) {
|
||||
type = MSG_ReadByte (net_message);
|
||||
switch (type) {
|
||||
case TE_WIZSPIKE: // spike hitting wall
|
||||
R_RunSpikeEffect (tempentity.position, prot_to_rend[tempentity.type]);
|
||||
S_StartSound (-1, 0, cl_sfx_wizhit, tempentity.position, 1, 1);
|
||||
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]);
|
||||
S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
|
||||
break;
|
||||
|
||||
case TE_KNIGHTSPIKE: // spike hitting wall
|
||||
R_RunSpikeEffect (tempentity.position, prot_to_rend[tempentity.type]);
|
||||
S_StartSound (-1, 0, cl_sfx_knighthit, tempentity.position, 1, 1);
|
||||
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]);
|
||||
S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
|
||||
break;
|
||||
|
||||
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)
|
||||
S_StartSound (-1, 0, cl_sfx_tink1, tempentity.position, 1, 1);
|
||||
S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
|
||||
else {
|
||||
rnd = rand () & 3;
|
||||
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)
|
||||
S_StartSound (-1, 0, cl_sfx_ric2, tempentity.position, 1, 1);
|
||||
S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
|
||||
else
|
||||
S_StartSound (-1, 0, cl_sfx_ric3, tempentity.position, 1, 1);
|
||||
S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
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)
|
||||
S_StartSound (-1, 0, cl_sfx_tink1, tempentity.position, 1, 1);
|
||||
S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
|
||||
else {
|
||||
rnd = rand () & 3;
|
||||
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)
|
||||
S_StartSound (-1, 0, cl_sfx_ric2, tempentity.position, 1, 1);
|
||||
S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
|
||||
else
|
||||
S_StartSound (-1, 0, cl_sfx_ric3, tempentity.position, 1, 1);
|
||||
S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case TE_EXPLOSION: // rocket explosion
|
||||
// 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
|
||||
dl = R_AllocDlight (0);
|
||||
VectorCopy (tempentity.position, dl->origin);
|
||||
VectorCopy (pos, dl->origin);
|
||||
dl->radius = 350;
|
||||
dl->die = cl.time + 0.5;
|
||||
dl->decay = 300;
|
||||
|
@ -292,78 +308,94 @@ CL_ParseTEnt (void)
|
|||
dl->color[2] = 0.24;
|
||||
|
||||
// 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
|
||||
ex = CL_AllocExplosion ();
|
||||
VectorCopy (tempentity.position, ex->ent.origin);
|
||||
VectorCopy (pos, ex->ent.origin);
|
||||
ex->start = cl.time;
|
||||
ex->ent.model = cl_spr_explod;
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case TE_LIGHTNING1: // lightning bolts
|
||||
CL_ParseBeam (&tempentity, cl_mod_bolt);
|
||||
CL_ParseBeam (cl_mod_bolt);
|
||||
break;
|
||||
|
||||
case TE_LIGHTNING2: // lightning bolts
|
||||
CL_ParseBeam (&tempentity, cl_mod_bolt2);
|
||||
CL_ParseBeam (cl_mod_bolt2);
|
||||
break;
|
||||
|
||||
case TE_LIGHTNING3: // lightning bolts
|
||||
CL_ParseBeam (&tempentity, cl_mod_bolt3);
|
||||
CL_ParseBeam (cl_mod_bolt3);
|
||||
break;
|
||||
|
||||
// PGM 01/21/97
|
||||
case TE_BEAM: // grappling hook beam
|
||||
CL_ParseBeam (&tempentity, Mod_ForName ("progs/beam.mdl", true));
|
||||
CL_ParseBeam (Mod_ForName ("progs/beam.mdl", true));
|
||||
break;
|
||||
// PGM 01/21/97
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
case TE_EXPLOSION2: // color mapped explosion
|
||||
R_ParticleExplosion2 (tempentity.position,
|
||||
tempentity.colorstart,
|
||||
tempentity.colorlength);
|
||||
pos[0] = MSG_ReadCoord (net_message);
|
||||
pos[1] = MSG_ReadCoord (net_message);
|
||||
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);
|
||||
VectorCopy (tempentity.position, dl->origin);
|
||||
VectorCopy (pos, dl->origin);
|
||||
dl->radius = 350;
|
||||
dl->die = cl.time + 0.5;
|
||||
dl->decay = 300;
|
||||
dl->color[0] = vid_basepal[(tempentity.colorstart
|
||||
+ (rand() % tempentity.colorlength))
|
||||
* 3] * (1.0 / 255.0);
|
||||
dl->color[1] = vid_basepal[(tempentity.colorstart
|
||||
+ (rand() % tempentity.colorlength))
|
||||
* 3 + 1] * (1.0 / 255.0);
|
||||
dl->color[2] = vid_basepal[(tempentity.colorstart
|
||||
+ (rand() % tempentity.colorlength))
|
||||
* 3 + 2] * (1.0 / 255.0);
|
||||
S_StartSound (-1, 0, cl_sfx_r_exp3, tempentity.position, 1, 1);
|
||||
dl->color[0] = vid_basepal[(colorStart + (rand() % colorLength)) *
|
||||
3] * (1.0 / 255.0);
|
||||
dl->color[1] = vid_basepal[(colorStart + (rand() % colorLength)) *
|
||||
3 + 1] * (1.0 / 255.0);
|
||||
dl->color[2] = vid_basepal[(colorStart + (rand() % colorLength)) *
|
||||
3 + 2] * (1.0 / 255.0);
|
||||
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
|
||||
break;
|
||||
|
||||
case TE_GUNSHOT: // bullet hitting wall
|
||||
case TE_BLOOD: // bullets hitting body
|
||||
R_RunPuffEffect (tempentity.position, prot_to_rend[tempentity.type],
|
||||
tempentity.gunshotcount * 20);
|
||||
cnt = MSG_ReadByte (net_message) * 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;
|
||||
|
||||
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
|
||||
dl = R_AllocDlight (0);
|
||||
VectorCopy (tempentity.position, dl->origin);
|
||||
VectorCopy (pos, dl->origin);
|
||||
dl->radius = 150;
|
||||
dl->die = cl.time + 0.1;
|
||||
dl->decay = 200;
|
||||
|
@ -371,11 +403,11 @@ CL_ParseTEnt (void)
|
|||
dl->color[1] = 0.40;
|
||||
dl->color[2] = 0.65;
|
||||
|
||||
R_RunPuffEffect (tempentity.position, prot_to_rend[tempentity.type], 0);
|
||||
R_RunPuffEffect (pos, prot_to_rend[type], cnt);
|
||||
break;
|
||||
|
||||
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 "compat.h"
|
||||
#include "host.h"
|
||||
#include "net_svc.h"
|
||||
#include "pmove.h"
|
||||
#include "view.h"
|
||||
|
||||
|
@ -241,18 +240,18 @@ V_DriftPitch (void)
|
|||
/* PALETTE FLASHES */
|
||||
|
||||
void
|
||||
CL_ParseDamage (void)
|
||||
V_ParseDamage (void)
|
||||
{
|
||||
float count, side;
|
||||
vec3_t forward, right, up;
|
||||
net_svc_damage_t damage;
|
||||
int armor, blood, i;
|
||||
vec3_t forward, from, right, up;
|
||||
|
||||
if (NET_SVC_Damage_Parse (&damage, net_message)) {
|
||||
Host_NetError ("CL_ParseDamage: Bad Read\n");
|
||||
return;
|
||||
}
|
||||
armor = MSG_ReadByte (net_message);
|
||||
blood = MSG_ReadByte (net_message);
|
||||
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)
|
||||
count = 10;
|
||||
|
||||
|
@ -266,11 +265,11 @@ CL_ParseDamage (void)
|
|||
cl.cshifts[CSHIFT_DAMAGE].percent =
|
||||
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[1] = 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[1] = 50;
|
||||
cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50;
|
||||
|
@ -282,15 +281,15 @@ CL_ParseDamage (void)
|
|||
}
|
||||
|
||||
// calculate view angle kicks
|
||||
VectorSubtract (damage.from, cl.simorg, damage.from);
|
||||
VectorNormalize (damage.from);
|
||||
VectorSubtract (from, cl.simorg, from);
|
||||
VectorNormalize (from);
|
||||
|
||||
AngleVectors (cl.simangles, forward, right, up);
|
||||
|
||||
side = DotProduct (damage.from, right);
|
||||
side = DotProduct (from, right);
|
||||
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_time = v_kicktime->value;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
net_packetlog.c
|
||||
net_packetlog.c
|
||||
|
||||
packet logging/parsing - for debugging and educational purposes
|
||||
packet logging/parsing - for debugging and educational purposes
|
||||
|
||||
**EXPERIMENTAL**
|
||||
**EXPERIMENTAL**
|
||||
|
||||
Copyright (C) 2000 Jukka Sorjonen <jukka.sorjonen@asikkala.fi>
|
||||
Copyright (C) 2000 Jukka Sorjonen <jukka.sorjonen@asikkala.fi>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
|
@ -56,7 +56,6 @@ static const char rcsid[] =
|
|||
|
||||
#include "compat.h"
|
||||
#include "net.h"
|
||||
#include "net_svc.h"
|
||||
#include "protocol.h"
|
||||
#include "server.h"
|
||||
|
||||
|
@ -65,12 +64,87 @@ cvar_t *net_loglevel;
|
|||
|
||||
int Net_LogStart (const char *fname);
|
||||
|
||||
void Analyze_Server_Packet (const byte *data, int len);
|
||||
void Analyze_Client_Packet (const byte *data, int len);
|
||||
void Analyze_Server_Packet (const byte * data, int len);
|
||||
void Analyze_Client_Packet (const byte * data, int len);
|
||||
void Parse_Server_Packet (void);
|
||||
void Parse_Client_Packet (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[] = {
|
||||
"clc_bad",
|
||||
"clc_nop",
|
||||
|
@ -95,6 +169,7 @@ const char *clc_string[] = {
|
|||
#define svc_particle 18 // [vec3] <variable>
|
||||
#define svc_signonnum 25 // [byte] used for the signon
|
||||
// sequence
|
||||
static VFile *_stdout;
|
||||
static VFile *Net_PacketLog;
|
||||
static const char **Net_sound_precache;
|
||||
static sizebuf_t _packet;
|
||||
|
@ -115,12 +190,11 @@ Net_LogPrintf (char *fmt, ...)
|
|||
va_start (argptr, fmt);
|
||||
vsnprintf (text, sizeof (text), fmt, argptr);
|
||||
va_end (argptr);
|
||||
if (!Net_PacketLog)
|
||||
return;
|
||||
|
||||
if (Net_PacketLog) {
|
||||
Qprintf (Net_PacketLog, "%s", text);
|
||||
Qflush (Net_PacketLog);
|
||||
} else
|
||||
Con_Printf ("%s", text);
|
||||
Qprintf (Net_PacketLog, "%s", text);
|
||||
Qflush (Net_PacketLog);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -230,113 +304,104 @@ Log_Outgoing_Packet (const char *p, int len)
|
|||
return;
|
||||
}
|
||||
|
||||
qboolean
|
||||
void
|
||||
Log_Delta(int bits)
|
||||
{
|
||||
entity_state_t to;
|
||||
int i;
|
||||
|
||||
Net_LogPrintf ("\n\t<%06x> ", MSG_GetReadCount (&packet) - 2);
|
||||
if (!bits) {
|
||||
Net_LogPrintf ("End");
|
||||
return 1;
|
||||
}
|
||||
Net_LogPrintf ("\n\t");
|
||||
|
||||
// set everything to the state we are delta'ing from
|
||||
|
||||
to.number = 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
|
||||
i = MSG_ReadByte (&packet);
|
||||
bits |= i;
|
||||
Net_LogPrintf (" U_MOREBITS");
|
||||
}
|
||||
|
||||
// LordHavoc: Endy neglected to mark this as being part of the QSG
|
||||
// version 2 stuff...
|
||||
if (bits & U_EXTEND1) {
|
||||
bits |= MSG_ReadByte (&packet) << 16;
|
||||
Net_LogPrintf (" U_EXTEND1");
|
||||
if (bits & U_EXTEND2) {
|
||||
if (bits & U_EXTEND2)
|
||||
bits |= MSG_ReadByte (&packet) << 24;
|
||||
Net_LogPrintf (" U_EXTEND2");
|
||||
}
|
||||
}
|
||||
|
||||
to.flags = bits;
|
||||
|
||||
if (bits & U_MODEL)
|
||||
Net_LogPrintf (" MdlIdx: %d", MSG_ReadByte (&packet));
|
||||
Net_LogPrintf (" MdlIdx: %d", MSG_ReadByte (&packet));
|
||||
|
||||
if (bits & U_FRAME) {
|
||||
to.frame = MSG_ReadByte (&packet);
|
||||
Net_LogPrintf (" Frame: %d", to.frame);
|
||||
}
|
||||
if (bits & U_FRAME) {
|
||||
to.frame = MSG_ReadByte (&packet);
|
||||
Net_LogPrintf (" Frame: %d", to.frame);
|
||||
}
|
||||
|
||||
if (bits & U_COLORMAP)
|
||||
Net_LogPrintf (" Colormap: %d", MSG_ReadByte (&packet));
|
||||
Net_LogPrintf (" Colormap: %d", MSG_ReadByte (&packet));
|
||||
|
||||
if (bits & U_SKIN)
|
||||
Net_LogPrintf (" Skinnum: %d", MSG_ReadByte (&packet));
|
||||
Net_LogPrintf (" Skinnum: %d", MSG_ReadByte (&packet));
|
||||
|
||||
if (bits & U_EFFECTS) {
|
||||
to.effects = MSG_ReadByte (&packet);
|
||||
Net_LogPrintf (" Effects: %d", to.effects);
|
||||
}
|
||||
if (bits & U_EFFECTS) {
|
||||
to.effects = MSG_ReadByte (&packet);
|
||||
Net_LogPrintf (" Effects: %d", to.effects);
|
||||
}
|
||||
|
||||
if (bits & U_ORIGIN1)
|
||||
Net_LogPrintf (" X: %f", MSG_ReadCoord (&packet));
|
||||
Net_LogPrintf (" X: %f", MSG_ReadCoord (&packet));
|
||||
|
||||
if (bits & U_ANGLE1)
|
||||
Net_LogPrintf (" Pitch: %d", MSG_ReadAngle (&packet));
|
||||
Net_LogPrintf (" Pitch: %d", MSG_ReadAngle (&packet));
|
||||
|
||||
if (bits & U_ORIGIN2)
|
||||
Net_LogPrintf (" Y: %f", MSG_ReadCoord (&packet));
|
||||
Net_LogPrintf (" Y: %f", MSG_ReadCoord (&packet));
|
||||
|
||||
if (bits & U_ANGLE2)
|
||||
Net_LogPrintf (" Yaw: %d", MSG_ReadAngle (&packet));
|
||||
Net_LogPrintf (" Yaw: %d", MSG_ReadAngle (&packet));
|
||||
|
||||
if (bits & U_ORIGIN3)
|
||||
Net_LogPrintf (" Z: %f", MSG_ReadCoord (&packet));
|
||||
Net_LogPrintf (" Z: %f", MSG_ReadCoord (&packet));
|
||||
|
||||
if (bits & U_ANGLE3)
|
||||
Net_LogPrintf (" Roll: %d", MSG_ReadAngle (&packet));
|
||||
Net_LogPrintf (" Roll: %d", MSG_ReadAngle (&packet));
|
||||
|
||||
// Ender (QSG - Begin)
|
||||
if (bits & U_ALPHA)
|
||||
Net_LogPrintf(" Alpha: %d", MSG_ReadByte (&packet));
|
||||
Net_LogPrintf(" Alpha: %d", MSG_ReadByte (&packet));
|
||||
if (bits & U_SCALE)
|
||||
Net_LogPrintf(" Scale: %d", MSG_ReadByte (&packet));
|
||||
Net_LogPrintf(" Scale: %d", MSG_ReadByte (&packet));
|
||||
if (bits & U_EFFECTS2)
|
||||
Net_LogPrintf(" U_EFFECTS2: %d", (to.effects & 0xFF) | (MSG_ReadByte (&packet) << 8));
|
||||
Net_LogPrintf(" U_EFFECTS2: %d", (to.effects & 0xFF) | (MSG_ReadByte (&packet) << 8));
|
||||
if (bits & U_GLOWSIZE)
|
||||
Net_LogPrintf(" GlowSize: %d", MSG_ReadByte (&packet));
|
||||
Net_LogPrintf(" GlowSize: %d", MSG_ReadByte (&packet));
|
||||
if (bits & U_GLOWCOLOR)
|
||||
Net_LogPrintf(" ColorGlow: %d", MSG_ReadByte (&packet));
|
||||
Net_LogPrintf(" ColorGlow: %d", MSG_ReadByte (&packet));
|
||||
if (bits & U_COLORMOD)
|
||||
Net_LogPrintf(" Colormod: %d", MSG_ReadByte (&packet));
|
||||
Net_LogPrintf(" Colormod: %d", MSG_ReadByte (&packet));
|
||||
if (bits & U_FRAME2)
|
||||
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)
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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->cursize = len;
|
||||
MSG_BeginReading (&packet);
|
||||
Parse_Server_Packet ();
|
||||
if (Net_PacketLog == _stdout)
|
||||
Net_PacketLog = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -373,11 +438,10 @@ Parse_Server_Packet ()
|
|||
if (c == -1)
|
||||
break;
|
||||
// Net_LogPrintf("\n<%ld,%ld> ",seq1 & 0x7FFFFFFF,seq2 & 0x7FFFFFFF);
|
||||
Net_LogPrintf ("<%06x> [0x%02x] ",
|
||||
MSG_GetReadCount (&packet) - 1, c);
|
||||
Net_LogPrintf ("<%06x> [0x%02x] ", MSG_GetReadCount (&packet), c);
|
||||
|
||||
if (c < 53)
|
||||
Net_LogPrintf ("%s: ", NET_SVC_GetString (c));
|
||||
Net_LogPrintf ("%s: ", svc_string[c]);
|
||||
// else Net_LogPrintf("(UNK: %d): ",c);
|
||||
|
||||
if (MSG_GetReadCount (&packet) > packet.message->cursize)
|
||||
|
@ -559,7 +623,7 @@ Parse_Server_Packet ()
|
|||
Net_LogPrintf ("**QW OBSOLETE**");
|
||||
break;
|
||||
case svc_centerprint:
|
||||
Net_LogPrintf ("%s", MSG_ReadString (&packet));
|
||||
Net_LogPrintf ("%s\n", MSG_ReadString (&packet));
|
||||
break;
|
||||
case svc_killedmonster:
|
||||
break;
|
||||
|
@ -730,20 +794,22 @@ Parse_Server_Packet ()
|
|||
else
|
||||
Net_LogPrintf ("\n\t*End of sound list*");
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
Net_LogPrintf ("from: %d", MSG_ReadByte (&packet));
|
||||
// intentional fallthrough
|
||||
case svc_packetentities:
|
||||
while (1) {
|
||||
mask1 = (unsigned short) MSG_ReadShort(&packet);
|
||||
if (packet.badread) {
|
||||
Net_LogPrintf (" Badread\n");
|
||||
Net_LogPrintf ("Badread\n");
|
||||
return;
|
||||
}
|
||||
if (Log_Delta(mask1))
|
||||
break;
|
||||
if (!mask1) break;
|
||||
if (mask1 & U_REMOVE) Net_LogPrintf("UREMOVE ");
|
||||
Log_Delta(mask1);
|
||||
}
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
Net_LogPrintf ("idx: %d", MSG_ReadByte (&packet));
|
||||
return;
|
||||
break;
|
||||
case svc_maxspeed:
|
||||
Net_LogPrintf ("%f", MSG_ReadFloat (&packet));
|
||||
break;
|
||||
|
@ -773,12 +839,16 @@ Parse_Server_Packet ()
|
|||
}
|
||||
|
||||
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->cursize = len;
|
||||
MSG_BeginReading (&packet);
|
||||
Parse_Client_Packet ();
|
||||
if (Net_PacketLog == _stdout)
|
||||
Net_PacketLog = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -892,7 +962,7 @@ Net_PacketLog_f (cvar_t *var)
|
|||
void
|
||||
Net_PacketLog_Zap_f (void)
|
||||
{
|
||||
if (Net_PacketLog) {
|
||||
if (Net_PacketLog && Net_PacketLog != _stdout) {
|
||||
Con_Printf ("truncating packet logfile: %s\n", "qfpacket.log");
|
||||
Qseek (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;
|
||||
|
||||
_stdout = Qdopen (1, "wt"); // create a QFile of stdout
|
||||
|
||||
net_packetlog = Cvar_Get ("net_packetlog", "0", CVAR_NONE, Net_PacketLog_f,
|
||||
"enable/disable packet logging");
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ static const char rcsid[] =
|
|||
|
||||
#include "bothdefs.h"
|
||||
#include "compat.h"
|
||||
#include "net_svc.h"
|
||||
#include "server.h"
|
||||
#include "sv_progs.h"
|
||||
|
||||
|
@ -830,15 +829,12 @@ SV_Heartbeat_f (void)
|
|||
void
|
||||
SV_SendServerInfoChange (const char *key, const char *value)
|
||||
{
|
||||
net_svc_serverinfo_t block;
|
||||
|
||||
if (!sv.state)
|
||||
return;
|
||||
|
||||
block.key = key;
|
||||
block.value = value;
|
||||
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 "msg_ucmd.h"
|
||||
#include "net_svc.h"
|
||||
#include "server.h"
|
||||
#include "sv_progs.h"
|
||||
|
||||
|
@ -126,29 +125,51 @@ SV_AddNailUpdate (edict_t *ent)
|
|||
void
|
||||
SV_EmitNailUpdate (sizebuf_t *msg)
|
||||
{
|
||||
int i;
|
||||
net_svc_nails_t block;
|
||||
byte bits[6]; // [48 bits] xyzpy 12 12 12 4 8
|
||||
int i, n, p, x, y, z, yaw;
|
||||
edict_t *ent;
|
||||
|
||||
if (!numnails)
|
||||
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);
|
||||
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;
|
||||
float miss;
|
||||
unsigned int bits = 0;
|
||||
int bits, i;
|
||||
float miss;
|
||||
|
||||
// send an update
|
||||
bits = 0;
|
||||
|
||||
for (i = 0; i < 3; 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
|
||||
// Ender (QSG - Begin)
|
||||
// if (stdver > 1) {
|
||||
if (stdver > 1) {
|
||||
if (to->alpha != from->alpha)
|
||||
bits |= U_ALPHA;
|
||||
|
||||
|
@ -197,44 +218,20 @@ SV_EntityState_Diff (entity_state_t *from, entity_state_t *to)
|
|||
|
||||
if (to->colormod != from->colormod)
|
||||
bits |= U_COLORMOD;
|
||||
// }
|
||||
}
|
||||
|
||||
// if (bits >= 16777216)
|
||||
if (bits & U_GROUP_EXTEND2)
|
||||
if (bits >= 16777216)
|
||||
bits |= U_EXTEND2;
|
||||
|
||||
// if (bits >= 65536)
|
||||
if (bits & U_GROUP_EXTEND1)
|
||||
if (bits >= 65536)
|
||||
bits |= U_EXTEND1;
|
||||
// Ender (QSG - End)
|
||||
|
||||
// if (bits & 511)
|
||||
if (bits & U_GROUP_MOREBITS)
|
||||
if (bits & 511)
|
||||
bits |= U_MOREBITS;
|
||||
|
||||
if (to->flags & 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
|
||||
if (!to->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)
|
||||
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)
|
||||
MSG_WriteByte (msg, bits & 255);
|
||||
|
@ -302,118 +302,80 @@ SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg,
|
|||
/*
|
||||
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
|
||||
SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
|
||||
{
|
||||
int index;
|
||||
entity_state_t *baseline;
|
||||
net_svc_packetentities_t block;
|
||||
|
||||
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;
|
||||
int newindex, oldindex, newnum, oldnum, oldmax;
|
||||
edict_t *ent;
|
||||
client_frame_t *fromframe;
|
||||
packet_entities_t *from;
|
||||
net_svc_deltapacketentities_t block;
|
||||
|
||||
// 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,
|
||||
// client->netchan.outgoing_sequence & UPDATE_MASK);
|
||||
for (newindex = 0, oldindex = 0, word = 0;
|
||||
newindex < to->num_entities || oldindex < from->num_entities;
|
||||
word++) {
|
||||
newnum = newindex >= to->num_entities ?
|
||||
9999 : to->entities[newindex].number;
|
||||
oldnum = oldindex >= from->num_entities ?
|
||||
9999 : from->entities[oldindex].number;
|
||||
while (newindex < to->num_entities || oldindex < oldmax) {
|
||||
newnum =
|
||||
newindex >= to->num_entities ? 9999 :
|
||||
to->entities[newindex].number;
|
||||
oldnum = oldindex >= oldmax ? 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);
|
||||
block.deltas[newindex] = to->entities[newindex];
|
||||
block.deltas[newindex].flags =
|
||||
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);
|
||||
|
||||
SV_WriteDelta (&from->entities[oldindex], &to->entities[newindex],
|
||||
msg, false, client->stdver);
|
||||
oldindex++;
|
||||
newindex++;
|
||||
} else if (newnum < oldnum) { // this is a new entity, send
|
||||
// it from the baseline
|
||||
baseline = EDICT_NUM (&sv_pr_state, newnum)->data;
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
block.deltas[newindex] = to->entities[newindex];
|
||||
block.deltas[newindex].flags =
|
||||
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);
|
||||
|
||||
SV_WriteDelta (ent->data, &to->entities[newindex], msg, true,
|
||||
client->stdver);
|
||||
newindex++;
|
||||
} else if (newnum > oldnum) { // the old entity isn't
|
||||
// present in the new message
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newnum > oldnum) { // the old entity isn't present in
|
||||
// the new message
|
||||
// SV_Printf ("remove %i\n", oldnum);
|
||||
block.words[word] = oldnum | U_REMOVE;
|
||||
MSG_WriteShort (msg, oldnum | U_REMOVE);
|
||||
oldindex++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
block.words[word] = 0;
|
||||
MSG_WriteByte (msg, svc_deltapacketentities);
|
||||
NET_SVC_DeltaPacketEntities_Emit (&block, msg);
|
||||
MSG_WriteShort (msg, 0); // end of packetentities
|
||||
}
|
||||
|
||||
void
|
||||
SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
|
||||
sizebuf_t *msg)
|
||||
{
|
||||
int i, j;
|
||||
int i, j, msec, pflags;
|
||||
client_t *cl;
|
||||
edict_t *ent;
|
||||
net_svc_playerinfo_t block;
|
||||
usercmd_t cmd;
|
||||
|
||||
for (j = 0, cl = svs.clients; j < MAX_CLIENTS; j++, cl++) {
|
||||
if (cl->state != cs_spawned)
|
||||
|
@ -435,63 +397,82 @@ SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
|
|||
continue; // not visible
|
||||
}
|
||||
|
||||
block.flags = PF_MSEC | PF_COMMAND;
|
||||
pflags = PF_MSEC | PF_COMMAND;
|
||||
|
||||
if (SVfloat (ent, modelindex) != sv_playermodel)
|
||||
block.flags |= PF_MODEL;
|
||||
pflags |= PF_MODEL;
|
||||
for (i = 0; i < 3; i++)
|
||||
if (SVvector (ent, velocity)[i])
|
||||
block.flags |= PF_VELOCITY1 << i;
|
||||
pflags |= PF_VELOCITY1 << i;
|
||||
if (SVfloat (ent, effects))
|
||||
block.flags |= PF_EFFECTS;
|
||||
pflags |= PF_EFFECTS;
|
||||
if (SVfloat (ent, skin))
|
||||
block.flags |= PF_SKINNUM;
|
||||
pflags |= PF_SKINNUM;
|
||||
if (SVfloat (ent, health) <= 0)
|
||||
block.flags |= PF_DEAD;
|
||||
pflags |= PF_DEAD;
|
||||
if (SVvector (ent, mins)[2] != -24)
|
||||
block.flags |= PF_GIB;
|
||||
pflags |= PF_GIB;
|
||||
|
||||
if (cl->spectator) { // only sent origin and velocity to
|
||||
// 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
|
||||
// personal entity
|
||||
block.flags &= ~(PF_MSEC | PF_COMMAND);
|
||||
pflags &= ~(PF_MSEC | PF_COMMAND);
|
||||
if (SVfloat (ent, weaponframe))
|
||||
block.flags |= PF_WEAPONFRAME;
|
||||
pflags |= PF_WEAPONFRAME;
|
||||
}
|
||||
|
||||
if (client->spec_track && client->spec_track - 1 == j &&
|
||||
SVfloat (ent, 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);
|
||||
SVfloat (ent, weaponframe)) pflags |= PF_WEAPONFRAME;
|
||||
|
||||
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,10 +591,8 @@ SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
|
|||
|
||||
// encode the packet entities as a delta from the
|
||||
// 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
|
||||
SV_EmitNailUpdate (msg);
|
||||
|
|
|
@ -46,7 +46,6 @@ static const char rcsid[] =
|
|||
|
||||
#include "compat.h"
|
||||
#include "crudefile.h"
|
||||
#include "net_svc.h"
|
||||
#include "server.h"
|
||||
#include "sv_progs.h"
|
||||
#include "world.h"
|
||||
|
@ -105,9 +104,8 @@ SV_FlushSignon (void)
|
|||
void
|
||||
SV_CreateBaseline (void)
|
||||
{
|
||||
int entnum;
|
||||
int i, entnum;
|
||||
edict_t *svent;
|
||||
net_svc_spawnbaseline_t block;
|
||||
|
||||
for (entnum = 0; entnum < sv.num_edicts; entnum++) {
|
||||
svent = EDICT_NUM (&sv_pr_state, entnum);
|
||||
|
@ -145,15 +143,19 @@ SV_CreateBaseline (void)
|
|||
SV_FlushSignon ();
|
||||
|
||||
// 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);
|
||||
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 "game.h"
|
||||
#include "net.h"
|
||||
#include "net_svc.h"
|
||||
#include "pmove.h"
|
||||
#include "server.h"
|
||||
#include "sv_progs.h"
|
||||
|
@ -261,14 +260,11 @@ SV_FinalMessage (const char *message)
|
|||
{
|
||||
client_t *cl;
|
||||
int i;
|
||||
net_svc_print_t block;
|
||||
|
||||
block.level = PRINT_HIGH;
|
||||
block.message = message;
|
||||
|
||||
SZ_Clear (net_message->message);
|
||||
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);
|
||||
|
||||
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;
|
||||
int i;
|
||||
net_svc_updateuserinfo_t block;
|
||||
|
||||
i = client - svs.clients;
|
||||
|
||||
|
@ -398,11 +393,10 @@ SV_FullClientUpdate (client_t *client, sizebuf_t *buf)
|
|||
info = client->userinfo ? Info_MakeString (client->userinfo,
|
||||
make_info_string_filter) : "";
|
||||
|
||||
block.slot = i;
|
||||
block.userid = client->userid;
|
||||
block.userinfo = info;
|
||||
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
|
||||
iswhitespace (char c)
|
||||
{
|
||||
c &= 127;
|
||||
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++) {
|
||||
if (iswhitespace (*p)) {
|
||||
if (!iswhitespace (p[1]) && p[1] != '\0')
|
||||
*r++ = ' '; // get rid of any special chars
|
||||
*r++ = *p;
|
||||
} else
|
||||
*r++ = *p & 127; // get rid of bold
|
||||
*r++ = *p;
|
||||
}
|
||||
*r = '\0';
|
||||
|
||||
|
@ -2217,14 +2210,6 @@ SV_ExtractFromUserinfo (client_t *cl)
|
|||
if (!*newname)
|
||||
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
|
||||
// legitimately it'll be a no-op later on
|
||||
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
|
||||
// than whitespace changed
|
||||
// finally, report it to all our friends
|
||||
// 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",
|
||||
cl->name, newname);
|
||||
strcpy (cl->name, newname);
|
||||
|
|
|
@ -36,6 +36,7 @@ static const char rcsid[] =
|
|||
#include "QF/model.h"
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -607,14 +607,14 @@ SV_CheckWaterTransition (edict_t *ent)
|
|||
if (cont <= CONTENTS_WATER) {
|
||||
if (SVfloat (ent, watertype) == CONTENTS_EMPTY) {
|
||||
// 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, waterlevel) = 1;
|
||||
} else {
|
||||
if (SVfloat (ent, watertype) != CONTENTS_EMPTY) {
|
||||
// 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, waterlevel) = cont;
|
||||
|
@ -717,7 +717,7 @@ SV_Physics_Step (edict_t *ent)
|
|||
if ((int) SVfloat (ent, flags) & FL_ONGROUND) // just hit ground
|
||||
{
|
||||
if (hitsound)
|
||||
SV_StartSound (ent, 0, "demon/dland2.wav", 1, 1);
|
||||
SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
|
||||
}
|
||||
}
|
||||
// regular thinking
|
||||
|
|
|
@ -45,7 +45,6 @@ static const char rcsid[] =
|
|||
|
||||
#include "compat.h"
|
||||
#include "crudefile.h"
|
||||
#include "net_svc.h"
|
||||
#include "server.h"
|
||||
#include "sv_pr_cmds.h"
|
||||
#include "sv_progs.h"
|
||||
|
@ -280,16 +279,17 @@ PF_ambientsound (progs_t *pr)
|
|||
{
|
||||
const char **check;
|
||||
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);
|
||||
block.volume = G_FLOAT (pr, OFS_PARM2) * 255;
|
||||
block.attenuation = G_FLOAT (pr, OFS_PARM3) * 64;
|
||||
vol = G_FLOAT (pr, OFS_PARM2);
|
||||
attenuation = G_FLOAT (pr, OFS_PARM3);
|
||||
|
||||
// check to see if samp was properly precached
|
||||
for (block.sound_num = 0, check = sv.sound_precache; *check;
|
||||
check++, block.sound_num++)
|
||||
for (soundnum = 0, check = sv.sound_precache; *check; check++, soundnum++)
|
||||
if (!strcmp (*check, samp))
|
||||
break;
|
||||
|
||||
|
@ -300,7 +300,14 @@ PF_ambientsound (progs_t *pr)
|
|||
|
||||
// add an svc_spawnambient command to the level signon packet
|
||||
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;
|
||||
edict_t *entity;
|
||||
float volume, attenuation;
|
||||
int channel;
|
||||
float attenuation;
|
||||
int channel, volume;
|
||||
|
||||
entity = G_EDICT (pr, OFS_PARM0);
|
||||
channel = G_FLOAT (pr, OFS_PARM1);
|
||||
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);
|
||||
|
||||
SV_StartSound (entity, channel, sample, volume, attenuation);
|
||||
|
@ -1135,21 +1142,25 @@ int SV_ModelIndex (const char *name);
|
|||
void
|
||||
PF_makestatic (progs_t *pr)
|
||||
{
|
||||
const char *model;
|
||||
edict_t *ent;
|
||||
net_svc_spawnstatic_t block;
|
||||
int i;
|
||||
|
||||
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);
|
||||
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
|
||||
ED_Free (pr, ent);
|
||||
|
@ -1358,7 +1369,6 @@ PF_setinfokey (progs_t *pr)
|
|||
int e1 = NUM_FOR_EDICT (pr, edict);
|
||||
const char *key = G_STRING (pr, OFS_PARM1);
|
||||
const char *value = G_STRING (pr, OFS_PARM2);
|
||||
net_svc_setinfo_t block;
|
||||
|
||||
if (e1 == 0) {
|
||||
if (*value)
|
||||
|
@ -1372,11 +1382,12 @@ PF_setinfokey (progs_t *pr)
|
|||
SV_ExtractFromUserinfo (&svs.clients[e1 - 1]);
|
||||
|
||||
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);
|
||||
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 "compat.h"
|
||||
#include "net_svc.h"
|
||||
#include "server.h"
|
||||
#include "sv_progs.h"
|
||||
|
||||
|
@ -70,7 +69,6 @@ void
|
|||
SV_FlushRedirect (void)
|
||||
{
|
||||
char send[8000 + 6];
|
||||
net_svc_print_t block;
|
||||
|
||||
if (sv_redirected == RD_PACKET) {
|
||||
send[0] = 0xff;
|
||||
|
@ -82,15 +80,10 @@ SV_FlushRedirect (void)
|
|||
|
||||
NET_SendPacket (strlen (send) + 1, send, net_from);
|
||||
} else if (sv_redirected == RD_CLIENT) {
|
||||
block.level = PRINT_HIGH;
|
||||
block.message = outputbuf;
|
||||
ClientReliableWrite_Begin (host_client, svc_print,
|
||||
strlen (outputbuf) + 3);
|
||||
if (host_client->num_backbuf) {
|
||||
NET_SVC_Print_Emit (&block, &host_client->backbuf);
|
||||
ClientReliable_FinishWrite (host_client);
|
||||
} else
|
||||
NET_SVC_Print_Emit (&block, &host_client->netchan.message);
|
||||
ClientReliableWrite_Byte (host_client, PRINT_HIGH);
|
||||
ClientReliableWrite_String (host_client, outputbuf);
|
||||
}
|
||||
// clear it
|
||||
outputbuf[0] = 0;
|
||||
|
@ -227,7 +220,6 @@ SV_PrintToClient (client_t *cl, int level, const char *string)
|
|||
unsigned char *b;
|
||||
int size;
|
||||
static int buffer_size;
|
||||
net_svc_print_t block;
|
||||
|
||||
size = strlen (string) + 1;
|
||||
if (size > buffer_size) {
|
||||
|
@ -247,14 +239,9 @@ SV_PrintToClient (client_t *cl, int level, const char *string)
|
|||
if (*b != 0xFF)
|
||||
b++;
|
||||
|
||||
block.level = level;
|
||||
block.message = buffer;
|
||||
ClientReliableWrite_Begin (cl, svc_print, strlen (buffer) + 3);
|
||||
if (cl->num_backbuf) {
|
||||
NET_SVC_Print_Emit (&block, &cl->backbuf);
|
||||
ClientReliable_FinishWrite (cl);
|
||||
} else
|
||||
NET_SVC_Print_Emit (&block, &cl->netchan.message);
|
||||
ClientReliableWrite_Byte (cl, level);
|
||||
ClientReliableWrite_String (cl, buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -429,16 +416,16 @@ SV_Multicast (vec3_t origin, int to)
|
|||
Larger attenuations will drop off. (max 4 attenuation)
|
||||
*/
|
||||
void
|
||||
SV_StartSound (edict_t *entity, int channel, const char *sample,
|
||||
float volume, float attenuation)
|
||||
SV_StartSound (edict_t *entity, int channel, const char *sample, int volume,
|
||||
float attenuation)
|
||||
{
|
||||
int i, sound_num;
|
||||
int ent, field_mask, sound_num, i;
|
||||
qboolean use_phs;
|
||||
qboolean reliable = false;
|
||||
net_svc_sound_t block;
|
||||
vec3_t origin;
|
||||
|
||||
if (volume < 0 || volume > 1)
|
||||
SV_Error ("SV_StartSound: volume = %f", volume);
|
||||
if (volume < 0 || volume > 255)
|
||||
SV_Error ("SV_StartSound: volume = %i", volume);
|
||||
|
||||
if (attenuation < 0 || attenuation > 4)
|
||||
SV_Error ("SV_StartSound: attenuation = %f", attenuation);
|
||||
|
@ -457,9 +444,7 @@ SV_StartSound (edict_t *entity, int channel, const char *sample,
|
|||
return;
|
||||
}
|
||||
|
||||
block.sound_num = sound_num;
|
||||
|
||||
block.entity = NUM_FOR_EDICT (&sv_pr_state, entity);
|
||||
ent = NUM_FOR_EDICT (&sv_pr_state, entity);
|
||||
|
||||
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)
|
||||
// reliable = true;
|
||||
|
||||
block.channel = channel;
|
||||
channel = (ent << 3) | channel;
|
||||
|
||||
block.volume = volume;
|
||||
// 4 * 64 == 256, which overflows a byte. 4 is the stated max for
|
||||
// it, and I don't want to break any progs, so I just nudge it
|
||||
// down instead
|
||||
if (attenuation == 4)
|
||||
attenuation = 3.999;
|
||||
block.attenuation = attenuation;
|
||||
field_mask = 0;
|
||||
if (volume != DEFAULT_SOUND_PACKET_VOLUME)
|
||||
channel |= SND_VOLUME;
|
||||
if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
|
||||
channel |= SND_ATTENUATION;
|
||||
|
||||
// use the entity origin unless it is a bmodel
|
||||
if (SVfloat (entity, solid) == SOLID_BSP) {
|
||||
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]);
|
||||
} else {
|
||||
VectorCopy (SVvector (entity, origin), block.position);
|
||||
VectorCopy (SVvector (entity, origin), origin);
|
||||
}
|
||||
|
||||
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)
|
||||
SV_Multicast (block.position,
|
||||
reliable ? MULTICAST_PHS_R : MULTICAST_PHS);
|
||||
SV_Multicast (origin, reliable ? MULTICAST_PHS_R : MULTICAST_PHS);
|
||||
else
|
||||
SV_Multicast (block.position,
|
||||
reliable ? MULTICAST_ALL_R : MULTICAST_ALL);
|
||||
SV_Multicast (origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL);
|
||||
}
|
||||
|
||||
/* FRAME UPDATES */
|
||||
|
@ -534,7 +522,6 @@ SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
|
|||
{
|
||||
edict_t *ent, *other;
|
||||
int i;
|
||||
net_svc_damage_t block;
|
||||
|
||||
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
|
||||
if (SVfloat (ent, dmg_take) || SVfloat (ent, dmg_save)) {
|
||||
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);
|
||||
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_save) = 0;
|
||||
|
@ -794,6 +780,7 @@ SV_SendClientMessages (void)
|
|||
// if the reliable message overflowed, drop the client
|
||||
if (c->netchan.message.overflowed) {
|
||||
int i;
|
||||
extern void Analyze_Server_Packet (byte *data, int len);
|
||||
byte *data = Hunk_TempAlloc (MAX_MSGLEN + 8);
|
||||
|
||||
memset (data, 0, 8);
|
||||
|
|
|
@ -54,7 +54,6 @@ static const char rcsid[] =
|
|||
#include "compat.h"
|
||||
#include "bothdefs.h"
|
||||
#include "msg_ucmd.h"
|
||||
#include "net_svc.h"
|
||||
#include "pmove.h"
|
||||
#include "server.h"
|
||||
#include "sv_progs.h"
|
||||
|
@ -97,7 +96,7 @@ void
|
|||
SV_New_f (void)
|
||||
{
|
||||
const char *gamedir;
|
||||
net_svc_serverdata_t block;
|
||||
int playernum;
|
||||
|
||||
if (host_client->state == cs_spawned)
|
||||
return;
|
||||
|
@ -116,23 +115,37 @@ SV_New_f (void)
|
|||
//NOTE: This doesn't go through ClientReliableWrite since it's before the user
|
||||
//spawns. These functions are written to not overflow
|
||||
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->num_backbuf = 0;
|
||||
SZ_Clear (&host_client->netchan.message);
|
||||
}
|
||||
|
||||
// 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);
|
||||
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
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_cdtrack);
|
||||
|
@ -152,14 +165,12 @@ void
|
|||
SV_Soundlist_f (void)
|
||||
{
|
||||
const char **s;
|
||||
int i, size;
|
||||
net_svc_soundlist_t block;
|
||||
unsigned n;
|
||||
|
||||
if (host_client->state != cs_connected) {
|
||||
SV_Printf ("soundlist not valid -- already spawned\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// handle the case of a level changing while a client was connecting
|
||||
if (atoi (Cmd_Argv (1)) != svs.spawncount) {
|
||||
SV_Printf ("SV_Soundlist_f from different level\n");
|
||||
|
@ -167,40 +178,34 @@ SV_Soundlist_f (void)
|
|||
return;
|
||||
}
|
||||
|
||||
block.startsound = atoi (Cmd_Argv (2));
|
||||
if (block.startsound >= MAX_SOUNDS) {
|
||||
n = atoi (Cmd_Argv (2));
|
||||
if (n >= MAX_SOUNDS) {
|
||||
SV_Printf ("SV_Soundlist_f: Invalid soundlist index\n");
|
||||
SV_New_f ();
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: This doesn't go through ClientReliableWrite since it's
|
||||
// before the user spawns. These functions are written to not
|
||||
// overflow
|
||||
//NOTE: This doesn't go through ClientReliableWrite since it's before the user
|
||||
//spawns. These functions are written to not overflow
|
||||
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->num_backbuf = 0;
|
||||
SZ_Clear (&host_client->netchan.message);
|
||||
}
|
||||
|
||||
for (s = sv.sound_precache + 1 + block.startsound, i = 0, size = 0;
|
||||
*s; i++, s++) {
|
||||
if (host_client->netchan.message.cursize + size >= (MAX_MSGLEN / 2))
|
||||
break;
|
||||
size += strlen (*s) + 1;
|
||||
block.sounds[i] = *s;
|
||||
}
|
||||
block.sounds[i] = "";
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_soundlist);
|
||||
MSG_WriteByte (&host_client->netchan.message, n);
|
||||
for (s = sv.sound_precache + 1 + n;
|
||||
*s && host_client->netchan.message.cursize < (MAX_MSGLEN / 2);
|
||||
s++, n++) MSG_WriteString (&host_client->netchan.message, *s);
|
||||
|
||||
MSG_WriteByte (&host_client->netchan.message, 0);
|
||||
|
||||
// next msg
|
||||
if (*s)
|
||||
block.nextsound = block.startsound + i;
|
||||
MSG_WriteByte (&host_client->netchan.message, n);
|
||||
else
|
||||
block.nextsound = 0;
|
||||
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_soundlist);
|
||||
NET_SVC_Soundlist_Emit (&block, &host_client->netchan.message);
|
||||
MSG_WriteByte (&host_client->netchan.message, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -210,14 +215,12 @@ void
|
|||
SV_Modellist_f (void)
|
||||
{
|
||||
const char **s;
|
||||
int i, size;
|
||||
net_svc_modellist_t block;
|
||||
unsigned n;
|
||||
|
||||
if (host_client->state != cs_connected) {
|
||||
SV_Printf ("modellist not valid -- already spawned\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// handle the case of a level changing while a client was connecting
|
||||
if (atoi (Cmd_Argv (1)) != svs.spawncount) {
|
||||
SV_Printf ("SV_Modellist_f from different level\n");
|
||||
|
@ -225,40 +228,33 @@ SV_Modellist_f (void)
|
|||
return;
|
||||
}
|
||||
|
||||
block.startmodel = atoi (Cmd_Argv (2));
|
||||
if (block.startmodel >= MAX_MODELS) {
|
||||
n = atoi (Cmd_Argv (2));
|
||||
if (n >= MAX_MODELS) {
|
||||
SV_Printf ("SV_Modellist_f: Invalid modellist index\n");
|
||||
SV_New_f ();
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: This doesn't go through ClientReliableWrite since it's
|
||||
// before the user spawns. These functions are written to not
|
||||
// overflow
|
||||
//NOTE: This doesn't go through ClientReliableWrite since it's before the user
|
||||
//spawns. These functions are written to not overflow
|
||||
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->num_backbuf = 0;
|
||||
SZ_Clear (&host_client->netchan.message);
|
||||
}
|
||||
|
||||
for (s = sv.model_precache + 1 + block.startmodel, i = 0, size = 0;
|
||||
*s; i++, s++) {
|
||||
if (host_client->netchan.message.cursize + size >= (MAX_MSGLEN / 2))
|
||||
break;
|
||||
size += strlen (*s) + 1;
|
||||
block.models[i] = *s;
|
||||
}
|
||||
block.models[i] = "";
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_modellist);
|
||||
MSG_WriteByte (&host_client->netchan.message, n);
|
||||
for (s = sv.model_precache + 1 + n;
|
||||
*s && host_client->netchan.message.cursize < (MAX_MSGLEN / 2);
|
||||
s++, n++) MSG_WriteString (&host_client->netchan.message, *s);
|
||||
MSG_WriteByte (&host_client->netchan.message, 0);
|
||||
|
||||
// next msg
|
||||
if (*s)
|
||||
block.nextmodel = block.startmodel + i;
|
||||
MSG_WriteByte (&host_client->netchan.message, n);
|
||||
else
|
||||
block.nextmodel = 0;
|
||||
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_modellist);
|
||||
NET_SVC_Modellist_Emit (&block, &host_client->netchan.message);
|
||||
MSG_WriteByte (&host_client->netchan.message, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -566,27 +562,27 @@ void
|
|||
SV_NextDownload_f (void)
|
||||
{
|
||||
byte buffer[1024];
|
||||
net_svc_download_t block;
|
||||
int r;
|
||||
int percent;
|
||||
int size;
|
||||
|
||||
if (!host_client->download)
|
||||
return;
|
||||
|
||||
block.size = host_client->downloadsize - host_client->downloadcount;
|
||||
if (block.size > 768)
|
||||
block.size = 768;
|
||||
block.size = Qread (host_client->download, buffer, block.size);
|
||||
r = host_client->downloadsize - host_client->downloadcount;
|
||||
if (r > 768)
|
||||
r = 768;
|
||||
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;
|
||||
block.percent = host_client->downloadcount * 100 /
|
||||
(host_client->downloadsize ?: 1);
|
||||
|
||||
block.data = buffer;
|
||||
ClientReliableWrite_Begin (host_client, svc_download, 6 + block.size);
|
||||
if (host_client->num_backbuf) {
|
||||
NET_SVC_Download_Emit (&block, &host_client->backbuf);
|
||||
ClientReliable_FinishWrite (host_client);
|
||||
} else
|
||||
NET_SVC_Download_Emit (&block, &host_client->netchan.message);
|
||||
host_client->downloadcount += r;
|
||||
size = host_client->downloadsize;
|
||||
if (!size)
|
||||
size = 1;
|
||||
percent = host_client->downloadcount * 100 / size;
|
||||
ClientReliableWrite_Byte (host_client, percent);
|
||||
ClientReliableWrite_SZ (host_client, buffer, r);
|
||||
|
||||
if (host_client->downloadcount != host_client->downloadsize)
|
||||
return;
|
||||
|
@ -695,7 +691,6 @@ SV_BeginDownload_f (void)
|
|||
int size;
|
||||
char realname[MAX_OSPATH];
|
||||
int zip;
|
||||
net_svc_download_t block;
|
||||
|
||||
name = Cmd_Argv (1);
|
||||
// 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)
|
||||
// MUST be in a subdirectory
|
||||
|| !strstr (name, "/")) { // don't allow anything with .. path
|
||||
block.size = -1;
|
||||
block.percent = 0;
|
||||
ClientReliableWrite_Begin (host_client, svc_download, 4);
|
||||
if (host_client->num_backbuf) {
|
||||
NET_SVC_Download_Emit (&block, &host_client->backbuf);
|
||||
ClientReliable_FinishWrite (host_client);
|
||||
} else
|
||||
NET_SVC_Download_Emit (&block, &host_client->netchan.message);
|
||||
ClientReliableWrite_Short (host_client, -1);
|
||||
ClientReliableWrite_Byte (host_client, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -756,30 +746,19 @@ SV_BeginDownload_f (void)
|
|||
}
|
||||
|
||||
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);
|
||||
if (host_client->num_backbuf) {
|
||||
NET_SVC_Download_Emit (&block, &host_client->backbuf);
|
||||
ClientReliable_FinishWrite (host_client);
|
||||
} else
|
||||
NET_SVC_Download_Emit (&block, &host_client->netchan.message);
|
||||
ClientReliableWrite_Short (host_client, -1);
|
||||
ClientReliableWrite_Byte (host_client, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (zip && strcmp (realname, name)) {
|
||||
SV_Printf ("download renamed to %s\n", realname);
|
||||
|
||||
block.size = -2;
|
||||
block.percent = 0;
|
||||
block.name = realname;
|
||||
ClientReliableWrite_Begin (host_client, svc_download,
|
||||
strlen (realname) + 5);
|
||||
if (host_client->num_backbuf)
|
||||
NET_SVC_Download_Emit (&block, &host_client->backbuf);
|
||||
else
|
||||
NET_SVC_Download_Emit (&block, &host_client->netchan.message);
|
||||
ClientReliableWrite_Short (host_client, -2);
|
||||
ClientReliableWrite_Byte (host_client, 0);
|
||||
ClientReliableWrite_String (host_client, realname);
|
||||
ClientReliable_FinishWrite (host_client);
|
||||
}
|
||||
|
||||
|
@ -1136,8 +1115,6 @@ SV_Msg_f (void)
|
|||
void
|
||||
SV_SetInfo_f (void)
|
||||
{
|
||||
net_svc_setinfo_t block;
|
||||
|
||||
if (Cmd_Argc () == 1) {
|
||||
SV_Printf ("User info settings:\n");
|
||||
Info_Print (host_client->userinfo);
|
||||
|
@ -1176,11 +1153,12 @@ SV_SetInfo_f (void)
|
|||
SV_ExtractFromUserinfo (host_client);
|
||||
|
||||
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);
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue