mirror of
https://github.com/rehlds/rehlds.git
synced 2025-01-14 15:48:04 +03:00
Minor refactoring and improve readability
This commit is contained in:
parent
c8308a2c60
commit
2834fb8494
@ -1060,15 +1060,18 @@ void World::ParseClientData(BitBuffer *stream, unsigned int deltaSeqNr, BitBuffe
|
||||
}
|
||||
}
|
||||
|
||||
// When a delta command is received from the server
|
||||
// We need to grab the entity # out of it any the bit settings, too
|
||||
int World::ParseDeltaHeader(BitBuffer *stream, bool &remove, bool &custom, int &numbase, bool &newbl, int &newblindex, bool full, int &offset)
|
||||
{
|
||||
int num;
|
||||
bool isdelta, isnext;
|
||||
bool isdelta;
|
||||
|
||||
offset = 0;
|
||||
custom = false;
|
||||
newbl = false;
|
||||
|
||||
// This full update (non-delta)
|
||||
if (full)
|
||||
{
|
||||
isdelta = stream->ReadBit() ? true : false;
|
||||
@ -1077,6 +1080,8 @@ int World::ParseDeltaHeader(BitBuffer *stream, bool &remove, bool &custom, int &
|
||||
else
|
||||
{
|
||||
isdelta = false;
|
||||
|
||||
// the entity was removed from server or not
|
||||
remove = stream->ReadBit() ? true : false;
|
||||
}
|
||||
|
||||
@ -1088,11 +1093,11 @@ int World::ParseDeltaHeader(BitBuffer *stream, bool &remove, bool &custom, int &
|
||||
{
|
||||
if (stream->ReadBit())
|
||||
{
|
||||
num = stream->ReadBits(11);
|
||||
num = stream->ReadBits(MAX_EDICT_BITS);
|
||||
}
|
||||
else
|
||||
{
|
||||
int delta = stream->ReadBits(6);
|
||||
int delta = stream->ReadBits(DELTA_OFFSET_BITS);
|
||||
num = delta + numbase;
|
||||
}
|
||||
}
|
||||
@ -1105,20 +1110,19 @@ int World::ParseDeltaHeader(BitBuffer *stream, bool &remove, bool &custom, int &
|
||||
|
||||
if (m_MaxInstanced_BaseLine)
|
||||
{
|
||||
isnext = stream->ReadBit() ? true : false;
|
||||
if (isnext)
|
||||
newbl = stream->ReadBit() ? true : false;
|
||||
|
||||
if (newbl)
|
||||
{
|
||||
newbl = true;
|
||||
newblindex = stream->ReadBits(6);
|
||||
newblindex = stream->ReadBits(MAX_BASELINE_BITS);
|
||||
}
|
||||
}
|
||||
|
||||
if (full && !newbl)
|
||||
{
|
||||
isnext = stream->ReadBit() ? true : false;
|
||||
if (isnext)
|
||||
if (stream->ReadBit() != 0)
|
||||
{
|
||||
offset = stream->ReadBits(6);
|
||||
offset = stream->ReadBits(MAX_BASELINE_BITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1273,15 +1277,14 @@ bool World::GetDeltaFromCache(unsigned int seqNr, unsigned int deltaNr, BitBuffe
|
||||
return 0;
|
||||
}
|
||||
|
||||
// marker an entity index that not in an old packet (for svc_packetentities)
|
||||
#define ENTITY_SENTINEL 9999
|
||||
|
||||
void World::WritePacketEntities(BitBuffer *stream, frame_t *frame, frame_t *deltaframe)
|
||||
{
|
||||
int oldmax;
|
||||
int oldindex;
|
||||
int newindex;
|
||||
int newnum;
|
||||
int oldnum;
|
||||
entity_state_t *frameEntities;
|
||||
entity_state_t *deltaEntities;
|
||||
unsigned int oldmax, oldindex, newindex;
|
||||
int newnum, oldnum;
|
||||
entity_state_t *frameEntities, *deltaEntities;
|
||||
|
||||
deltacallback_t header;
|
||||
header.instanced_baseline = (m_MaxInstanced_BaseLine > 0) ? true : false;
|
||||
@ -1289,9 +1292,9 @@ void World::WritePacketEntities(BitBuffer *stream, frame_t *frame, frame_t *delt
|
||||
header.offset = 0;
|
||||
header.numbase = 0;
|
||||
header.newblindex = 0;
|
||||
header.full = false;
|
||||
header.newbl = false;
|
||||
header.remove = false;
|
||||
header.full = false;
|
||||
header.custom = false;
|
||||
|
||||
if (frame->delta || deltaframe->delta) {
|
||||
@ -1302,79 +1305,82 @@ void World::WritePacketEntities(BitBuffer *stream, frame_t *frame, frame_t *delt
|
||||
m_Delta.SetTime(frame->time);
|
||||
|
||||
oldmax = deltaframe->entitynum;
|
||||
newnum = 0; // index in frame->entities
|
||||
oldnum = 0; // index in deltaframe->entities
|
||||
newindex = 0; // index in frame->entities
|
||||
oldindex = 0; // index in deltaframe->entities
|
||||
|
||||
frameEntities = (entity_state_t *)frame->entities;
|
||||
deltaEntities = (entity_state_t *)deltaframe->entities;
|
||||
|
||||
stream->StartBitMode();
|
||||
while (true)
|
||||
{
|
||||
if ((unsigned)newnum < frame->entitynum)
|
||||
{
|
||||
newindex = frameEntities[newnum].number;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oldnum >= oldmax)
|
||||
break;
|
||||
|
||||
// TODO: Unreachable code
|
||||
if ((unsigned)newnum < frame->entitynum)
|
||||
newindex = frameEntities[newnum].number;
|
||||
else
|
||||
newindex = 9999;
|
||||
}
|
||||
|
||||
if (oldnum < oldmax)
|
||||
oldindex = deltaEntities[oldnum].number;
|
||||
else
|
||||
oldindex = 9999;
|
||||
|
||||
if (newindex == oldindex)
|
||||
while (newindex < frame->entitynum || oldindex < oldmax)
|
||||
{
|
||||
header.custom = (frameEntities[newnum].entityType & ENTITY_BEAM) == ENTITY_BEAM;
|
||||
header.num = newindex;
|
||||
newnum = (newindex >= frame->entitynum) ? ENTITY_SENTINEL : frameEntities[newindex].number;
|
||||
oldnum = (oldindex >= oldmax) ? ENTITY_SENTINEL : deltaEntities[oldindex].number;
|
||||
|
||||
// this is a delta update of the entity from previous position
|
||||
if (newnum == oldnum)
|
||||
{
|
||||
// delta update from old position
|
||||
// because the force parm is false, this will not result
|
||||
// in any bytes being emitted if the entity has not changed at all
|
||||
// note that players are always 'newentities', this updates their oldorigin always
|
||||
// and prevents warping
|
||||
|
||||
header.custom = (frameEntities[newindex].entityType & ENTITY_BEAM) == ENTITY_BEAM;
|
||||
header.num = newnum;
|
||||
header.newblindex = 0;
|
||||
header.newbl = false;
|
||||
header.remove = false;
|
||||
|
||||
delta_t *delta = GetDeltaEncoder(newindex, header.custom);
|
||||
m_Delta.WriteDelta(stream, (byte *)&deltaEntities[newindex], (byte *)&frameEntities[newnum], false, delta, &header);
|
||||
delta_t *delta = GetDeltaEncoder(newnum, header.custom);
|
||||
m_Delta.WriteDelta(stream, (byte *)&deltaEntities[oldindex], (byte *)&frameEntities[newindex], false, delta, &header);
|
||||
|
||||
oldnum++;
|
||||
newnum++;
|
||||
oldindex++;
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newindex >= oldindex)
|
||||
// Figure out how we want to update the entity
|
||||
// This is a new entity, send it from the baseline
|
||||
if (newnum < oldnum)
|
||||
{
|
||||
if (newindex > oldindex)
|
||||
{
|
||||
header.num = oldindex;
|
||||
header.remove = true;
|
||||
header.newbl = false;
|
||||
//
|
||||
// If the entity was not in the old packet (oldnum == 9999),
|
||||
// then delta from the baseline since this is a new entity
|
||||
header.custom = (frameEntities[newindex].entityType & ENTITY_BEAM) == ENTITY_BEAM;
|
||||
header.num = newnum;
|
||||
header.newblindex = 0;
|
||||
header.newbl = false;
|
||||
header.remove = false;
|
||||
|
||||
delta_t *delta = GetDeltaEncoder(newnum, header.custom);
|
||||
m_Delta.WriteDelta(stream, (byte *)&m_BaseLines[newnum], (byte *)&frameEntities[newindex], true, delta, &header);
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// the old entity isn't present in the new message
|
||||
if (newnum > oldnum)
|
||||
{
|
||||
//
|
||||
// If the entity was in the old list, but is not in the new list (newindex == 9999),
|
||||
// then construct a special remove message
|
||||
|
||||
header.num = oldnum;
|
||||
header.newblindex = 0;
|
||||
header.newbl = false;
|
||||
header.remove = true; // tell the client that entity was removed from server
|
||||
|
||||
m_Delta.WriteHeader(stream, &header);
|
||||
++oldnum;
|
||||
}
|
||||
oldindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
header.custom = (frameEntities[newnum].entityType & ENTITY_BEAM) == ENTITY_BEAM;
|
||||
header.newblindex = 0;
|
||||
header.num = newindex;
|
||||
header.remove = false;
|
||||
header.newbl = false;
|
||||
|
||||
delta_t *delta = GetDeltaEncoder(newindex, header.custom);
|
||||
m_Delta.WriteDelta(stream, (byte *)&m_BaseLines[oldnum], (byte *)&frameEntities[newnum], true, delta, &header);
|
||||
newnum++;
|
||||
}
|
||||
|
||||
// No more entities.. (end of packet entities)
|
||||
stream->WriteBits(0, 16);
|
||||
|
||||
stream->EndBitMode();
|
||||
}
|
||||
|
||||
@ -1467,10 +1473,11 @@ double World::GetTime()
|
||||
return m_WorldTime;
|
||||
}
|
||||
|
||||
// An svc_packetentities has just been parsed, deal with the rest of the data stream
|
||||
bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsigned int from)
|
||||
{
|
||||
int newnum, oldnum;
|
||||
int oldindex, newindex;
|
||||
unsigned int oldindex, newindex;
|
||||
|
||||
bool remove, custom, newbl;
|
||||
int newblindex, numbase, offset;
|
||||
@ -1485,11 +1492,15 @@ bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsi
|
||||
oldindex = 0;
|
||||
newindex = 0;
|
||||
|
||||
numbase = 0;
|
||||
newblindex = 0;
|
||||
newbl = false;
|
||||
remove = false;
|
||||
custom = false;
|
||||
newbl = false;
|
||||
newblindex = 0;
|
||||
numbase = 0;
|
||||
|
||||
//
|
||||
// Parse uncompress entities
|
||||
//
|
||||
|
||||
m_Delta.SetTime(frame->time);
|
||||
stream->StartBitMode();
|
||||
@ -1500,60 +1511,75 @@ bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsi
|
||||
while (stream->PeekBits(16))
|
||||
{
|
||||
newnum = ParseDeltaHeader(stream, remove, custom, numbase, newbl, newblindex, false, offset);
|
||||
oldnum = (oldindex >= deltaFrame.entitynum) ? ENTITY_SENTINEL : deltaEntity[oldindex].number;
|
||||
|
||||
if ((unsigned)oldindex < deltaFrame.entitynum)
|
||||
oldnum = deltaEntity[oldindex].number;
|
||||
else
|
||||
oldnum = 9999;
|
||||
|
||||
while (newnum > oldnum)
|
||||
while (oldnum < newnum)
|
||||
{
|
||||
//
|
||||
// one or more entities from the old packet are unchanged
|
||||
|
||||
if (newindex >= MAX_PACKET_ENTITIES)
|
||||
{
|
||||
m_System->DPrintf("WARNING!World::UncompressEntitiesFromStream: newindex >= MAX_PACKET_ENTITIES.\n");
|
||||
stream->m_Overflowed = true;
|
||||
}
|
||||
|
||||
// copy one of the old entities over to the new packet unchanged
|
||||
Q_memcpy(&entity[newindex], &deltaEntity[oldindex], sizeof(entity[newindex]));
|
||||
|
||||
newindex++;
|
||||
oldindex++;
|
||||
|
||||
if ((unsigned)oldindex < deltaFrame.entitynum)
|
||||
oldnum = deltaEntity[oldindex].number;
|
||||
else
|
||||
oldnum = 9999;
|
||||
// lookup next index
|
||||
oldnum = (oldindex >= deltaFrame.entitynum) ? ENTITY_SENTINEL : deltaEntity[oldindex].number;
|
||||
}
|
||||
|
||||
if (newnum >= oldnum)
|
||||
{
|
||||
// delta from previous state
|
||||
if (newnum == oldnum)
|
||||
{
|
||||
if (remove)
|
||||
{
|
||||
++oldindex;
|
||||
oldindex++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//
|
||||
// Insert new the entity to frame
|
||||
|
||||
entity[newindex].entityType = custom ? ENTITY_BEAM : ENTITY_NORMAL;
|
||||
|
||||
delta_t *delta = GetDeltaEncoder(newnum, custom);
|
||||
m_Delta.ParseDelta(stream, (byte *)&deltaEntity[oldindex], (byte *)&entity[newindex], delta);
|
||||
|
||||
entity[newindex].number = newnum;
|
||||
++newindex;
|
||||
++oldindex;
|
||||
newindex++;
|
||||
oldindex++;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!remove)
|
||||
|
||||
// Figure out how we want to update the entity
|
||||
// This is a new entity, sent it from the baseline
|
||||
if (newnum < oldnum)
|
||||
{
|
||||
//
|
||||
// If the entity was not in the old packet (oldnum == 9999),
|
||||
// then delta from the baseline since this is a new entity
|
||||
|
||||
if (remove)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newindex >= MAX_PACKET_ENTITIES)
|
||||
{
|
||||
m_System->DPrintf("World::UncompressEntitiesFromStream: newindex >= MAX_PACKET_ENTITIES.\n");
|
||||
stream->m_Overflowed = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Insert new the entity to frame
|
||||
|
||||
entity_state_t *baseline;
|
||||
if (newbl)
|
||||
{
|
||||
@ -1574,9 +1600,12 @@ bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsi
|
||||
m_Delta.ParseDelta(stream, (byte *)baseline, (byte *)&entity[newindex], delta);
|
||||
entity[newindex].number = newnum;
|
||||
newindex++;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// peek bit == 0 end of packet entities
|
||||
if (stream->ReadShort())
|
||||
{
|
||||
m_System->DPrintf("WARNING! World::UncompressEntitiesFromStream: missing end tag.\n");
|
||||
@ -1585,7 +1614,10 @@ bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsi
|
||||
|
||||
stream->EndBitMode();
|
||||
|
||||
while ((unsigned)oldindex < deltaFrame.entitynum)
|
||||
// Copy all the rest of the entities from the old packet
|
||||
//
|
||||
|
||||
while (oldindex != ENTITY_SENTINEL && oldindex < deltaFrame.entitynum)
|
||||
{
|
||||
if (newindex >= MAX_PACKET_ENTITIES)
|
||||
{
|
||||
@ -1593,33 +1625,22 @@ bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsi
|
||||
stream->m_Overflowed = true;
|
||||
}
|
||||
|
||||
// copy everything to the new state we are delta'ing
|
||||
Q_memcpy(&entity[newindex], &deltaEntity[oldindex], sizeof(entity[newindex]));
|
||||
newindex++;
|
||||
oldindex++;
|
||||
}
|
||||
|
||||
if (newindex != frame->entitynum) {
|
||||
m_System->DPrintf("WARNING! World::UncompressEntitiesFromStream: newindex != frame->entitynum.\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream)
|
||||
{
|
||||
int num;
|
||||
int newindex = 0;
|
||||
int num, newindex = 0;
|
||||
int entnum = frame->entitynum;
|
||||
entity_state_t *baseline;
|
||||
bool remove, custom, newbl;
|
||||
int newblindex, numbase, offset;
|
||||
|
||||
newblindex = 0;
|
||||
numbase = 0;
|
||||
|
||||
remove = false;
|
||||
custom = false;
|
||||
newbl = false;
|
||||
bool remove = false, custom = false, newbl = false;
|
||||
int newblindex = 0, numbase = 0, offset;
|
||||
|
||||
entity_state_t *entities = (entity_state_t *)frame->entities;
|
||||
m_Delta.SetTime(frame->time);
|
||||
@ -2240,8 +2261,8 @@ void World::RearrangeFrame(frame_t *frame, int seqNrOffset, float timeOffset)
|
||||
BitBuffer tempStream(frame->entities, frame->entitiesSize);
|
||||
Q_memset(frame->entities, 0, frame->entitiesSize);
|
||||
|
||||
int newsize = CompressFrame(&fullFrame, &tempStream);
|
||||
if ((unsigned)newsize > frame->entitiesSize || tempStream.IsOverflowed()) {
|
||||
unsigned int newsize = CompressFrame(&fullFrame, &tempStream);
|
||||
if (newsize > frame->entitiesSize || tempStream.IsOverflowed()) {
|
||||
m_System->Printf("WARNING! World::RearrangeFrame: wrong entities size (%i != %i).\n", frame->entitiesSize, newsize);
|
||||
return;
|
||||
}
|
||||
|
@ -39,6 +39,9 @@
|
||||
#define RESOURCE_INDEX_BITS 12
|
||||
#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS)
|
||||
|
||||
#define MAX_BASELINE_BITS 6
|
||||
#define MAX_BASELINES (1 << MAX_BASELINE_BITS)
|
||||
|
||||
class World: public IWorld, public BaseSystemModule {
|
||||
public:
|
||||
World() {}
|
||||
|
@ -98,6 +98,9 @@
|
||||
// Max size of udp packet payload
|
||||
#define MAX_UDP_PACKET 4010 // 9 bytes SPLITHEADER + 4000 payload?
|
||||
|
||||
#define DELTA_OFFSET_BITS 6
|
||||
#define DELTA_OFFSET_MAX ((1 << DELTA_OFFSET_BITS) - 1)
|
||||
|
||||
enum svc_commands_e
|
||||
{
|
||||
svc_bad,
|
||||
|
@ -30,6 +30,9 @@
|
||||
|
||||
#include "entity_state.h"
|
||||
|
||||
// marker an entity index that not in an old packet (for svc_packetentities)
|
||||
#define ENTITY_SENTINEL 9999
|
||||
|
||||
typedef struct packet_entities_s
|
||||
{
|
||||
int num_entities;
|
||||
|
@ -4529,15 +4529,20 @@ int SV_CreatePacketEntities(sv_delta_t type, client_t *client, packet_entities_t
|
||||
return g_RehldsHookchains.m_SV_CreatePacketEntities.callChain(SV_CreatePacketEntities_api, type, GetRehldsApiClient(client), to, msg);
|
||||
}
|
||||
|
||||
// Computes either a compressed, or uncompressed delta buffer for the client
|
||||
// Returns the size IN BITS of the message buffer created
|
||||
int SV_CreatePacketEntities_internal(sv_delta_t type, client_t *client, packet_entities_t *to, sizebuf_t *msg)
|
||||
{
|
||||
packet_entities_t *from;
|
||||
int oldindex;
|
||||
int newindex;
|
||||
int oldnum;
|
||||
int newnum;
|
||||
edict_t *ent;
|
||||
client_frame_t *fromframe;
|
||||
packet_entities_t *from; // Entity packet for that frame
|
||||
delta_t *delta;
|
||||
int oldindex, newindex;
|
||||
int oldnum, newnum;
|
||||
int oldmax;
|
||||
int numbase;
|
||||
qboolean custom = FALSE;
|
||||
int offset;
|
||||
int numbase = 0;
|
||||
|
||||
// fix for https://github.com/dreamstalker/rehlds/issues/24
|
||||
#ifdef REHLDS_FIXES
|
||||
@ -4545,129 +4550,116 @@ int SV_CreatePacketEntities_internal(sv_delta_t type, client_t *client, packet_e
|
||||
uint64 toBaselinesForceMask[MAX_PACKET_ENTITIES];
|
||||
#endif
|
||||
|
||||
numbase = 0;
|
||||
// See if this is a full update
|
||||
if (type == sv_packet_delta)
|
||||
{
|
||||
client_frame_t *fromframe = &client->frames[SV_UPDATE_MASK & client->delta_sequence];
|
||||
// This is the frame that we are going to delta update from
|
||||
fromframe = &client->frames[SV_UPDATE_MASK & client->delta_sequence];
|
||||
from = &fromframe->entities;
|
||||
_mm_prefetch((const char*)&from->entities[0], _MM_HINT_T0);
|
||||
_mm_prefetch(((const char*)&from->entities[0]) + 64, _MM_HINT_T0);
|
||||
oldmax = from->num_entities;
|
||||
MSG_WriteByte(msg, svc_deltapacketentities);
|
||||
MSG_WriteShort(msg, to->num_entities);
|
||||
MSG_WriteByte(msg, client->delta_sequence);
|
||||
oldmax = fromframe->entities.num_entities;
|
||||
|
||||
MSG_WriteByte(msg, svc_deltapacketentities); // This is a delta
|
||||
MSG_WriteShort(msg, to->num_entities); // This is how many ents are in the new packet
|
||||
MSG_WriteByte(msg, client->delta_sequence); // This is the sequence # that we are updating from
|
||||
}
|
||||
else
|
||||
{
|
||||
oldmax = 0;
|
||||
oldmax = 0; // no delta update
|
||||
from = NULL;
|
||||
MSG_WriteByte(msg, svc_packetentities);
|
||||
MSG_WriteShort(msg, to->num_entities);
|
||||
|
||||
MSG_WriteByte(msg, svc_packetentities); // Just a packet update.
|
||||
MSG_WriteShort(msg, to->num_entities); // This is the # of entities we are sending.
|
||||
}
|
||||
|
||||
newnum = 0; //index in to->entities
|
||||
oldnum = 0; //index in from->entities
|
||||
newindex = 0; // index in to->entities
|
||||
oldindex = 0; // index in from->entities
|
||||
|
||||
MSG_StartBitWriting(msg);
|
||||
while (1)
|
||||
{
|
||||
if (newnum < to->num_entities)
|
||||
{
|
||||
newindex = to->entities[newnum].number;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oldnum >= oldmax)
|
||||
break;
|
||||
|
||||
if (newnum < to->num_entities)
|
||||
newindex = to->entities[newnum].number;
|
||||
else
|
||||
newindex = 9999;
|
||||
}
|
||||
|
||||
#ifdef REHLDS_FIXES
|
||||
if (oldnum < oldmax && from)
|
||||
#else
|
||||
if (oldnum < oldmax)
|
||||
#endif
|
||||
oldindex = from->entities[oldnum].number;
|
||||
else
|
||||
oldindex = 9999;
|
||||
|
||||
if (newindex == oldindex)
|
||||
while (newindex < to->num_entities || oldindex < oldmax)
|
||||
{
|
||||
entity_state_t *baseline_ = &to->entities[newnum];
|
||||
qboolean custom = baseline_->entityType & 0x2 ? TRUE : FALSE;
|
||||
SV_SetCallback(newindex, FALSE, custom, &numbase, FALSE, 0);
|
||||
DELTA_WriteDelta((uint8 *)&from->entities[oldnum], (uint8 *)baseline_, FALSE, custom ? g_pcustomentitydelta : (SV_IsPlayerIndex(newindex) ? g_pplayerdelta : g_pentitydelta), &SV_InvokeCallback);
|
||||
++oldnum;
|
||||
_mm_prefetch((const char*)&from->entities[oldnum], _MM_HINT_T0);
|
||||
_mm_prefetch(((const char*)&from->entities[oldnum]) + 64, _MM_HINT_T0);
|
||||
++newnum;
|
||||
newnum = (newindex >= to->num_entities) ? ENTITY_SENTINEL : to->entities[newindex].number;
|
||||
oldnum = (!from || oldindex >= oldmax) ? ENTITY_SENTINEL : from->entities[oldindex].number; // FIXED: from can be null
|
||||
|
||||
// this is a delta update of the entity from old position
|
||||
if (newnum == oldnum)
|
||||
{
|
||||
// delta update from old position
|
||||
// because the force parm is false, this will not result
|
||||
// in any bytes being emitted if the entity has not changed at all
|
||||
// note that players are always 'newentities', this updates their oldorigin always
|
||||
// and prevents warping
|
||||
|
||||
entity_state_t *baseline = &to->entities[newindex];
|
||||
custom = (baseline->entityType == ENTITY_BEAM) ? TRUE : FALSE;
|
||||
SV_SetCallback(newnum, FALSE, custom, &numbase, FALSE, 0);
|
||||
DELTA_WriteDelta((uint8 *)&from->entities[oldindex], (uint8 *)baseline, FALSE, custom ? g_pcustomentitydelta : (SV_IsPlayerIndex(newnum) ? g_pplayerdelta : g_pentitydelta), &SV_InvokeCallback);
|
||||
oldindex++;
|
||||
_mm_prefetch((const char*)&from->entities[oldindex], _MM_HINT_T0);
|
||||
_mm_prefetch(((const char*)&from->entities[oldindex]) + 64, _MM_HINT_T0);
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newindex >= oldindex)
|
||||
// Figure out how we want to update the entity
|
||||
// This is a new entity, send it from the baseline
|
||||
if (newnum < oldnum)
|
||||
{
|
||||
if (newindex > oldindex)
|
||||
{
|
||||
SV_WriteDeltaHeader(oldindex, TRUE, FALSE, &numbase, FALSE, 0, FALSE, 0);
|
||||
++oldnum;
|
||||
_mm_prefetch((const char*)&from->entities[oldnum], _MM_HINT_T0);
|
||||
_mm_prefetch(((const char*)&from->entities[oldnum]) + 64, _MM_HINT_T0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// If the entity was not in the old packet (oldnum == 9999),
|
||||
// then delta from the baseline since this is a new entity
|
||||
|
||||
edict_t *ent = EDICT_NUM(newindex);
|
||||
qboolean custom = to->entities[newnum].entityType & 0x2 ? TRUE : FALSE;
|
||||
SV_SetCallback(
|
||||
newindex,
|
||||
FALSE,
|
||||
custom,
|
||||
&numbase,
|
||||
from == NULL,
|
||||
0);
|
||||
ent = EDICT_NUM(newnum);
|
||||
custom = (to->entities[newindex].entityType == ENTITY_BEAM) ? TRUE : FALSE;
|
||||
|
||||
entity_state_t *baseline_ = &g_psv.baselines[newindex];
|
||||
if (sv_instancedbaseline.value != 0.0f && g_psv.instance_baselines->number != 0 && newindex > sv_lastnum)
|
||||
if (from == NULL)
|
||||
SV_SetCallback(newnum, FALSE, custom, &numbase, TRUE, 0);
|
||||
else
|
||||
SV_SetCallback(newnum, FALSE, custom, &numbase, FALSE, 0);
|
||||
|
||||
// this is a new entity, send it from the baseline
|
||||
entity_state_t *baseline = &g_psv.baselines[newnum];
|
||||
|
||||
if (sv_instancedbaseline.value && g_psv.instance_baselines->number != 0 && newnum > sv_lastnum)
|
||||
{
|
||||
for (int i = 0; i < g_psv.instance_baselines->number; i++)
|
||||
{
|
||||
if (g_psv.instance_baselines->classname[i] == ent->v.classname)
|
||||
{
|
||||
SV_SetNewInfo(i);
|
||||
baseline_ = &g_psv.instance_baselines->baseline[i];
|
||||
baseline = &g_psv.instance_baselines->baseline[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this is full update
|
||||
if (!from)
|
||||
{
|
||||
int offset = SV_FindBestBaseline(newnum, &baseline_, to->entities, newindex, custom);
|
||||
_mm_prefetch((const char*)baseline_, _MM_HINT_T0);
|
||||
_mm_prefetch(((const char*)baseline_) + 64, _MM_HINT_T0);
|
||||
offset = SV_FindBestBaseline(newindex, &baseline, to->entities, newnum, custom);
|
||||
_mm_prefetch((const char*)baseline, _MM_HINT_T0);
|
||||
_mm_prefetch(((const char*)baseline) + 64, _MM_HINT_T0);
|
||||
if (offset)
|
||||
SV_SetCallback(newindex, FALSE, custom, &numbase, TRUE, offset);
|
||||
SV_SetCallback(newnum, FALSE, custom, &numbase, TRUE, offset);
|
||||
|
||||
// fix for https://github.com/dreamstalker/rehlds/issues/24
|
||||
#ifdef REHLDS_FIXES
|
||||
if (offset)
|
||||
baselineToIdx = newnum - offset;
|
||||
baselineToIdx = newindex - offset;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delta_t* delta = custom ? g_pcustomentitydelta : (SV_IsPlayerIndex(newindex) ? g_pplayerdelta : g_pentitydelta);
|
||||
delta = custom ? g_pcustomentitydelta : (SV_IsPlayerIndex(newnum) ? g_pplayerdelta : g_pentitydelta);
|
||||
|
||||
// fix for https://github.com/dreamstalker/rehlds/issues/24
|
||||
#ifdef REHLDS_FIXES
|
||||
DELTA_WriteDeltaForceMask(
|
||||
(uint8 *)baseline_,
|
||||
(uint8 *)&to->entities[newnum],
|
||||
(uint8 *)baseline,
|
||||
(uint8 *)&to->entities[newindex],
|
||||
TRUE,
|
||||
delta,
|
||||
&SV_InvokeCallback,
|
||||
@ -4679,25 +4671,42 @@ int SV_CreatePacketEntities_internal(sv_delta_t type, client_t *client, packet_e
|
||||
uint64 usedMask = DELTA_GetMaskU64(delta);
|
||||
uint64 diffMask = origMask ^ usedMask;
|
||||
|
||||
//Remember changed fields that was marked in original mask, but unmarked by the conditional encoder
|
||||
toBaselinesForceMask[newnum] = diffMask & origMask;
|
||||
// Remember changed fields that was marked in original mask, but unmarked by the conditional encoder
|
||||
toBaselinesForceMask[newindex] = diffMask & origMask;
|
||||
|
||||
|
||||
#else //REHLDS_FIXES
|
||||
#else // REHLDS_FIXES
|
||||
DELTA_WriteDelta(
|
||||
(uint8 *)baseline_,
|
||||
(uint8 *)&to->entities[newnum],
|
||||
(uint8 *)baseline,
|
||||
(uint8 *)&to->entities[newindex],
|
||||
TRUE,
|
||||
delta,
|
||||
&SV_InvokeCallback
|
||||
);
|
||||
#endif //REHLDS_FIXES
|
||||
|
||||
++newnum;
|
||||
#endif // REHLDS_FIXES
|
||||
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// the old entity isn't present in the new message
|
||||
if (newnum > oldnum)
|
||||
{
|
||||
//
|
||||
// If the entity was in the old list, but is not in the new list (newnum == 9999),
|
||||
// then construct a special remove message
|
||||
|
||||
// remove = TRUE, tell the client that entity was removed from server
|
||||
SV_WriteDeltaHeader(oldnum, TRUE, FALSE, &numbase, FALSE, 0, FALSE, 0);
|
||||
oldindex++;
|
||||
_mm_prefetch((const char*)&from->entities[oldindex], _MM_HINT_T0);
|
||||
_mm_prefetch(((const char*)&from->entities[oldindex]) + 64, _MM_HINT_T0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// No more entities.. (end of packet entities)
|
||||
MSG_WriteBits(0, 16);
|
||||
|
||||
MSG_EndBitWriting(msg);
|
||||
return msg->cursize;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user