mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Engine: fix netchan bugs and add SendData()
Fixed bug in CNetChan::SendNetMsg() where the return value of INetMessage::WriteToBuffer() was not checked, nor did we return if the stream we added the message in was overflowed. If the function gets to the stage of writing the msg in the buffer, we need to return true only if we didn't overflow AND if the msg was successfully written. Also added a method for sending bitbuf data into stream of choice.
This commit is contained in:
parent
b3cd76aa70
commit
976f1ab5ae
@ -19,16 +19,18 @@
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the netchannel network loss
|
||||
// Purpose: gets the netchannel resend rate
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float CNetChan::GetNetworkLoss() const
|
||||
float CNetChan::GetResendRate() const
|
||||
{
|
||||
int64_t totalupdates = this->m_DataFlow[FLOW_INCOMING].totalupdates;
|
||||
const int64_t totalupdates = this->m_DataFlow[FLOW_INCOMING].totalupdates;
|
||||
|
||||
if (!totalupdates && !this->m_nSequencesSkipped_MAYBE)
|
||||
return 0.0f;
|
||||
|
||||
float lossRate = (float)(totalupdates + m_nSequencesSkipped_MAYBE);
|
||||
|
||||
if (totalupdates + m_nSequencesSkipped_MAYBE < 0.0f)
|
||||
lossRate += float(2 ^ 64);
|
||||
|
||||
@ -64,6 +66,36 @@ double CNetChan::GetTimeConnected(void) const
|
||||
return (t > 0.0) ? t : 0.0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the number of bits written in selected stream
|
||||
//-----------------------------------------------------------------------------
|
||||
int CNetChan::GetNumBitsWritten(const bool bReliable)
|
||||
{
|
||||
bf_write* pStream = &m_StreamUnreliable;
|
||||
|
||||
if (bReliable)
|
||||
{
|
||||
pStream = &m_StreamReliable;
|
||||
}
|
||||
|
||||
return pStream->GetNumBitsWritten();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the number of bits written in selected stream
|
||||
//-----------------------------------------------------------------------------
|
||||
int CNetChan::GetNumBitsLeft(const bool bReliable)
|
||||
{
|
||||
bf_write* pStream = &m_StreamUnreliable;
|
||||
|
||||
if (bReliable)
|
||||
{
|
||||
pStream = &m_StreamReliable;
|
||||
}
|
||||
|
||||
return pStream->GetNumBitsLeft();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: flows a new packet
|
||||
// Input : *pChan -
|
||||
@ -394,8 +426,9 @@ bool CNetChan::ProcessMessages(bf_read* buf)
|
||||
|
||||
if (!NET_ReadMessageType(&cmd, buf) && buf->m_bOverflow)
|
||||
{
|
||||
Warning(eDLL_T::ENGINE, "%s(%s): Incoming buffer overflow!\n", __FUNCTION__, GetAddress());
|
||||
Error(eDLL_T::ENGINE, 0, "%s(%s): Incoming buffer overflow!\n", __FUNCTION__, GetAddress());
|
||||
m_MessageHandler->ConnectionCrashed("Buffer overflow in net message");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -475,6 +508,12 @@ bool CNetChan::ProcessMessages(bf_read* buf)
|
||||
}
|
||||
}
|
||||
|
||||
bool CNetChan::ReadSubChannelData(bf_read& buf)
|
||||
{
|
||||
// TODO: rebuild this and hook
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send message
|
||||
// Input : &msg -
|
||||
@ -482,10 +521,10 @@ bool CNetChan::ProcessMessages(bf_read* buf)
|
||||
// bVoice -
|
||||
// Output : true on success, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetChan::SendNetMsg(INetMessage& msg, bool bForceReliable, bool bVoice)
|
||||
bool CNetChan::SendNetMsg(INetMessage& msg, const bool bForceReliable, const bool bVoice)
|
||||
{
|
||||
if (remote_address.GetType() == netadrtype_t::NA_NULL)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
bf_write* pStream = &m_StreamUnreliable;
|
||||
|
||||
@ -495,19 +534,59 @@ bool CNetChan::SendNetMsg(INetMessage& msg, bool bForceReliable, bool bVoice)
|
||||
if (bVoice)
|
||||
pStream = &m_StreamVoice;
|
||||
|
||||
if (pStream != &m_StreamUnreliable ||
|
||||
pStream->GetNumBytesLeft() >= NET_UNRELIABLE_STREAM_MINSIZE)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_Lock);
|
||||
if (pStream == &m_StreamUnreliable && pStream->GetNumBytesLeft() < NET_UNRELIABLE_STREAM_MINSIZE)
|
||||
return true;
|
||||
|
||||
pStream->WriteUBitLong(msg.GetType(), NETMSG_TYPE_BITS);
|
||||
if (!pStream->IsOverflowed())
|
||||
msg.WriteToBuffer(pStream);
|
||||
AcquireSRWLockExclusive(&m_Lock);
|
||||
|
||||
ReleaseSRWLockExclusive(&m_Lock);
|
||||
}
|
||||
pStream->WriteUBitLong(msg.GetType(), NETMSG_TYPE_BITS);
|
||||
const bool ret = msg.WriteToBuffer(pStream);
|
||||
|
||||
return true;
|
||||
ReleaseSRWLockExclusive(&m_Lock);
|
||||
|
||||
return !pStream->IsOverflowed() && ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send data
|
||||
// Input : &msg -
|
||||
// bReliable -
|
||||
// Output : true on success, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetChan::SendData(bf_write& msg, const bool bReliable)
|
||||
{
|
||||
// Always queue any pending reliable data ahead of the fragmentation buffer
|
||||
|
||||
if (remote_address.GetType() == netadrtype_t::NA_NULL)
|
||||
return true;
|
||||
|
||||
if (msg.GetNumBitsWritten() <= 0)
|
||||
return true;
|
||||
|
||||
if (msg.IsOverflowed() && !bReliable)
|
||||
return true;
|
||||
|
||||
bf_write& buf = bReliable
|
||||
? m_StreamReliable
|
||||
: m_StreamUnreliable;
|
||||
|
||||
const int dataBits = msg.GetNumBitsWritten();
|
||||
const int bitsLeft = buf.GetNumBitsLeft();
|
||||
|
||||
if (dataBits > bitsLeft)
|
||||
{
|
||||
if (bReliable)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, 0, "%s(%s): Data too large for reliable buffer (%i > %i)!\n",
|
||||
__FUNCTION__, GetAddress(), msg.GetNumBytesWritten(), buf.GetNumBytesLeft());
|
||||
|
||||
m_MessageHandler->ChannelDisconnect("reliable buffer is full");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return buf.WriteBits(msg.GetData(), dataBits);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
inline int GetDataRate(void) const { return m_Rate; }
|
||||
inline int GetBufferSize(void) const { return NET_FRAMES_BACKUP; }
|
||||
|
||||
float GetNetworkLoss() const;
|
||||
float GetResendRate() const;
|
||||
|
||||
inline float GetLatency(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].latency; }
|
||||
inline float GetAvgChoke(int flow) const { Assert(flow >= 0 && flow < SDK_ARRAYSIZE(m_DataFlow)); return m_DataFlow[flow].avgchoke; }
|
||||
@ -128,13 +128,17 @@ public:
|
||||
inline int GetSocket(void) const { return m_Socket; }
|
||||
inline const bf_write& GetStreamVoice(void) const { return m_StreamVoice; }
|
||||
inline const netadr_t& GetRemoteAddress(void) const { return remote_address; }
|
||||
|
||||
int GetNumBitsWritten(const bool bReliable);
|
||||
int GetNumBitsLeft(const bool bReliable);
|
||||
inline bool IsOverflowed(void) const { return m_StreamReliable.IsOverflowed(); }
|
||||
|
||||
bool HasPendingReliableData(void);
|
||||
|
||||
inline bool CanPacket(void) const { return CNetChan__CanPacket(this); }
|
||||
inline int SendDatagram(bf_write* pDatagram) { return CNetChan__SendDatagram(this, pDatagram); }
|
||||
bool SendNetMsg(INetMessage& msg, bool bForceReliable, bool bVoice);
|
||||
bool SendNetMsg(INetMessage& msg, const bool bForceReliable, const bool bVoice);
|
||||
bool SendData(bf_write& msg, const bool bReliable);
|
||||
|
||||
INetMessage* FindMessage(int type);
|
||||
bool RegisterMessage(INetMessage* msg);
|
||||
@ -144,6 +148,8 @@ public:
|
||||
void FreeReceiveList();
|
||||
bool ProcessMessages(bf_read* pMsg);
|
||||
|
||||
bool ReadSubChannelData(bf_read& buf);
|
||||
|
||||
static void _Shutdown(CNetChan* pChan, const char* szReason, uint8_t bBadRep, bool bRemoveNow);
|
||||
static bool _ProcessMessages(CNetChan* pChan, bf_read* pMsg);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user