Network: Remove NetPacket class

It was badly designed
This commit is contained in:
SirLynix 2024-02-24 18:03:36 +01:00
parent 03ff328b5b
commit 7956e1552b
15 changed files with 44 additions and 711 deletions

View File

@ -40,7 +40,6 @@
#include <Nazara/Network/Export.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/NetBuffer.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/Network.hpp>
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/SocketPoller.hpp>

View File

@ -18,13 +18,13 @@
#define NAZARA_NETWORK_ENETHOST_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Network/ENetCompressor.hpp>
#include <Nazara/Network/ENetPeer.hpp>
#include <Nazara/Network/ENetProtocol.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/NetBuffer.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/SocketPoller.hpp>
#include <Nazara/Network/UdpSocket.hpp>
#include <NazaraUtils/Flags.hpp>
@ -45,11 +45,11 @@ namespace Nz
inline ~ENetHost();
ENetPacketRef AllocatePacket(ENetPacketFlags flags);
inline ENetPacketRef AllocatePacket(ENetPacketFlags flags, NetPacket&& data);
inline ENetPacketRef AllocatePacket(ENetPacketFlags flags, ByteArray&& payload);
inline void AllowsIncomingConnections(bool allow = true);
void Broadcast(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet);
void Broadcast(UInt8 channelId, ENetPacketFlags flags, ByteArray&& packet);
bool CheckEvents(ENetEvent* event);
@ -112,15 +112,15 @@ namespace Nz
struct PendingIncomingPacket
{
ByteArray data;
IpAddress from;
NetPacket data;
UInt32 deliveryTime;
};
struct PendingOutgoingPacket
{
ByteArray data;
IpAddress to;
NetPacket data;
UInt32 deliveryTime;
};

View File

@ -18,10 +18,10 @@ namespace Nz
Destroy();
}
inline ENetPacketRef ENetHost::AllocatePacket(ENetPacketFlags flags, NetPacket&& data)
inline ENetPacketRef ENetHost::AllocatePacket(ENetPacketFlags flags, ByteArray&& payload)
{
ENetPacketRef ref = AllocatePacket(flags);
ref->data = std::move(data);
ref->data = std::move(payload);
return ref;
}
@ -110,7 +110,7 @@ namespace Nz
inline void ENetHost::UpdateServiceTime()
{
// Use high precision clock for extra precision
m_serviceTime = static_cast<UInt32>(GetElapsedNanoseconds().AsMilliseconds());
m_serviceTime = static_cast<UInt32>(GetElapsedNanoseconds().AsMilliseconds()); // overflow is permitted
}
}

View File

@ -8,7 +8,8 @@
#define NAZARA_NETWORK_ENETPACKET_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Network/Export.hpp>
#include <NazaraUtils/MemoryPool.hpp>
#include <NazaraUtils/MovablePtr.hpp>
#include <NazaraUtils/Signal.hpp>
@ -34,8 +35,8 @@ namespace Nz
struct ENetPacket
{
ByteArray data;
ENetPacketFlags flags;
NetPacket data;
std::size_t poolIndex;
std::size_t referenceCount = 0;
UInt32 remainingFragments; // for ack

View File

@ -73,7 +73,7 @@ namespace Nz
void Reset();
bool Send(UInt8 channelId, ENetPacketRef packetRef);
bool Send(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet);
bool Send(UInt8 channelId, ENetPacketFlags flags, ByteArray&& payload);
void SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay);

View File

