From c7a0e7b930cc78a71e6e583c6d26b190da0ccc89 Mon Sep 17 00:00:00 2001 From: stramer Date: Mon, 31 May 2021 14:52:50 -0700 Subject: [PATCH 1/3] [LYN-4366] Add API documentation for AzNetworking, Mutiplayer Gem, and Multiplayer Compression Gem classes. Signed-off-by: stramer --- .../ConnectionLayer/IConnection.h | 6 +++ .../ConnectionLayer/IConnectionListener.h | 6 +++ .../ConnectionLayer/IConnectionSet.h | 5 ++ .../AzNetworking/Framework/ICompressor.h | 26 +++++++--- .../Framework/INetworkInterface.h | 11 +++- .../AzNetworking/Framework/INetworking.h | 11 ++++ .../AzNetworking/PacketLayer/IPacket.h | 9 ++++ .../AzNetworking/PacketLayer/IPacketHeader.h | 13 +++++ .../AzNetworking/Serialization/ISerializer.h | 12 +++++ .../TcpTransport/TcpNetworkInterface.h | 38 ++++++++++++++ .../UdpTransport/UdpNetworkInterface.h | 52 +++++++++++++++++-- .../Code/Include/Multiplayer/IMultiplayer.h | 27 +++++++--- .../Include/Multiplayer/IMultiplayerTools.h | 10 ++-- 13 files changed, 207 insertions(+), 19 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h index 4ef8ca44d4..53505c556f 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h @@ -44,6 +44,12 @@ namespace AzNetworking //! @class IConnection //! @brief interface class for network connections. + //! + //! IConnection provides a pure-virtual interface for all network connection types. The two child classes are TcpConnection + //! and UdpConnection, though the pure-virtual interface operates largely the same for both. IConnections provide access to + //! a ConnectionMetrics object which provides a variety of metrics on the connection itself such as data rate, RTT and + //! packet statistics. + class IConnection { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionListener.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionListener.h index af9e26c765..219ae2b005 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionListener.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionListener.h @@ -22,6 +22,12 @@ namespace AzNetworking { //! @class IConnectionListener //! @brief interface class for application layer dealing with connection level events. + //! + //! IConnectionListener defines an abstract interface that the user of AzNetworking is expected to implement to react and + //! handle all IConnection related events, including the handling of any received IPacket derived packets. The AzNetworking + //! user should derive a handler class from IConnectionListener, and provide an instance of that handler to any + //! INetworkInterface the user instantiates. The lifetime of the IConnectionListener must outlive the lifetime of the + //! INetworkInterface. class IConnectionListener { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionSet.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionSet.h index 5b53efd951..c86f78e8be 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionSet.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionSet.h @@ -18,6 +18,11 @@ namespace AzNetworking { //! @class IConnectionSet //! @brief interface class for managing a set of connections. + //! + //! IConnectionSet defines a simple interface for working with an abstract set of IConnections bound to an + //! INetworkInterface. Generally users of AzNetworking will not have reason to interact directly with the IConnectionSet, + //! as its interface is completely wrapped by INetworkInterface. + class IConnectionSet { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h b/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h index 47bc7adf4e..80f4aa153b 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h @@ -23,10 +23,10 @@ namespace AzNetworking //! Collection of compression related error codes enum class CompressorError { - Ok, ///< No error, operation finished successfully - InsufficientBuffer, ///< Buffer size is insufficient for the operation to complete, increase the size and try again - CorruptData, ///< Malformed or hacked packet, potentially security issue - Uninitialized ///< Compressor or supplied buffers are uninitialized + Ok, //!< No error, operation finished successfully + InsufficientBuffer, //!< Buffer size is insufficient for the operation to complete, increase the size and try again + CorruptData, //!< Malformed or hacked packet, potentially security issue + Uninitialized //!< Compressor or supplied buffers are uninitialized }; //! Unique identifier of a given compressor @@ -34,6 +34,12 @@ namespace AzNetworking //! @class ICompressor //! @brief Packet data compressor interface. + //! + //! ICompressor is an abstract compression interface meant for user provided GEMs to implement (such as the [Multiplayer + //! Compression Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression)). + //! Compression is currently supported on Udp and Tcp connections. Instantiation of a compressor is controlled by the + //! `net_UdpCompressor` or `net_TcpCompressor` cvar for their respective protocols. + class ICompressor { public: @@ -87,8 +93,16 @@ namespace AzNetworking ) = 0; }; - //! Abstract factory to instantiate compressors. - //! Used by the network interface to create a compressor + //! @class ICompressorFactory + //! @brief Abstract factory to instantiate compressors. + //! + //! ICompressorFactory is an abstract compression interface meant for user provided GEMs to implement. ICompressorFactory + //! implementations can be registered to classes implementing INetworking. Registered factories can then be used to create + //! ICompressor implementations on demand. The [Multiplayer Compression + //! Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression) is an example of an ICompressorFactory + //! for an LZ4 Compressor. In it, MultiplayerCompressionSystemComponent registers its ICompressorFactory with + //! NetworkingSystemComponent, which is an implementation of INetworking. Registered factories are keyed by their AZ Name + //! which is accessed through the factory's GetFactoryName method. class ICompressorFactory { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h index e674640053..b0f383c710 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h @@ -22,7 +22,16 @@ namespace AzNetworking { //! @class INetworkInterface - //! @brief pure virtual network interface class to abstract client/server and tcp/udp concerns from application code. + //! @brief Network interface class to abstract client/server and protocol concerns from application code. + //! + //! INetworkInterface provides an abstract API capable of receiving and opening IConnection objects, sending IPacket objects with optional + //! reliability, and determining the delivery status of packets that have been sent unreliably (delivery of reliable packets + //! is guaranteed as long as the associated connection remains open). INetworkInterface must be provided an + //! IConnectionListener instance that outlives the INetworkInterface itself. The INetworkInterface also creates and manages + //! the IConnectionSet, which tracks all open connections bound to the interface. INetworkInterface also provides GetMetrics + //! functions which can be used to fetch a struct detailing a variety of metrics relating to send and receive rates for both + //! packets and bytes in addition to the effect of features on those rates (such as packet size reduction due to compression.) + class INetworkInterface { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h index fb6d217b80..fea3b70c79 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h @@ -23,6 +23,17 @@ namespace AzNetworking //! @class INetworking //! @brief The interface for creating and working with network interfaces. + //! + //! INetworking is an Az::Interface that provides applications access to higher level networking abstractions. + //! AzNetworking::INetworking can be used to instantiate new INetworkInterfaces that can be configured to operate over + //! either TCP or UDP, enable or disable encryption, and be assigned a trust level. + //! + //! INetworking is also responsible for registering ICompressorFactory implementations. This allows a developer to have + //! access to multiple ICompressorFactory implementations by name. The [MultiplayerCompressor + //! Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression) is an example of this using the + //! [LZ4](https://wikipedia.org/wiki/LZ4_%28compression_algorithm%29) algorithm. + //! + class INetworking { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h index d62318ec36..81c79f9e3a 100644 --- a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h +++ b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h @@ -24,6 +24,15 @@ namespace AzNetworking //! @class IPacket //! @brief Base class for all packets. + //! + //! IPacket defines an abstract interface that all packets transmitted using AzNetworking must conform to. While there are + //! a number of core packets used internally by AzNetworking, it is fully possible for end-users to define their own custom + //! packets using this interface. PacketType should be distinct, and should be greater than + //! AzNetworking::CorePackets::MAX. The Serialize method allows the IPacket to be used by an + //! ISerializer to move data between hosts safely and efficiently. + //! + //! For more information on the packet format and best practices for extending the packet system, read + //! [Networking Packets](http://docs.o3de.org/docs/user-guide/networking/packets) on the O3DE documentation site. class IPacket { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h index 750b24befb..4669187906 100644 --- a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h +++ b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h @@ -28,6 +28,19 @@ namespace AzNetworking //! @class IPacketHeader //! @brief A packet header that lets us deduce packet type for any incoming packet. + //! + //! IPacketHeader defines an abstract interface for a descriptor of all AzNetworking::IPacket sent through AzNetworking. The + //! PacketHeader is used to identify and describe the contents of a Packet so that transport logic can identify what + //! additional processing steps need to be taken (if any) and what type of Packet is being inspected. + //! + //! The PacketFlags portion of the header represents the first byte of the header. While it can be encrypted it is + //! otherwise not exposed to additional processing (such as an AzNetworking::ICompressor). PacketFlags are a bitfield use to provide up + //! front information about the state of the packet. Currently there is only one flag to indicate if the Packet is + //! compressed or not. + //! + //! The remainder of the header contains the PacketType and the PacketId. While the PacketFlags byte is exempted from most + //! additional forms of processing, the remainder of the header is not. + class IPacketHeader { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/Serialization/ISerializer.h b/Code/Framework/AzNetworking/AzNetworking/Serialization/ISerializer.h index d083c7fc0e..999a229f65 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Serialization/ISerializer.h +++ b/Code/Framework/AzNetworking/AzNetworking/Serialization/ISerializer.h @@ -27,6 +27,18 @@ namespace AzNetworking //! @class ISerializer //! @brief Interface class for all serializers to derive from. + //! + //! ISerializer defines an abstract interface for visiting an object hierarchy and performing operations upon that hierarchy, + //! typically reading from or writing data to the object hierarchy for reasons of persistence or network transmission. + //! + //! While the most common types of serializers are provided by the AzNetworking framework, users can implement custom + //! serializers and perform complex operations on any serializable structures. A few types native to AzNetworking, many of which + //! relate to packets, demonstrate this. + //! + //! Provided serializers include NetworkInputSerializer for writing an object model into a bytestream, NetworkOutputSerializer + //! for writing to an object model, TrackChangesSerializer which is used to efficiently serialize objects without incurring significant + //! copy or comparison overhead, and HashSerializer which can be used to generate a hash of all visited data which is important for + //! automated desync detection. class ISerializer { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h index f2d65eeb63..ab9d743b63 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h @@ -25,6 +25,44 @@ namespace AzNetworking //! @class TcpNetworkInterface //! @brief This class implements a TCP network interface. + //! + //! TcpNetworkInterface is an implementation of AzNetworking::INetworkInterface. + //! Unlike UDP, TCP implements a variety of transport features such as congestion + //! avoidance, flow control, and reliability. These features are valuable, but TCP + //! offers minimal configuration of them. This is why UdpNetworkInterface offers + //! similar features, but with greater flexibility in configuration. If your project doesn't + //! require the low latency of UDP, consider using TCP. + //! + //! ## Packet structure + //! + //! * Flags - A bitfield a receiving endpoint can quickly inspect to learn about configuration of a packet + //! * Header - Details the type of packet and other information related to reliability + //! * Payload - The actual serialized content of the packet + //! + //! For more information, read [Networking Packets](http://docs.o3de.org/docs/user-guide/networking/packets) in the O3DE documentation. + //! + //! ## Reliability + //! + //! TCP packets can only be sent reliably. This is a feature of TCP itself. + //! + //! ## Fragmentation + //! + //! TCP implements fragmentation under the hood. Consumers of TCP packets will never + //! need to worry about reconstructing the contents over multiple transmissions. + //! + //! ## Compression + //! + //! Compression here refers to content insensitive compression using libraries like + //! LZ4. If enabled, the target payload is run through the compressor and replaces + //! the original payload if it's in fact smaller. To tell if compression is enabled + //! on a given packet, we operate on a bit in the packet's Flags. The Sender writes + //! this bit while the Receiver checks it to see if a packet needs to be + //! decompressed. + //! + //! ## Encryption + //! + //! AzNetworking uses the [OpenSSL](https://www.openssl.org/) library to implement TLS encryption. If enabled, + //! the O3DE network layer handles the OpenSSL handshake under the hood using provided certificates. class TcpNetworkInterface final : public INetworkInterface { diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h index dda15c421a..9d44212ea7 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h @@ -27,12 +27,58 @@ namespace AzNetworking class IConnectionListener; class ICompressor; - // 20 byte IPv4 header + 8 byte UDP header - static const uint32_t UdpPacketHeaderSize = 20 + 8; - static const uint32_t DtlsPacketHeaderSize = 13; // DTLS1_RT_HEADER_LENGTH + static const uint32_t UdpPacketHeaderSize = 20 + 8; //!< 20 byte IPv4 header + 8 byte UDP header + static const uint32_t DtlsPacketHeaderSize = 13; //!< DTLS1_RT_HEADER_LENGTH //! @class UdpNetworkInterface //! @brief This class implements a UDP network interface. + //! + //! UdpNetworkInterface is an implementation of AzNetworking::INetworkInterface. Since UDP is a very bare bones protocol, + //! the Open 3D Engine implementation has to provide significantly more than its TCP counterpart (since TCP implements a + //! significant number of reliability features.) + //! + //! When sent through UDP, a packet can have additional actions performed on it depending on which features are enabled and + //! configured. Each feature listed in this description is in the order a packet will see them on Send. + //! + //! ### Packet structure + //! + //! The general structure of a UDP packet is: + //! + //! * Flags - A bitfield a receiving endpoint can quickly inspect to learn about configuration of a packet + //! * Header - Details the type of packet and other information related to reliability + //! * Payload - The actual serialized content of the packet + //! + //! For more information, read [Networking Packets](http://docs.o3de.org/docs/user-guide/networking/packets) in the O3DE documentation. + //! + //! ### Reliability + //! + //! UDP packets can be sent reliably or unreliably. Reliably sent packets are registered for tracking first. This causes the + //! reliable packet to be resent if a timeout on the packet is reached. Once the packet is acknowledged, the packet is + //! unregistered. + //! + //! ### Fragmentation + //! + //! If the raw packet size exceeds the configured maximum transmission unit (MTU) then the packet is broken into + //! multiple reliable fragments to avoid fragmentation at the routing level. Fragments are always reliable so the original + //! packet can be reconstructed. Operations that alter the payload generally follow this step so that they can be + //! separately applied to the Fragments in addition to not being applied to both the original and Fragments. + //! + //! ### Compression + //! + //! Compression here refers to content insensitive compression using libraries like LZ4. If enabled, the target payload is + //! run through the compressor and replaces the original payload if it's in fact smaller. To tell if compression is enabled + //! on a given packet, we operate on a bit in the packet's Flags. The Sender writes this bit while the Receiver checks it to + //! see if a packet needs to be decompressed. + //! + //! O3DE could potentially move from over MTU to under with compression, and the UDP interface doesn't check for this. Detecting a change + //! that would reduce the number of fragmented packets would require pre-emptively compressing payloads to tell if that change happened, + //! which could potentially lead to a lot of unnecessary calls to the compressor. + //! + //! ### Encryption + //! + //! AzNetworking uses the [OpenSSL](https://www.openssl.org/) library to implement Datagram Layer Transport Security (DTLS) encryption + //! on UDP traffic. Encryption operates as described in [O3DE Networking Encryption](http://docs.o3de.org/docs/user-guide/networking/encryption) + //! on the documentation website. Once both endpoints have completed their handshake, all traffic is expected to be fully encrypted. class UdpNetworkInterface final : public INetworkInterface { diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 579ca195e5..50d52abf54 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -30,13 +30,13 @@ namespace Multiplayer //! Collection of types of Multiplayer Connections enum class MultiplayerAgentType { - Uninitialized, ///< Agent is uninitialized. - Client, ///< A Client connected to either a server or host. - ClientServer, ///< A Client that also hosts and is the authority of the session - DedicatedServer ///< A Dedicated Server which does not locally host any clients + Uninitialized, //!< Agent is uninitialized. + Client, //!< A Client connected to either a server or host. + ClientServer, //!< A Client that also hosts and is the authority of the session + DedicatedServer //!< A Dedicated Server which does not locally host any clients }; - //! Payload detailing aspects of a Connection other services may be interested in + //! @brief Payload detailing aspects of a Connection other services may be interested in struct MultiplayerAgentDatum { bool m_isInvited; @@ -49,7 +49,22 @@ namespace Multiplayer using SessionInitEvent = AZ::Event; using SessionShutdownEvent = AZ::Event; - //! IMultiplayer provides insight into the Multiplayer session and its Agents + //! @class IMultiplayer + //! @brief IMultiplayer provides insight into the Multiplayer session and its Agents + //! + //! IMultiplayer is an AZ::Interface that provides applications access to + //! multiplayer session information and events. IMultiplayer is implemented on the + //! MultiplayerSystemsComponent and is used to define and access information about + //! the type of session and the role held by the current agent. An Agent is defined + //! here as an actor in a session. Types of Agents included by default are a Client, + //! a Client Server and a Dedicated Server. + //! + //! IMultiplayer also provides events to allow developers to receive and respond to + //! notifications relating to the session. These include Session Init and Shutdown + //! and on acquisition of a new connection. These events are only fired on Client + //! Server or Dedicated Server. These events are useful for services that talk to + //! matchmaking services that may run in an entirely different layer which may need + //! insight to the gameplay session. class IMultiplayer { public: diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerTools.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerTools.h index c621808f7a..92c8cf3456 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerTools.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerTools.h @@ -16,7 +16,11 @@ namespace Multiplayer { - //! IMultiplayer provides insight into the Multiplayer session and its Agents + //! @class IMultiplayerTools + //! @brief IMultiplayerTools provides interfacing between the Editor and Multiplayer Gem. + //! + //! IMultiplayerTools is an AZ::Interface that provides information about + //! O3DE Editor and Tools integrations with the Multiplayer Gem. class IMultiplayerTools { public: @@ -27,8 +31,8 @@ namespace Multiplayer virtual ~IMultiplayerTools() = default; - //! Returns if network prefab processing has created currently active or pending spawnables - //! @return If network prefab processing has created currently active or pending spawnables + //! @brief Whether or not network prefab processing has created active or pending spawnable prefabs. + //! @return `true` if network prefab processing has created currently active or pending spawnables. virtual bool DidProcessNetworkPrefabs() = 0; private: From c7399537e2529a9ee7afe1889d31b1ed323d618c Mon Sep 17 00:00:00 2001 From: stramer <169061+sptramer@users.noreply.github.com> Date: Thu, 17 Jun 2021 14:15:56 -0700 Subject: [PATCH 2/3] Address review feedback. Signed-off-by: stramer <169061+sptramer@users.noreply.github.com> --- .../AzNetworking/AzNetworking/ConnectionLayer/IConnection.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h index 53505c556f..6b8c599bd8 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h @@ -45,8 +45,7 @@ namespace AzNetworking //! @class IConnection //! @brief interface class for network connections. //! - //! IConnection provides a pure-virtual interface for all network connection types. The two child classes are TcpConnection - //! and UdpConnection, though the pure-virtual interface operates largely the same for both. IConnections provide access to + //! IConnection provides a pure-virtual interface for all network connection types. IConnections provide access to //! a ConnectionMetrics object which provides a variety of metrics on the connection itself such as data rate, RTT and //! packet statistics. From 673495c49dbbecbd14eb62ad8419b70501db405d Mon Sep 17 00:00:00 2001 From: stramer <169061+sptramer@users.noreply.github.com> Date: Thu, 17 Jun 2021 18:01:44 -0700 Subject: [PATCH 3/3] Address additional review comments. Signed-off-by: stramer <169061+sptramer@users.noreply.github.com> --- .../Framework/AzNetworking/AzNetworking/Framework/ICompressor.h | 2 +- .../AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h | 2 +- Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h b/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h index 80f4aa153b..abd38a392b 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h @@ -37,7 +37,7 @@ namespace AzNetworking //! //! ICompressor is an abstract compression interface meant for user provided GEMs to implement (such as the [Multiplayer //! Compression Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression)). - //! Compression is currently supported on Udp and Tcp connections. Instantiation of a compressor is controlled by the + //! Compression is supported for both TCP and UDP connections. Instantiation of a compressor is controlled by the //! `net_UdpCompressor` or `net_TcpCompressor` cvar for their respective protocols. class ICompressor diff --git a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h index 4669187906..f51a959415 100644 --- a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h +++ b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h @@ -38,7 +38,7 @@ namespace AzNetworking //! front information about the state of the packet. Currently there is only one flag to indicate if the Packet is //! compressed or not. //! - //! The remainder of the header contains the PacketType and the PacketId. While the PacketFlags byte is exempted from most + //! The remainder of the header contains the PacketType and the PacketId. While the PacketFlags byte is exempt from most //! additional forms of processing, the remainder of the header is not. class IPacketHeader diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 50d52abf54..308fbf2ccb 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -54,7 +54,7 @@ namespace Multiplayer //! //! IMultiplayer is an AZ::Interface that provides applications access to //! multiplayer session information and events. IMultiplayer is implemented on the - //! MultiplayerSystemsComponent and is used to define and access information about + //! MultiplayerSystemComponent and is used to define and access information about //! the type of session and the role held by the current agent. An Agent is defined //! here as an actor in a session. Types of Agents included by default are a Client, //! a Client Server and a Dedicated Server.