mirror of
https://github.com/rehlds/rehlds.git
synced 2025-02-05 18:20:45 +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 World::ParseDeltaHeader(BitBuffer *stream, bool &remove, bool &custom, int &numbase, bool &newbl, int &newblindex, bool full, int &offset)
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
bool isdelta, isnext;
|
bool isdelta;
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
custom = false;
|
custom = false;
|
||||||
newbl = false;
|
newbl = false;
|
||||||
|
|
||||||
|
// This full update (non-delta)
|
||||||
if (full)
|
if (full)
|
||||||
{
|
{
|
||||||
isdelta = stream->ReadBit() ? true : false;
|
isdelta = stream->ReadBit() ? true : false;
|
||||||
@ -1077,6 +1080,8 @@ int World::ParseDeltaHeader(BitBuffer *stream, bool &remove, bool &custom, int &
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
isdelta = false;
|
isdelta = false;
|
||||||
|
|
||||||
|
// the entity was removed from server or not
|
||||||
remove = stream->ReadBit() ? true : false;
|
remove = stream->ReadBit() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1088,11 +1093,11 @@ int World::ParseDeltaHeader(BitBuffer *stream, bool &remove, bool &custom, int &
|
|||||||
{
|
{
|
||||||
if (stream->ReadBit())
|
if (stream->ReadBit())
|
||||||
{
|
{
|
||||||
num = stream->ReadBits(11);
|
num = stream->ReadBits(MAX_EDICT_BITS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int delta = stream->ReadBits(6);
|
int delta = stream->ReadBits(DELTA_OFFSET_BITS);
|
||||||
num = delta + numbase;
|
num = delta + numbase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1105,20 +1110,19 @@ int World::ParseDeltaHeader(BitBuffer *stream, bool &remove, bool &custom, int &
|
|||||||
|
|
||||||
if (m_MaxInstanced_BaseLine)
|
if (m_MaxInstanced_BaseLine)
|
||||||
{
|
{
|
||||||
isnext = stream->ReadBit() ? true : false;
|
newbl = stream->ReadBit() ? true : false;
|
||||||
if (isnext)
|
|
||||||
|
if (newbl)
|
||||||
{
|
{
|
||||||
newbl = true;
|
newblindex = stream->ReadBits(MAX_BASELINE_BITS);
|
||||||
newblindex = stream->ReadBits(6);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full && !newbl)
|
if (full && !newbl)
|
||||||
{
|
{
|
||||||
isnext = stream->ReadBit() ? true : false;
|
if (stream->ReadBit() != 0)
|
||||||
if (isnext)
|
|
||||||
{
|
{
|
||||||
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;
|
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)
|
void World::WritePacketEntities(BitBuffer *stream, frame_t *frame, frame_t *deltaframe)
|
||||||
{
|
{
|
||||||
int oldmax;
|
unsigned int oldmax, oldindex, newindex;
|
||||||
int oldindex;
|
int newnum, oldnum;
|
||||||
int newindex;
|
entity_state_t *frameEntities, *deltaEntities;
|
||||||
int newnum;
|
|
||||||
int oldnum;
|
|
||||||
entity_state_t *frameEntities;
|
|
||||||
entity_state_t *deltaEntities;
|
|
||||||
|
|
||||||
deltacallback_t header;
|
deltacallback_t header;
|
||||||
header.instanced_baseline = (m_MaxInstanced_BaseLine > 0) ? true : false;
|
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.offset = 0;
|
||||||
header.numbase = 0;
|
header.numbase = 0;
|
||||||
header.newblindex = 0;
|
header.newblindex = 0;
|
||||||
header.full = false;
|
|
||||||
header.newbl = false;
|
header.newbl = false;
|
||||||
header.remove = false;
|
header.remove = false;
|
||||||
|
header.full = false;
|
||||||
header.custom = false;
|
header.custom = false;
|
||||||
|
|
||||||
if (frame->delta || deltaframe->delta) {
|
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);
|
m_Delta.SetTime(frame->time);
|
||||||
|
|
||||||
oldmax = deltaframe->entitynum;
|
oldmax = deltaframe->entitynum;
|
||||||
newnum = 0; // index in frame->entities
|
newindex = 0; // index in frame->entities
|
||||||
oldnum = 0; // index in deltaframe->entities
|
oldindex = 0; // index in deltaframe->entities
|
||||||
|
|
||||||
frameEntities = (entity_state_t *)frame->entities;
|
frameEntities = (entity_state_t *)frame->entities;
|
||||||
deltaEntities = (entity_state_t *)deltaframe->entities;
|
deltaEntities = (entity_state_t *)deltaframe->entities;
|
||||||
|
|
||||||
stream->StartBitMode();
|
stream->StartBitMode();
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if ((unsigned)newnum < frame->entitynum)
|
|
||||||
{
|
|
||||||
newindex = frameEntities[newnum].number;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (oldnum >= oldmax)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// TODO: Unreachable code
|
while (newindex < frame->entitynum || oldindex < oldmax)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
header.custom = (frameEntities[newnum].entityType & ENTITY_BEAM) == ENTITY_BEAM;
|
newnum = (newindex >= frame->entitynum) ? ENTITY_SENTINEL : frameEntities[newindex].number;
|
||||||
header.num = newindex;
|
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.newblindex = 0;
|
||||||
header.newbl = false;
|
header.newbl = false;
|
||||||
header.remove = false;
|
header.remove = false;
|
||||||
|
|
||||||
delta_t *delta = GetDeltaEncoder(newindex, header.custom);
|
delta_t *delta = GetDeltaEncoder(newnum, header.custom);
|
||||||
m_Delta.WriteDelta(stream, (byte *)&deltaEntities[newindex], (byte *)&frameEntities[newnum], false, delta, &header);
|
m_Delta.WriteDelta(stream, (byte *)&deltaEntities[oldindex], (byte *)&frameEntities[newindex], false, delta, &header);
|
||||||
|
|
||||||
oldnum++;
|
oldindex++;
|
||||||
newnum++;
|
newindex++;
|
||||||
continue;
|
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)
|
//
|
||||||
{
|
// If the entity was not in the old packet (oldnum == 9999),
|
||||||
header.num = oldindex;
|
// then delta from the baseline since this is a new entity
|
||||||
header.remove = true;
|
header.custom = (frameEntities[newindex].entityType & ENTITY_BEAM) == ENTITY_BEAM;
|
||||||
header.newbl = false;
|
header.num = newnum;
|
||||||
header.newblindex = 0;
|
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);
|
m_Delta.WriteHeader(stream, &header);
|
||||||
++oldnum;
|
oldindex++;
|
||||||
}
|
|
||||||
continue;
|
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->WriteBits(0, 16);
|
||||||
|
|
||||||
stream->EndBitMode();
|
stream->EndBitMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1467,10 +1473,11 @@ double World::GetTime()
|
|||||||
return m_WorldTime;
|
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)
|
bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsigned int from)
|
||||||
{
|
{
|
||||||
int newnum, oldnum;
|
int newnum, oldnum;
|
||||||
int oldindex, newindex;
|
unsigned int oldindex, newindex;
|
||||||
|
|
||||||
bool remove, custom, newbl;
|
bool remove, custom, newbl;
|
||||||
int newblindex, numbase, offset;
|
int newblindex, numbase, offset;
|
||||||
@ -1485,11 +1492,15 @@ bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsi
|
|||||||
oldindex = 0;
|
oldindex = 0;
|
||||||
newindex = 0;
|
newindex = 0;
|
||||||
|
|
||||||
|
numbase = 0;
|
||||||
|
newblindex = 0;
|
||||||
|
newbl = false;
|
||||||
remove = false;
|
remove = false;
|
||||||
custom = false;
|
custom = false;
|
||||||
newbl = false;
|
|
||||||
newblindex = 0;
|
//
|
||||||
numbase = 0;
|
// Parse uncompress entities
|
||||||
|
//
|
||||||
|
|
||||||
m_Delta.SetTime(frame->time);
|
m_Delta.SetTime(frame->time);
|
||||||
stream->StartBitMode();
|
stream->StartBitMode();
|
||||||
@ -1500,60 +1511,75 @@ bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsi
|
|||||||
while (stream->PeekBits(16))
|
while (stream->PeekBits(16))
|
||||||
{
|
{
|
||||||
newnum = ParseDeltaHeader(stream, remove, custom, numbase, newbl, newblindex, false, offset);
|
newnum = ParseDeltaHeader(stream, remove, custom, numbase, newbl, newblindex, false, offset);
|
||||||
|
oldnum = (oldindex >= deltaFrame.entitynum) ? ENTITY_SENTINEL : deltaEntity[oldindex].number;
|
||||||
|
|
||||||
if ((unsigned)oldindex < deltaFrame.entitynum)
|
while (oldnum < newnum)
|
||||||
oldnum = deltaEntity[oldindex].number;
|
|
||||||
else
|
|
||||||
oldnum = 9999;
|
|
||||||
|
|
||||||
while (newnum > oldnum)
|
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// one or more entities from the old packet are unchanged
|
||||||
|
|
||||||
if (newindex >= MAX_PACKET_ENTITIES)
|
if (newindex >= MAX_PACKET_ENTITIES)
|
||||||
{
|
{
|
||||||
m_System->DPrintf("WARNING!World::UncompressEntitiesFromStream: newindex >= MAX_PACKET_ENTITIES.\n");
|
m_System->DPrintf("WARNING!World::UncompressEntitiesFromStream: newindex >= MAX_PACKET_ENTITIES.\n");
|
||||||
stream->m_Overflowed = true;
|
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]));
|
Q_memcpy(&entity[newindex], &deltaEntity[oldindex], sizeof(entity[newindex]));
|
||||||
|
|
||||||
newindex++;
|
newindex++;
|
||||||
oldindex++;
|
oldindex++;
|
||||||
|
|
||||||
if ((unsigned)oldindex < deltaFrame.entitynum)
|
// lookup next index
|
||||||
oldnum = deltaEntity[oldindex].number;
|
oldnum = (oldindex >= deltaFrame.entitynum) ? ENTITY_SENTINEL : deltaEntity[oldindex].number;
|
||||||
else
|
|
||||||
oldnum = 9999;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newnum >= oldnum)
|
// delta from previous state
|
||||||
{
|
|
||||||
if (newnum == oldnum)
|
if (newnum == oldnum)
|
||||||
{
|
{
|
||||||
if (remove)
|
if (remove)
|
||||||
{
|
{
|
||||||
++oldindex;
|
oldindex++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
//
|
||||||
|
// Insert new the entity to frame
|
||||||
|
|
||||||
entity[newindex].entityType = custom ? ENTITY_BEAM : ENTITY_NORMAL;
|
entity[newindex].entityType = custom ? ENTITY_BEAM : ENTITY_NORMAL;
|
||||||
|
|
||||||
delta_t *delta = GetDeltaEncoder(newnum, custom);
|
delta_t *delta = GetDeltaEncoder(newnum, custom);
|
||||||
m_Delta.ParseDelta(stream, (byte *)&deltaEntity[oldindex], (byte *)&entity[newindex], delta);
|
m_Delta.ParseDelta(stream, (byte *)&deltaEntity[oldindex], (byte *)&entity[newindex], delta);
|
||||||
|
|
||||||
entity[newindex].number = newnum;
|
entity[newindex].number = newnum;
|
||||||
++newindex;
|
newindex++;
|
||||||
++oldindex;
|
oldindex++;
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
// Figure out how we want to update the entity
|
||||||
else if (!remove)
|
// 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)
|
if (newindex >= MAX_PACKET_ENTITIES)
|
||||||
{
|
{
|
||||||
m_System->DPrintf("World::UncompressEntitiesFromStream: newindex >= MAX_PACKET_ENTITIES.\n");
|
m_System->DPrintf("World::UncompressEntitiesFromStream: newindex >= MAX_PACKET_ENTITIES.\n");
|
||||||
stream->m_Overflowed = true;
|
stream->m_Overflowed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert new the entity to frame
|
||||||
|
|
||||||
entity_state_t *baseline;
|
entity_state_t *baseline;
|
||||||
if (newbl)
|
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);
|
m_Delta.ParseDelta(stream, (byte *)baseline, (byte *)&entity[newindex], delta);
|
||||||
entity[newindex].number = newnum;
|
entity[newindex].number = newnum;
|
||||||
newindex++;
|
newindex++;
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// peek bit == 0 end of packet entities
|
||||||
if (stream->ReadShort())
|
if (stream->ReadShort())
|
||||||
{
|
{
|
||||||
m_System->DPrintf("WARNING! World::UncompressEntitiesFromStream: missing end tag.\n");
|
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();
|
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)
|
if (newindex >= MAX_PACKET_ENTITIES)
|
||||||
{
|
{
|
||||||
@ -1593,33 +1625,22 @@ bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream, unsi
|
|||||||
stream->m_Overflowed = true;
|
stream->m_Overflowed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy everything to the new state we are delta'ing
|
||||||
Q_memcpy(&entity[newindex], &deltaEntity[oldindex], sizeof(entity[newindex]));
|
Q_memcpy(&entity[newindex], &deltaEntity[oldindex], sizeof(entity[newindex]));
|
||||||
newindex++;
|
newindex++;
|
||||||
oldindex++;
|
oldindex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newindex != frame->entitynum) {
|
|
||||||
m_System->DPrintf("WARNING! World::UncompressEntitiesFromStream: newindex != frame->entitynum.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream)
|
bool World::UncompressEntitiesFromStream(frame_t *frame, BitBuffer *stream)
|
||||||
{
|
{
|
||||||
int num;
|
int num, newindex = 0;
|
||||||
int newindex = 0;
|
|
||||||
int entnum = frame->entitynum;
|
int entnum = frame->entitynum;
|
||||||
entity_state_t *baseline;
|
entity_state_t *baseline;
|
||||||
bool remove, custom, newbl;
|
bool remove = false, custom = false, newbl = false;
|
||||||
int newblindex, numbase, offset;
|
int newblindex = 0, numbase = 0, offset;
|
||||||
|
|
||||||
newblindex = 0;
|
|
||||||
numbase = 0;
|
|
||||||
|
|
||||||
remove = false;
|
|
||||||
custom = false;
|
|
||||||
newbl = false;
|
|
||||||
|
|
||||||
entity_state_t *entities = (entity_state_t *)frame->entities;
|
entity_state_t *entities = (entity_state_t *)frame->entities;
|
||||||
m_Delta.SetTime(frame->time);
|
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);
|
BitBuffer tempStream(frame->entities, frame->entitiesSize);
|
||||||
Q_memset(frame->entities, 0, frame->entitiesSize);
|
Q_memset(frame->entities, 0, frame->entitiesSize);
|
||||||
|
|
||||||
int newsize = CompressFrame(&fullFrame, &tempStream);
|
unsigned int newsize = CompressFrame(&fullFrame, &tempStream);
|
||||||
if ((unsigned)newsize > frame->entitiesSize || tempStream.IsOverflowed()) {
|
if (newsize > frame->entitiesSize || tempStream.IsOverflowed()) {
|
||||||
m_System->Printf("WARNING! World::RearrangeFrame: wrong entities size (%i != %i).\n", frame->entitiesSize, newsize);
|
m_System->Printf("WARNING! World::RearrangeFrame: wrong entities size (%i != %i).\n", frame->entitiesSize, newsize);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
#define RESOURCE_INDEX_BITS 12
|
#define RESOURCE_INDEX_BITS 12
|
||||||
#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS)
|
#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 {
|
class World: public IWorld, public BaseSystemModule {
|
||||||
public:
|
public:
|
||||||
World() {}
|
World() {}
|
||||||
|
@ -98,6 +98,9 @@
|
|||||||
// Max size of udp packet payload
|
// Max size of udp packet payload
|
||||||
#define MAX_UDP_PACKET 4010 // 9 bytes SPLITHEADER + 4000 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
|
enum svc_commands_e
|
||||||
{
|
{
|
||||||
svc_bad,
|
svc_bad,
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
#include "entity_state.h"
|
#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
|
typedef struct packet_entities_s
|
||||||
{
|
{
|
||||||
int num_entities;
|
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);
|
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)
|
int SV_CreatePacketEntities_internal(sv_delta_t type, client_t *client, packet_entities_t *to, sizebuf_t *msg)
|
||||||
{
|
{
|
||||||
packet_entities_t *from;
|
edict_t *ent;
|
||||||
int oldindex;
|
client_frame_t *fromframe;
|
||||||
int newindex;
|
packet_entities_t *from; // Entity packet for that frame
|
||||||
int oldnum;
|
delta_t *delta;
|
||||||
int newnum;
|
int oldindex, newindex;
|
||||||
|
int oldnum, newnum;
|
||||||
int oldmax;
|
int oldmax;
|
||||||
int numbase;
|
qboolean custom = FALSE;
|
||||||
|
int offset;
|
||||||
|
int numbase = 0;
|
||||||
|
|
||||||
// fix for https://github.com/dreamstalker/rehlds/issues/24
|
// fix for https://github.com/dreamstalker/rehlds/issues/24
|
||||||
#ifdef REHLDS_FIXES
|
#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];
|
uint64 toBaselinesForceMask[MAX_PACKET_ENTITIES];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
numbase = 0;
|
// See if this is a full update
|
||||||
if (type == sv_packet_delta)
|
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;
|
from = &fromframe->entities;
|
||||||
_mm_prefetch((const char*)&from->entities[0], _MM_HINT_T0);
|
_mm_prefetch((const char*)&from->entities[0], _MM_HINT_T0);
|
||||||
_mm_prefetch(((const char*)&from->entities[0]) + 64, _MM_HINT_T0);
|
_mm_prefetch(((const char*)&from->entities[0]) + 64, _MM_HINT_T0);
|
||||||
oldmax = from->num_entities;
|
oldmax = fromframe->entities.num_entities;
|
||||||
MSG_WriteByte(msg, svc_deltapacketentities);
|
|
||||||
MSG_WriteShort(msg, to->num_entities);
|
MSG_WriteByte(msg, svc_deltapacketentities); // This is a delta
|
||||||
MSG_WriteByte(msg, client->delta_sequence);
|
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
|
else
|
||||||
{
|
{
|
||||||
oldmax = 0;
|
oldmax = 0; // no delta update
|
||||||
from = NULL;
|
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
|
newindex = 0; // index in to->entities
|
||||||
oldnum = 0; //index in from->entities
|
oldindex = 0; // index in from->entities
|
||||||
|
|
||||||
MSG_StartBitWriting(msg);
|
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)
|
while (newindex < to->num_entities || oldindex < oldmax)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
entity_state_t *baseline_ = &to->entities[newnum];
|
newnum = (newindex >= to->num_entities) ? ENTITY_SENTINEL : to->entities[newindex].number;
|
||||||
qboolean custom = baseline_->entityType & 0x2 ? TRUE : FALSE;
|
oldnum = (!from || oldindex >= oldmax) ? ENTITY_SENTINEL : from->entities[oldindex].number; // FIXED: from can be null
|
||||||
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);
|
// this is a delta update of the entity from old position
|
||||||
++oldnum;
|
if (newnum == oldnum)
|
||||||
_mm_prefetch((const char*)&from->entities[oldnum], _MM_HINT_T0);
|
{
|
||||||
_mm_prefetch(((const char*)&from->entities[oldnum]) + 64, _MM_HINT_T0);
|
// delta update from old position
|
||||||
++newnum;
|
// 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;
|
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)
|
//
|
||||||
{
|
// If the entity was not in the old packet (oldnum == 9999),
|
||||||
SV_WriteDeltaHeader(oldindex, TRUE, FALSE, &numbase, FALSE, 0, FALSE, 0);
|
// then delta from the baseline since this is a new entity
|
||||||
++oldnum;
|
|
||||||
_mm_prefetch((const char*)&from->entities[oldnum], _MM_HINT_T0);
|
|
||||||
_mm_prefetch(((const char*)&from->entities[oldnum]) + 64, _MM_HINT_T0);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
edict_t *ent = EDICT_NUM(newindex);
|
ent = EDICT_NUM(newnum);
|
||||||
qboolean custom = to->entities[newnum].entityType & 0x2 ? TRUE : FALSE;
|
custom = (to->entities[newindex].entityType == ENTITY_BEAM) ? TRUE : FALSE;
|
||||||
SV_SetCallback(
|
|
||||||
newindex,
|
|
||||||
FALSE,
|
|
||||||
custom,
|
|
||||||
&numbase,
|
|
||||||
from == NULL,
|
|
||||||
0);
|
|
||||||
|
|
||||||
entity_state_t *baseline_ = &g_psv.baselines[newindex];
|
if (from == NULL)
|
||||||
if (sv_instancedbaseline.value != 0.0f && g_psv.instance_baselines->number != 0 && newindex > sv_lastnum)
|
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++)
|
for (int i = 0; i < g_psv.instance_baselines->number; i++)
|
||||||
{
|
{
|
||||||
if (g_psv.instance_baselines->classname[i] == ent->v.classname)
|
if (g_psv.instance_baselines->classname[i] == ent->v.classname)
|
||||||
{
|
{
|
||||||
SV_SetNewInfo(i);
|
SV_SetNewInfo(i);
|
||||||
baseline_ = &g_psv.instance_baselines->baseline[i];
|
baseline = &g_psv.instance_baselines->baseline[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// If this is full update
|
||||||
if (!from)
|
if (!from)
|
||||||
{
|
{
|
||||||
int offset = SV_FindBestBaseline(newnum, &baseline_, to->entities, newindex, custom);
|
offset = SV_FindBestBaseline(newindex, &baseline, to->entities, newnum, custom);
|
||||||
_mm_prefetch((const char*)baseline_, _MM_HINT_T0);
|
_mm_prefetch((const char*)baseline, _MM_HINT_T0);
|
||||||
_mm_prefetch(((const char*)baseline_) + 64, _MM_HINT_T0);
|
_mm_prefetch(((const char*)baseline) + 64, _MM_HINT_T0);
|
||||||
if (offset)
|
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
|
// fix for https://github.com/dreamstalker/rehlds/issues/24
|
||||||
#ifdef REHLDS_FIXES
|
#ifdef REHLDS_FIXES
|
||||||
if (offset)
|
if (offset)
|
||||||
baselineToIdx = newnum - offset;
|
baselineToIdx = newindex - offset;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delta = custom ? g_pcustomentitydelta : (SV_IsPlayerIndex(newnum) ? g_pplayerdelta : g_pentitydelta);
|
||||||
delta_t* delta = custom ? g_pcustomentitydelta : (SV_IsPlayerIndex(newindex) ? g_pplayerdelta : g_pentitydelta);
|
|
||||||
|
|
||||||
// fix for https://github.com/dreamstalker/rehlds/issues/24
|
// fix for https://github.com/dreamstalker/rehlds/issues/24
|
||||||
#ifdef REHLDS_FIXES
|
#ifdef REHLDS_FIXES
|
||||||
DELTA_WriteDeltaForceMask(
|
DELTA_WriteDeltaForceMask(
|
||||||
(uint8 *)baseline_,
|
(uint8 *)baseline,
|
||||||
(uint8 *)&to->entities[newnum],
|
(uint8 *)&to->entities[newindex],
|
||||||
TRUE,
|
TRUE,
|
||||||
delta,
|
delta,
|
||||||
&SV_InvokeCallback,
|
&SV_InvokeCallback,
|
||||||
@ -4680,24 +4672,41 @@ int SV_CreatePacketEntities_internal(sv_delta_t type, client_t *client, packet_e
|
|||||||
uint64 diffMask = origMask ^ usedMask;
|
uint64 diffMask = origMask ^ usedMask;
|
||||||
|
|
||||||
// Remember changed fields that was marked in original mask, but unmarked by the conditional encoder
|
// Remember changed fields that was marked in original mask, but unmarked by the conditional encoder
|
||||||
toBaselinesForceMask[newnum] = diffMask & origMask;
|
toBaselinesForceMask[newindex] = diffMask & origMask;
|
||||||
|
|
||||||
|
|
||||||
#else // REHLDS_FIXES
|
#else // REHLDS_FIXES
|
||||||
DELTA_WriteDelta(
|
DELTA_WriteDelta(
|
||||||
(uint8 *)baseline_,
|
(uint8 *)baseline,
|
||||||
(uint8 *)&to->entities[newnum],
|
(uint8 *)&to->entities[newindex],
|
||||||
TRUE,
|
TRUE,
|
||||||
delta,
|
delta,
|
||||||
&SV_InvokeCallback
|
&SV_InvokeCallback
|
||||||
);
|
);
|
||||||
#endif // REHLDS_FIXES
|
#endif // REHLDS_FIXES
|
||||||
|
|
||||||
++newnum;
|
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_WriteBits(0, 16);
|
||||||
|
|
||||||
MSG_EndBitWriting(msg);
|
MSG_EndBitWriting(msg);
|
||||||
return msg->cursize;
|
return msg->cursize;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user