@ -1,74 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Export.hpp
#pragma once
#ifndef NAZARA_NETWORK_NETPACKET_HPP
#define NAZARA_NETWORK_NETPACKET_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Core/MemoryStream.hpp>
#include <Nazara/Network/Export.hpp>
#include <mutex>
namespace Nz
{
class NAZARA_NETWORK_API NetPacket : public ByteStream
{
friend class Network;
public:
inline NetPacket();
inline NetPacket(UInt16 netCode, std::size_t minCapacity = 0);
inline NetPacket(UInt16 netCode, const void* ptr, std::size_t size);
NetPacket(const NetPacket&) = delete;
NetPacket(NetPacket&& packet);
inline ~NetPacket();
inline const UInt8* GetConstData() const;
inline UInt8* GetData() const;
inline size_t GetDataSize() const;
inline UInt16 GetNetCode() const;
virtual void OnReceive(UInt16 netCode, const void* data, std::size_t size);
virtual const void* OnSend(std::size_t* newSize) const;
inline void Reset();
inline void Reset(UInt16 netCode, std::size_t minCapacity = 0);
inline void Reset(UInt16 netCode, const void* ptr, std::size_t size);
inline void Resize(std::size_t newSize);
inline void SetNetCode(UInt16 netCode);
NetPacket& operator=(const NetPacket&) = delete;
NetPacket& operator=(NetPacket&& packet);
static bool DecodeHeader(const void* data, UInt32* packetSize, UInt16* netCode);
static bool EncodeHeader(void* data, UInt32 packetSize, UInt16 netCode);
static constexpr std::size_t HeaderSize = sizeof(UInt32) + sizeof(UInt16); //< PacketSize + NetCode
private:
void OnEmptyStream() override;
void FreeStream();
void InitStream(std::size_t minCapacity, UInt64 cursorPos, OpenModeFlags openMode);
static bool Initialize();
static void Uninitialize();
std::unique_ptr<ByteArray> m_buffer;
MemoryStream m_memoryStream;
UInt16 m_netCode;
static std::recursive_mutex s_availableBuffersMutex;
static std::vector<std::pair<std::size_t, std::unique_ptr<ByteArray>>> s_availableBuffers;
};
}
#include <Nazara/Network/NetPacket.inl>
#endif // NAZARA_NETWORK_NETPACKET_HPP

View File

@ -1,222 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Export.hpp
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Network/Enums.hpp>
#include <cstring>
namespace Nz
{
/*!
* \brief Constructs a NetPacket object by default
*/
inline NetPacket::NetPacket() :
m_netCode(0)
{
}
/*!
* \brief Constructs a NetPacket object with a packet number and a minimal capacity
*
* \param netCode Packet number
* \param minCapacity Minimal capacity of the packet
*/
inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity)
{
Reset(netCode, minCapacity);
}
/*!
* \brief Constructs a NetPacket object with a packet number and raw memory
*
* \param netCode Packet number
* \param ptr Raw memory
* \param size Size of the memory
*/
inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size)
{
Reset(netCode, ptr, size);
}
/*!
* \brief Constructs a NetPacket object with another one by move semantic
*
* \param packet NetPacket to move into this
*/
inline NetPacket::NetPacket(NetPacket&& packet) :
ByteStream(std::move(packet)),
m_buffer(std::move(packet.m_buffer)),
m_memoryStream(std::move(packet.m_memoryStream)),
m_netCode(packet.m_netCode)
{
///< Redirect memory stream to the moved buffer
if (m_buffer)
{
m_memoryStream.SetBuffer(m_buffer.get(), m_memoryStream.GetOpenMode());
SetStream(&m_memoryStream);
}
}
/*!
* \brief Destructs the object
*/
inline NetPacket::~NetPacket()
{
FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
FreeStream();
}
/*!
* \brief Gets the raw buffer
* \return Constant raw buffer
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline const UInt8* NetPacket::GetConstData() const
{
NazaraAssert(m_buffer, "Invalid buffer");
return m_buffer->GetConstBuffer();
}
/*!
* \brief Gets the raw buffer
* \return Raw buffer
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline UInt8* NetPacket::GetData() const
{
NazaraAssert(m_buffer, "Invalid buffer");
return m_buffer->GetBuffer();
}
/*!
* \brief Gets the size of the data
* \return Size of the data
*/
inline size_t NetPacket::GetDataSize() const
{
if (m_buffer)
return m_buffer->GetSize() - HeaderSize;
else
return 0;
}
/*!
* \brief Gets the packet number
* \return Packet number
*/
inline UInt16 NetPacket::GetNetCode() const
{
return m_netCode;
}
/*!
* \brief Resets the packet
*/
inline void NetPacket::Reset()
{
FreeStream();
}
/*!
* \brief Resets the packet with a packet number and a minimal capacity
*
* \param netCode Packet number
* \param minCapacity Minimal capacity of the packet
*/
inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity)
{
InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite);
m_netCode = netCode;
}
/*!
* \brief Resets the packet with a packet number and raw memory
*
* \param netCode Packet number
* \param ptr Raw memory
* \param size Size of the memory
*/
inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size)
{
InitStream(HeaderSize + size, HeaderSize, OpenMode::Read);
m_buffer->Resize(HeaderSize + size);
if (ptr)
std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size);
m_netCode = netCode;
}
/*!
* \brief Resizes the packet
*
* \param newSize Size for the resizing operation
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline void NetPacket::Resize(std::size_t newSize)
{
NazaraAssert(m_buffer, "Invalid buffer");
m_buffer->Resize(newSize);
}
/*!
* \brief Sets the packet number
*
* \param netCode Packet number
*/
inline void NetPacket::SetNetCode(UInt16 netCode)
{
m_netCode = netCode;
}
/*!
* \brief Moves the NetPacket into this
* \return A reference to this
*
* \param packet NetPacket to move in this
*/
inline NetPacket& NetPacket::operator=(NetPacket&& packet)
{
FreeStream();
ByteStream::operator=(std::move(packet));
m_buffer = std::move(packet.m_buffer);
m_memoryStream = std::move(packet.m_memoryStream);
m_netCode = packet.m_netCode;
///< Redirect memory stream to the moved buffer
if (m_buffer)
{
m_memoryStream.SetBuffer(m_buffer.get(), m_memoryStream.GetOpenMode());
SetStream(&m_memoryStream);
}
else
SetStream(static_cast<Stream*>(nullptr));
return *this;
}
}

