// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Types/BaseTypes.h" #include "Engine/Core/Types/String.h" API_INJECT_CODE(cpp, "#include \"Engine/Platform/Network.h\""); /// /// Network connection protocol type. /// API_ENUM() enum class NetworkProtocol { /// Not specified. Undefined, /// User Datagram Protocol. Udp, /// Transmission Control Protocol. Tcp, }; /// /// IP version type. /// API_ENUM() enum class NetworkIPVersion { /// Not specified. Undefined, /// Internet Protocol version 4. IPv4, /// Internet Protocol version 6. IPv6, }; /// /// Network socket. /// API_STRUCT() struct FLAXENGINE_API NetworkSocket { DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup); /// Socket protocol type. API_FIELD() NetworkProtocol Protocol = NetworkProtocol::Undefined; /// Socket address IP version. API_FIELD() NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; API_FIELD(Private, NoArray) byte Data[8] = {}; }; /// /// Network end-point. /// API_STRUCT() struct FLAXENGINE_API NetworkEndPoint { DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup); /// End-point IP version. API_FIELD(ReadOnly) NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; API_FIELD(Private, NoArray) byte Data[28] = {}; }; /// /// Network socket options. /// API_ENUM() enum class NetworkSocketOption { /// Enables debugging info recording. Debug, /// Allows local address reusing. ReuseAddr, /// Keeps connections alive. KeepAlive, /// Indicates that outgoing data should be sent on whatever interface the socket is bound to and not a routed on some other interface. DontRoute, /// Allows for sending broadcast data. Broadcast, /// Uses the local loopback address when sending data from this socket. UseLoopback, /// Lingers on close if data present. Linger, /// Allows out-of-bound data to be returned in-line with regular data. OOBInline, /// Socket send data buffer size. SendBuffer, /// Socket receive data buffer size. RecvBuffer, /// The timeout in milliseconds for blocking send calls. SendTimeout, /// The timeout in milliseconds for blocking receive calls. RecvTimeout, /// The last socket error code. Error, /// Enables the Nagle algorithm for TCP sockets. NoDelay, /// Enables IPv6/Ipv4 dual-stacking, UDP/TCP. IPv6Only, /// Retrieve the current path MTU, the socket must be connected UDP/TCP. Mtu, /// Socket type, DGRAM, STREAM .. Type, }; /// /// Network socket state. /// API_ENUM() enum class NetworkSocketState { /// Nothing. None = 0, /// Socket error. Error = 1 << 0, /// Invalid request. Invalid = 1 << 1, /// Socket disconnected. Disconnected = 1 << 2, /// Socket is readable. Readable = 1 << 3, /// Socket is writable. Writeable = 1 << 4, }; DECLARE_ENUM_OPERATORS(NetworkSocketState); /// /// Network sockets group. /// API_STRUCT() struct FLAXENGINE_API NetworkSocketGroup { DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup); /// Group size. API_FIELD(ReadOnly) uint32 Count = 0; /// Group capacity. API_FIELD(ReadOnly) uint32 Capacity = 0; API_FIELD(Private) byte* Data = nullptr; }; /// /// Low-level networking implementation interface with Berkeley sockets. /// API_CLASS(Static, Name="Network", Tag="NativeInvokeUseName") class FLAXENGINE_API NetworkBase { public: static struct FLAXENGINE_API ScriptingTypeInitializer TypeInitializer; /// /// Creates a new native socket. /// /// The socket struct to fill in. /// The protocol. /// The ip version. /// Returns true on error, otherwise false. API_FUNCTION() static bool CreateSocket(API_PARAM(Ref) NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv); /// /// Closes native socket. /// /// The socket. /// Returns true on error, otherwise false. API_FUNCTION() static bool DestroySocket(API_PARAM(Ref) NetworkSocket& socket); /// /// Sets the specified socket option. /// /// The socket. /// The option. /// The value. /// Returns true on error, otherwise false. API_FUNCTION() static bool SetSocketOption(API_PARAM(Ref) NetworkSocket& socket, NetworkSocketOption option, int32 value); /// /// Gets the specified socket option. /// /// The socket. /// The option. /// The returned value. /// Returns true on error, otherwise false. API_FUNCTION() static bool GetSocketOption(API_PARAM(Ref) NetworkSocket& socket, NetworkSocketOption option, API_PARAM(Out) int32& value); /// /// Connects a socket to the specified end point. /// /// The socket. /// The end point. /// Returns true on error, otherwise false. API_FUNCTION() static bool ConnectSocket(API_PARAM(Ref) NetworkSocket& socket, API_PARAM(Ref) NetworkEndPoint& endPoint); /// /// Binds a socket to the specified end point. /// /// The socket. /// The end point. /// Returns true on error, otherwise false. API_FUNCTION() static bool BindSocket(API_PARAM(Ref) NetworkSocket& socket, API_PARAM(Ref) NetworkEndPoint& endPoint); /// /// Listens for incoming connection. /// /// The socket. /// Pending connection queue size. /// Returns true on error, otherwise false. API_FUNCTION() static bool Listen(API_PARAM(Ref) NetworkSocket& socket, uint16 queueSize); /// /// Accepts a pending connection. /// /// The socket. /// The newly connected socket. /// The end point of the new socket. /// Returns true on error, otherwise false. API_FUNCTION() static bool Accept(API_PARAM(Ref) NetworkSocket& serverSocket, API_PARAM(Ref) NetworkSocket& newSocket, API_PARAM(Out) NetworkEndPoint& newEndPoint); /// /// Checks for socket readability. /// /// The socket. /// Returns true when data is available. Otherwise false. API_FUNCTION() static bool IsReadable(API_PARAM(Ref) NetworkSocket& socket); /// /// Checks for socket writeability. /// /// The socket. /// Returns true when data can be written. Otherwise false. API_FUNCTION() static bool IsWritable(API_PARAM(Ref) NetworkSocket& socket); /// /// Creates a socket group. It allocate memory based on the desired capacity. /// /// The group capacity (fixed). /// The group. /// Returns true on error, otherwise false. API_FUNCTION() static bool CreateSocketGroup(uint32 capacity, API_PARAM(Out) NetworkSocketGroup& group); /// /// Destroy the socket group, and free the allocated memory. /// /// The group. /// Returns true if the group is already destroyed, otherwise false. API_FUNCTION() static bool DestroySocketGroup(API_PARAM(Ref) NetworkSocketGroup& group); /// /// Updates sockets states. /// /// The sockets group. /// Returns -1 on error, The number of elements where states are nonzero, otherwise 0. API_FUNCTION() static int32 Poll(API_PARAM(Ref) NetworkSocketGroup& group); /// /// Retrieves socket state. /// /// The group. /// The socket index in group. /// The returned state. /// Returns true on error, otherwise false. API_FUNCTION() static bool GetSocketState(API_PARAM(Ref) NetworkSocketGroup& group, uint32 index, API_PARAM(Out) NetworkSocketState& state); /// /// Adds a socket to a group. /// /// The group. /// The socket. /// Returns the socket index in group or -1 on error. API_FUNCTION() static int32 AddSocketToGroup(API_PARAM(Ref) NetworkSocketGroup& group, API_PARAM(Ref) NetworkSocket& socket); /// /// Gets a socket by index. Some data like socket IPVersion might be undefined. /// /// The group. /// The index. /// The returned socket. /// Returns true on error, otherwise false. API_FUNCTION() static bool GetSocketFromGroup(API_PARAM(Ref) NetworkSocketGroup& group, uint32 index, API_PARAM(Out) NetworkSocket& socket); /// /// Removes the socket at the specified index. /// /// The group. /// The index. API_FUNCTION() static void RemoveSocketFromGroup(API_PARAM(Ref) NetworkSocketGroup& group, uint32 index); /// /// Removes the socket if present. /// /// The group. /// The socket. /// Returns true if the socket is not found, otherwise false. API_FUNCTION() static bool RemoveSocketFromGroup(API_PARAM(Ref) NetworkSocketGroup& group, API_PARAM(Ref) NetworkSocket& socket); /// /// Clears the socket group. /// /// The group. API_FUNCTION() static void ClearGroup(API_PARAM(Ref) NetworkSocketGroup& group); /// /// Writes data to the socket. /// /// The socket. /// The data to write. /// The length of data. /// If protocol is UDP, the destination end point. Otherwise nullptr. /// Returns -1 on error, otherwise bytes written. API_FUNCTION() static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); /// /// Reads data on the socket. /// /// The socket. /// The buffer. /// Size of the buffer. /// If UDP, the end point from where data is coming. Otherwise nullptr. /// Returns -1 on error, otherwise bytes read. API_FUNCTION() static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); /// /// Creates an end point. /// /// The network address. /// The network port. /// The ip version. /// The created end point. /// True if the end point will be connected or binded. /// Returns true on error, otherwise false. API_FUNCTION() static bool CreateEndPoint(const String& address, const String& port, NetworkIPVersion ipv, API_PARAM(Out) NetworkEndPoint& endPoint, bool bindable = true); /// /// Remaps an ipv4 end point to an ipv6 one. /// /// The ipv4 end point. /// The ipv6 end point. API_FUNCTION() static NetworkEndPoint RemapEndPointToIPv6(API_PARAM(Ref) NetworkEndPoint& endPoint); };