Files
watrbx-game-engine/Network/DirectPhysicsReceiver.cpp
T
2025-09-18 17:55:52 -04:00

153 lines
4.4 KiB
C++

/* Copyright 2003-2008 ROBLOX Corporation, All Rights Reserved */
#include "DirectPhysicsReceiver.h"
#include "Compressor.h"
#include "GetTime.h"
#include "NetworkSettings.h"
#include "Streaming.h"
#include "Replicator.h"
#include "V8DataModel/PartInstance.h"
#include "V8DataModel/Workspace.h"
#include "V8World/World.h"
#include "V8World/Primitive.h"
#include "V8World/Assembly.h"
#include "util/standardout.h"
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include "NetworkProfiler.h"
DYNAMIC_FASTFLAG(PhysicsSenderUseOwnerTimestamp)
DYNAMIC_FASTFLAG(CleanUpInterpolationTimestamps)
SYNCHRONIZED_FASTFLAG(PhysicsPacketSendWorldStepTimestamp)
using namespace RBX;
using namespace RBX::Network;
void DirectPhysicsReceiver::receivePacket(RakNet::BitStream& inBitstream, RakNet::Time timeStamp, ReplicatorStats::PhysicsReceiverStats* _stats)
{
RakNet::Time interpolationTimestamp;
RBX::RemoteTime remoteSendTime;
if (SFFlag::getPhysicsPacketSendWorldStepTimestamp())
{
inBitstream >> interpolationTimestamp;
remoteSendTime = ((double)interpolationTimestamp / 1000.0f);
}
else
{
remoteSendTime = ((double)timeStamp / 1000.0f);
}
stats = _stats;
RakNet::Time now = RakNet::GetTime();
//RBXASSERT(now >= timeStamp); // Defect filed: DE6810
if (!SFFlag::getPhysicsPacketSendWorldStepTimestamp() && DFFlag::PhysicsSenderUseOwnerTimestamp && timeStamp > now)
{
timeStamp = now;
}
RakNet::Time deltaTime = SFFlag::getPhysicsPacketSendWorldStepTimestamp() ? now - interpolationTimestamp : now - timeStamp;//
// local RBX time when the packet was sent
Time localTime = replicator->raknetTimeToRbxTime(timeStamp);
while (true)
{
shared_ptr<PartInstance> part;
if (replicator->isStreamingEnabled())
{
bool done;
inBitstream >> done;
if (done)
break; // packet ended
bool cframeOnly;
inBitstream >> cframeOnly;
if (cframeOnly)
{
receiveMechanismCFrames(inBitstream, timeStamp, remoteSendTime);
continue;
}
else if (!receiveRootPart(part, inBitstream)) {
continue; // mechanism ended
}
}
else // non-streaming
{
if (!receiveRootPart(part, inBitstream)) {
break; // packet ended
}
BOOST_STATIC_ASSERT(sizeof(RakNet::Time) == sizeof(part->raknetTime));
}
// read mechanism if non-streaming OR (streaming and not cframe only)
if (part)
{
if (!iAmServer && localTime < part->getLastUpdateTime())
{
// old packet, discard
if (replicator->settings().printPhysicsErrors) {
RBX::StandardOut::singleton()->print(RBX::MESSAGE_INFO, "Discard old packet");
}
part.reset();
}
if (part)
{
RakNet::Time partTime = static_cast<RakNet::Time>(part->raknetTime);
if (partTime > (SFFlag::getPhysicsPacketSendWorldStepTimestamp() ? interpolationTimestamp : timeStamp) ) {
if (replicator->settings().printPhysicsErrors) {
RBX::StandardOut::singleton()->print(RBX::MESSAGE_INFO, "Physics-in old packet");
}
part.reset();
}
else
{
if (SFFlag::getPhysicsPacketSendWorldStepTimestamp())
{
// RakNetTime will no longer hold some arbitrary send time, but instead
// adjusted Physics Timestamp
partTime = interpolationTimestamp;
}
else
{
partTime = timeStamp;
}
}
}
}
RakNet::BitSize_t characterBits = inBitstream.GetReadOffset();
int numNodesInHistory;
receiveMechanism(inBitstream, part.get(), tempItem, remoteSendTime, numNodesInHistory);
if (stats && part && "Torso" == part->getName()) {
stats->details.characterAnim.increment();
stats->details.characterAnimSize.sample((inBitstream.GetReadOffset() - characterBits) / 8);
}
if (part) {
setPhysics(tempItem, remoteSendTime, deltaTime, numNodesInHistory);
if (!iAmServer)
{
if (DFFlag::CleanUpInterpolationTimestamps)
{
// Interpolation Delay has been re-purposed for use with relation to NetworkPing
// Interpolation Delay depends greatly on NetworkPing and Frequency of Updates.
part->setInterpolationDelay( (double)deltaTime/1000 );
}
else
{
part->setInterpolationDelay((localTime - part->getLastUpdateTime()).seconds());
}
part->setLastUpdateTime(localTime);
}
}
}
}