View File

@ -17,7 +17,6 @@
namespace Nz
{
struct NetBuffer;
class NetPacket;
class NAZARA_NETWORK_API TcpClient : public AbstractSocket, public Stream
{
@ -46,11 +45,9 @@ namespace Nz
SocketState PollForConnected(UInt64 waitDuration = 0);
bool Receive(void* buffer, std::size_t size, std::size_t* received);
bool ReceivePacket(NetPacket* packet);
bool Send(const void* buffer, std::size_t size, std::size_t* sent);
bool SendMultiple(const NetBuffer* buffers, std::size_t bufferCount, std::size_t* sent);
bool SendPacket(const NetPacket& packet);
SocketState WaitForConnected(UInt64 msTimeout = 3000);

View File

@ -14,7 +14,6 @@
namespace Nz
{
struct NetBuffer;
class NetPacket;
class NAZARA_NETWORK_API UdpSocket : public AbstractSocket
{
@ -40,11 +39,9 @@ namespace Nz
bool Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received);
bool ReceiveMultiple(NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, std::size_t* received);
bool ReceivePacket(NetPacket* packet, IpAddress* from);
bool Send(const IpAddress& to, const void* buffer, std::size_t size, std::size_t* sent);
bool SendMultiple(const IpAddress& to, const NetBuffer* buffers, std::size_t bufferCount, std::size_t* sent);
bool SendPacket(const IpAddress& to, const NetPacket& packet);
UdpSocket& operator=(const UdpSocket& udpSocket) = delete;
UdpSocket& operator=(UdpSocket && udpSocket) noexcept = default;

View File

@ -16,7 +16,6 @@
#include <Nazara/Core/StringExt.hpp>
#include <Nazara/Network/Algorithm.hpp>
#include <Nazara/Network/ENetPeer.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <NazaraUtils/OffsetOf.hpp>
namespace Nz
@ -56,7 +55,7 @@ namespace Nz
return enetPacket;
}
void ENetHost::Broadcast(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet)
void ENetHost::Broadcast(UInt8 channelId, ENetPacketFlags flags, ByteArray&& packet)
{
ENetPacketRef enetPacket = AllocatePacket(flags, std::move(packet));
@ -545,8 +544,8 @@ namespace Nz
if (peer)
{
peer->m_address = m_receivedAddress;
peer->m_incomingDataTotal += UInt32(m_receivedDataLength);
peer->m_totalByteReceived += UInt32(m_receivedDataLength);
peer->m_incomingDataTotal += SafeCast<UInt32>(m_receivedDataLength);
peer->m_totalByteReceived += SafeCast<UInt32>(m_receivedDataLength);
}
auto commandError = [&]() -> bool
@ -715,8 +714,8 @@ namespace Nz
shouldReceive = false;
m_receivedAddress = it->from;
receivedLength = it->data.GetDataSize();
std::memcpy(m_packetData[0].data(), it->data.GetConstData() + NetPacket::HeaderSize, receivedLength);
receivedLength = it->data.GetSize();
std::memcpy(m_packetData[0].data(), it->data.GetConstBuffer(), receivedLength);
m_pendingIncomingPackets.erase(it);
break;
@ -743,7 +742,7 @@ namespace Nz
PendingIncomingPacket pendingPacket;
pendingPacket.deliveryTime = m_serviceTime + delay;
pendingPacket.from = m_receivedAddress;
pendingPacket.data.Reset(0, m_packetData[0].data(), receivedLength);
pendingPacket.data = ByteArray(m_packetData[0].data(), receivedLength);
auto it = std::upper_bound(m_pendingIncomingPackets.begin(), m_pendingIncomingPackets.end(), pendingPacket, [] (const PendingIncomingPacket& first, const PendingIncomingPacket& second)
{
@ -948,7 +947,7 @@ namespace Nz
++m_bufferCount;
NetBuffer& packetBuffer = m_buffers[m_bufferCount];
packetBuffer.data = outgoingCommand->packet->data.GetData() + NetPacket::HeaderSize + outgoingCommand->fragmentOffset;
packetBuffer.data = outgoingCommand->packet->data.GetBuffer() + outgoingCommand->fragmentOffset;
packetBuffer.dataLength = outgoingCommand->fragmentLength;
m_packetSize += packetBuffer.dataLength;
@ -1093,10 +1092,10 @@ namespace Nz
for (std::size_t i = 0; i < m_bufferCount; ++i)
{
NetBuffer& buffer = m_buffers[i];
outgoingPacket.data.Write(buffer.data, buffer.dataLength);
outgoingPacket.data.Append(buffer.data, buffer.dataLength);
}
m_totalSentData += outgoingPacket.data.GetDataSize();
m_totalSentData += outgoingPacket.data.GetSize();
// Add it to the right place
auto it = std::upper_bound(m_pendingOutgoingPackets.begin(), m_pendingOutgoingPackets.end(), outgoingPacket, [](const PendingOutgoingPacket& first, const PendingOutgoingPacket& second)
@ -1151,7 +1150,7 @@ namespace Nz
if (m_serviceTime < it->deliveryTime)
break;
if (!m_socket.Send(it->to, it->data.GetConstData() + NetPacket::HeaderSize, it->data.GetDataSize(), nullptr))
if (!m_socket.Send(it->to, it->data.GetConstBuffer(), it->data.GetSize(), nullptr))
return -1;
}
@ -1223,7 +1222,7 @@ namespace Nz
++m_bufferCount;
NetBuffer& packetBuffer = m_buffers[m_bufferCount];
packetBuffer.data = outgoingCommand->packet->data.GetData() + NetPacket::HeaderSize + outgoingCommand->fragmentOffset;
packetBuffer.data = outgoingCommand->packet->data.GetBuffer() + outgoingCommand->fragmentOffset;
packetBuffer.dataLength = outgoingCommand->fragmentLength;
m_packetSize += packetBuffer.dataLength;

View File

@ -15,7 +15,6 @@
#include <Nazara/Network/ENetPeer.hpp>
#include <Nazara/Network/Algorithm.hpp>
#include <Nazara/Network/ENetHost.hpp>
#include <Nazara/Network/NetPacket.hpp>
namespace Nz
{
@ -101,7 +100,7 @@ namespace Nz
IncomingCommmand& incomingCommand = m_dispatchedCommands.front();
m_totalWaitingData -= incomingCommand.packet->data.GetDataSize();
m_totalWaitingData -= incomingCommand.packet->data.GetSize();
if (packet)
*packet = std::move(incomingCommand.packet);
@ -175,9 +174,9 @@ namespace Nz
ResetQueues();
}
bool ENetPeer::Send(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet)
bool ENetPeer::Send(UInt8 channelId, ENetPacketFlags flags, ByteArray&& payload)
{
return Send(channelId, m_host->AllocatePacket(flags, std::move(packet)));
return Send(channelId, m_host->AllocatePacket(flags, std::move(payload)));
}
void ENetPeer::SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay)
@ -196,14 +195,14 @@ namespace Nz
bool ENetPeer::Send(UInt8 channelId, ENetPacketRef packetRef)
{
if (m_state != ENetPeerState::Connected || channelId >= m_channels.size() || packetRef->data.GetDataSize() > m_host->m_maximumPacketSize)
if (m_state != ENetPeerState::Connected || channelId >= m_channels.size() || packetRef->data.GetSize() > m_host->m_maximumPacketSize)
return false;
Channel& channel = m_channels[channelId];
UInt16 fragmentLength = static_cast<UInt16>(m_mtu - sizeof(ENetProtocolHeader) - sizeof(ENetProtocolSendFragment));
UInt32 packetSize = static_cast<UInt32>(packetRef->data.GetDataSize());
UInt32 packetSize = SafeCast<UInt32>(packetRef->data.GetSize());
if (packetSize > fragmentLength)
{
UInt32 fragmentCount = (packetSize + fragmentLength - 1) / fragmentLength;
@ -259,21 +258,20 @@ namespace Nz
if ((packetRef->flags & (ENetPacketFlag::Reliable | ENetPacketFlag::Unsequenced)) == ENetPacketFlag::Unsequenced)
{
command.header.command = ENetProtocolCommand_SendUnsequenced | ENetProtocolFlag_Unsequenced;
command.sendUnsequenced.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize()));
command.sendUnsequenced.dataLength = HostToNet(SafeCast<UInt16>(packetRef->data.GetSize()));
}
else if (packetRef->flags & ENetPacketFlag::Reliable || channel.outgoingUnreliableSequenceNumber >= 0xFFFF)
{
command.header.command = ENetProtocolCommand_SendReliable | ENetProtocolFlag_Acknowledge;
command.sendReliable.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize()));
command.sendReliable.dataLength = HostToNet(SafeCast<UInt16>(packetRef->data.GetSize()));
}
else
{
command.header.command = ENetProtocolCommand_SendUnreliable;
command.sendUnreliable.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize()));
command.sendUnreliable.dataLength = HostToNet(SafeCast<UInt16>(packetRef->data.GetSize()));
}
QueueOutgoingCommand(command, packetRef, 0, UInt16(packetSize));
QueueOutgoingCommand(command, packetRef, 0, SafeCast<UInt16>(packetSize));
return true;
}
}
@ -651,7 +649,7 @@ namespace Nz
break;
if ((incomingCommand.command.header.command & ENetProtocolCommand_Mask) != ENetProtocolCommand_SendFragment ||
totalLength != incomingCommand.packet->data.GetDataSize() || fragmentCount != incomingCommand.fragments.GetSize())
totalLength != incomingCommand.packet->data.GetSize() || fragmentCount != incomingCommand.fragments.GetSize())
return false;
startCommand = &incomingCommand;
@ -675,10 +673,10 @@ namespace Nz
startCommand->fragments.Set(fragmentNumber, true);
if (fragmentOffset + fragmentLength > startCommand->packet->data.GetDataSize())
fragmentLength = static_cast<UInt16>(startCommand->packet->data.GetDataSize() - fragmentOffset);
if (fragmentOffset + fragmentLength > startCommand->packet->data.GetSize())
fragmentLength = static_cast<UInt16>(startCommand->packet->data.GetSize() - fragmentOffset);
std::memcpy(startCommand->packet->data.GetData() + NetPacket::HeaderSize + fragmentOffset, reinterpret_cast<const UInt8*>(command) + sizeof(ENetProtocolSendFragment), fragmentLength);
std::memcpy(startCommand->packet->data.GetBuffer() + fragmentOffset, reinterpret_cast<const UInt8*>(command) + sizeof(ENetProtocolSendFragment), fragmentLength);
if (startCommand->fragmentsRemaining <= 0)
DispatchIncomingReliableCommands(channel);
@ -779,7 +777,7 @@ namespace Nz
break;
if ((incomingCommand.command.header.command & ENetProtocolCommand_Mask) != ENetProtocolCommand_SendUnreliableFragment ||
totalLength != incomingCommand.packet->data.GetDataSize() || fragmentCount != incomingCommand.fragments.GetSize())
totalLength != incomingCommand.packet->data.GetSize() || fragmentCount != incomingCommand.fragments.GetSize())
return false;
startCommand = &incomingCommand;
@ -800,10 +798,10 @@ namespace Nz
startCommand->fragments.Set(fragmentNumber, true);
if (fragmentOffset + fragmentLength > startCommand->packet->data.GetDataSize())
fragmentLength = static_cast<UInt16>(startCommand->packet->data.GetDataSize() - fragmentOffset);
if (fragmentOffset + fragmentLength > startCommand->packet->data.GetSize())
fragmentLength = static_cast<UInt16>(startCommand->packet->data.GetSize() - fragmentOffset);
std::memcpy(startCommand->packet->data.GetData() + NetPacket::HeaderSize + fragmentOffset, reinterpret_cast<const UInt8*>(command) + sizeof(ENetProtocolSendFragment), fragmentLength);
std::memcpy(startCommand->packet->data.GetBuffer() + fragmentOffset, reinterpret_cast<const UInt8*>(command) + sizeof(ENetProtocolSendFragment), fragmentLength);
if (startCommand->fragmentsRemaining <= 0)
DispatchIncomingUnreliableCommands(channel);
@ -1238,7 +1236,7 @@ namespace Nz
return nullptr;
ENetPacketRef packet = m_host->AllocatePacket(ENetPacketFlags(flags));
packet->data.Reset(0, data, dataLength);
packet->data = ByteArray(data, dataLength);
IncomingCommmand incomingCommand;
incomingCommand.reliableSequenceNumber = command.header.reliableSequenceNumber;
@ -1249,7 +1247,7 @@ namespace Nz
incomingCommand.fragmentsRemaining = fragmentCount;
if (packet)
m_totalWaitingData += packet->data.GetDataSize();
m_totalWaitingData += packet->data.GetSize();
auto it = commandList->insert(currentCommand.base(), incomingCommand);

View File

@ -1,175 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Export.hpp
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Core/MemoryView.hpp>
namespace Nz
{
/*!
* \ingroup network
* \class Nz::NetPacket
* \brief Network class that represents a packet
*/
/*!
* \brief Operation to do when receiving data
*
* \param netCode Packet number
* \param data Raw memory
* \param size Size of the memory
*/
void NetPacket::OnReceive(UInt16 netCode, const void* data, std::size_t size)
{
Reset(netCode, data, size);
}
/*!
* \brief Operation to do when sending data
* \return Beggining of the raw memory
*
* \param newSize Size of the memory to send
*
* \remark Produces a NazaraAssert if newSize is invalid
* \remark Produces a NazaraAssert if net code is invalid
* \remark Produces a NazaraError if header could not be encoded
*/
const void* NetPacket::OnSend(std::size_t* newSize) const
{
NazaraAssert(newSize, "Invalid size pointer");
NazaraAssert(m_netCode != 0, "Invalid NetCode");
std::size_t size = m_buffer->GetSize();
if (!EncodeHeader(m_buffer->GetBuffer(), static_cast<UInt32>(size), m_netCode))
{
NazaraError("failed to encode packet header");
return nullptr;
}
*newSize = size;
return m_buffer->GetBuffer();
}
/*!
* \brief Decodes the header of the packet
* \return true If successful
*
* \param data Raw memory
* \param packetSize Size of the packet
* \param netCode Packet number
*/
bool NetPacket::DecodeHeader(const void* data, UInt32* packetSize, UInt16* netCode)
{
MemoryView stream(data, HeaderSize);
SerializationContext context;
context.stream = &stream;
return Unserialize(context, packetSize) && Unserialize(context, netCode);
}
/*!
* \brief Encodes the header of the packet
* \return true If successful
*
* \param data Raw memory
* \param packetSize Size of the packet
* \param netCode Packet number
*/
bool NetPacket::EncodeHeader(void* data, UInt32 packetSize, UInt16 netCode)
{
MemoryView stream(data, HeaderSize);
SerializationContext context;
context.stream = &stream;
return Serialize(context, packetSize) && Serialize(context, netCode);
}
/*!
* \brief Operation to do when stream is empty
*/
void NetPacket::OnEmptyStream()
{
Reset(0);
}
/*!
* \brief Frees the stream
*/
void NetPacket::FreeStream()
{
if (!m_buffer)
return;
std::size_t size = m_buffer->GetSize();
std::lock_guard<std::recursive_mutex> lock(s_availableBuffersMutex);
s_availableBuffers.emplace_back(std::make_pair(size, std::move(m_buffer)));
}
/*!
* \brief Inits the internal stream
*
* \param minCapacity Minimal capacity of the stream
* \param cursorPos Position of the cursor in the stream
* \param openMode Flag of the stream
*
* \remark Produces a NazaraAssert if cursor position is greather than the capacity
*/
void NetPacket::InitStream(std::size_t minCapacity, UInt64 cursorPos, OpenModeFlags openMode)
{
NazaraAssert(minCapacity >= cursorPos, "Cannot init stream with a smaller capacity than wanted cursor pos");
{
std::lock_guard<std::recursive_mutex> lock(s_availableBuffersMutex);
FreeStream(); //< In case it wasn't released yet
if (!s_availableBuffers.empty())
{
m_buffer = std::move(s_availableBuffers.back().second);
s_availableBuffers.pop_back();
}
}
if (!m_buffer)
m_buffer = std::make_unique<ByteArray>();
m_buffer->Resize(minCapacity);
m_memoryStream.SetBuffer(m_buffer.get(), openMode);
m_memoryStream.SetCursorPos(cursorPos);
SetStream(&m_memoryStream);
}
/*!
* \brief Initializes the NetPacket class
* \return true If initialization is successful
*/
bool NetPacket::Initialize()
{
return true;
}
/*!
* \brief Uninitializes the NetPacket class
*/
void NetPacket::Uninitialize()
{
s_availableBuffers.clear();
}
std::recursive_mutex NetPacket::s_availableBuffersMutex;
std::vector<std::pair<std::size_t, std::unique_ptr<ByteArray>>> NetPacket::s_availableBuffers;
}

View File

@ -7,11 +7,9 @@
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Network/Export.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/WebService.hpp>
#include <NazaraUtils/CallOnExit.hpp>
#ifndef NAZARA_PLATFORM_WEB
#include <Nazara/Network/CurlLibrary.hpp>
#endif
@ -42,9 +40,6 @@ namespace Nz
if (!SocketImpl::Initialize())
throw std::runtime_error("failed to initialize socket implementation");
if (!NetPacket::Initialize())
throw std::runtime_error("failed to initialize packets");
#ifndef NAZARA_PLATFORM_WEB
if (config.webServices)
{
@ -61,7 +56,6 @@ namespace Nz
m_curlLibrary.reset();
#endif
NetPacket::Uninitialize();
SocketImpl::Uninitialize();
}

View File

@ -5,8 +5,7 @@
#include <Nazara/Network/TcpClient.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/StringExt.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <NazaraUtils/CallOnExit.hpp>
#include <NazaraUtils/CallOnExit.hpp>
#include <limits>
#if defined(NAZARA_PLATFORM_WINDOWS)
@ -22,7 +21,7 @@ namespace Nz
{
/*!
* \ingroup network
* \class Nz::TcpClient
* \class Nz::TcpClient,l
* \brief Network class that represents a client in a TCP connection
*/
@ -231,90 +230,6 @@ namespace Nz
return true;
}
/*!
* \brief Receives the packet available
* \return true If packet received
*
* \param packet Packet to receive
*
* \remark Produces a NazaraAssert if packet is invalid
* \remark Produces a NazaraAssert if packet size is inferior to the header size
* \remark Produces a NazaraWarning if packet's header is invalid
*/
bool TcpClient::ReceivePacket(NetPacket* packet)
{
//TODO: Every packet requires at least two Receive call, using an internal buffer of a fixed size would prevent this
NazaraAssert(packet, "Invalid packet");
if (!m_pendingPacket.headerReceived)
{
m_pendingPacket.data.Resize(NetPacket::HeaderSize);
std::size_t received;
if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], NetPacket::HeaderSize - m_pendingPacket.received, &received))
return false;
m_pendingPacket.received += received;
//TODO: Should never happen in production !
NazaraAssert(m_pendingPacket.received <= NetPacket::HeaderSize, "Received more data than header size");
if (m_pendingPacket.received >= NetPacket::HeaderSize)
{
UInt32 size;
if (!NetPacket::DecodeHeader(m_pendingPacket.data.GetConstBuffer(), &size, &m_pendingPacket.netcode))
{
m_lastError = SocketError::Packet;
NazaraWarning("Invalid header data");
return false;
}
m_pendingPacket.data.Resize(size - NetPacket::HeaderSize);
m_pendingPacket.headerReceived = true;
m_pendingPacket.received = 0;
}
}
// We may have just received the header now
if (m_pendingPacket.headerReceived)
{
UInt32 packetSize = static_cast<UInt32>(m_pendingPacket.data.GetSize()); //< Total packet size
if (packetSize == 0)
{
// Special case: our packet carry no data
packet->Reset(m_pendingPacket.netcode);
// And reset every state
m_pendingPacket.data.Clear();
m_pendingPacket.headerReceived = false;
m_pendingPacket.received = 0;
return true;
}
std::size_t received;
if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], packetSize - m_pendingPacket.received, &received))
return false;
m_pendingPacket.received += received;
//TODO: Should never happen in production !
NazaraAssert(m_pendingPacket.received <= packetSize, "Received more data than packet size");
if (m_pendingPacket.received >= packetSize)
{
// Okay we received the whole packet, copy it
packet->Reset(m_pendingPacket.netcode, m_pendingPacket.data.GetConstBuffer(), m_pendingPacket.data.GetSize());
// And reset every state
m_pendingPacket.data.Clear();
m_pendingPacket.headerReceived = false;
m_pendingPacket.received = 0;
return true;
}
}
return false;
}
/*!
* \brief Sends the data available
* \return true If data sended
@ -327,7 +242,6 @@ namespace Nz
* \remark Produces a NazaraAssert if socket is invalid
* \remark Produces a NazaraAssert if buffer and its size is invalid
*/
bool TcpClient::Send(const void* buffer, std::size_t size, std::size_t* sent)
{
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
@ -409,29 +323,6 @@ namespace Nz
return true;
}
/*!
* \brief Sends the packet available
* \return true If packet sent
*
* \param packet Packet to send
*
* \remark Produces a NazaraError if packet could not be prepared for sending
*/
bool TcpClient::SendPacket(const NetPacket& packet)
{
std::size_t size = 0;
const UInt8* ptr = static_cast<const UInt8*>(packet.OnSend(&size));
if (!ptr)
{
m_lastError = SocketError::Packet;
NazaraError("failed to prepare packet");
return false;
}
return Send(ptr, size, nullptr);
}
/*!
* \brief Waits for being connected before time out
* \return The new socket state, either Connected if connection did succeed or NotConnected if an error occurred

View File

@ -5,7 +5,6 @@
#include <Nazara/Network/UdpSocket.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/StringExt.hpp>
#include <Nazara/Network/NetPacket.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Network/Win32/SocketImpl.hpp>
@ -155,53 +154,6 @@ namespace Nz
return true;
}
/*!
* \brief Receives the packet available
* \return true If packet received
*
* \param packet Packet to receive
* \param from IpAddress of the peer
*
* \remark Produces a NazaraAssert if packet is invalid
* \remark Produces a NazaraWarning if packet's header is invalid
*/
bool UdpSocket::ReceivePacket(NetPacket* packet, IpAddress* from)
{
NazaraAssert(packet, "Invalid packet");
// I'm not sure what's the best between having a 65k bytes buffer ready for any datagram size
// or querying the next datagram size every time, for now I'll leave it as is
packet->Reset(0, std::numeric_limits<UInt16>::max());
packet->Resize(std::numeric_limits<UInt16>::max());
std::size_t received;
if (!Receive(packet->GetData(), static_cast<std::size_t>(packet->GetSize()), from, &received))
return false;
if (received == 0)
return false; //< No datagram received
Nz::UInt16 netCode;
Nz::UInt32 packetSize;
if (!NetPacket::DecodeHeader(packet->GetConstData(), &packetSize, &netCode))
{
m_lastError = SocketError::Packet;
NazaraWarning("invalid header data");
return false;
}
if (packetSize != received)
{
m_lastError = SocketError::Packet;
NazaraWarningFmt("Invalid packet size (packet size is {0} bytes, received {1} bytes)", packetSize, received);
return false;
}
packet->Resize(received);
packet->SetNetCode(netCode);
return true;
}
/*!
* \brief Sends the data available
* \return true If data sended
@ -257,30 +209,6 @@ namespace Nz
return true;
}
/*!
* \brief Sends the packet available
* \return true If packet sent
*
* \param to IpAddress of the peer
* \param packet Packet to send
*
* \remark Produces a NazaraError if packet could not be prepared for sending
*/
bool UdpSocket::SendPacket(const IpAddress& to, const NetPacket& packet)
{
std::size_t size = 0;
const UInt8* ptr = static_cast<const UInt8*>(packet.OnSend(&size));
if (!ptr)
{
m_lastError = SocketError::Packet;
NazaraError("failed to prepare packet");
return false;
}
return Send(to, ptr, size, nullptr);
}
/*!
* \brief Operation to do when closing socket
*/