diff --git a/README.md b/README.md index 2e24a8e..9ecb46f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

+

alt logo

@@ -277,6 +277,11 @@ Provides per packet events. `PacketFreeCallback(Packet packet)` notifies when a packet is being destroyed. A reference to the delegate should be preserved from being garbage collected. +#### Host callbacks +Provides per host events. + +`InterceptCallback(ref Event @event, IntPtr receivedData, int receivedDataLength)` notifies when a raw UDP packet is intercepted. Status code returned from this callback instructs ENet how the set event should be handled. Returning 1 indicates dispatching of the set event by the service. Returning 0 indicates that ENet subsystems should handle received data. Returning -1 indicates an error. + ### Structures #### Address Contains structure with anonymous host data and port number. @@ -285,7 +290,7 @@ Contains structure with anonymous host data and port number. `Address.GetIP()` gets an IP address. -`Address.SetIP(string ip)` sets an IP address. To use IPv4 broadcast in the local network the address can be set to _255.255.255.255_ for a client. ENet will automatically respond to the broadcast and update the address to a server's actual IP. +`Address.SetIP(string ip)` sets an IP address. To use IPv4 broadcast in the local network the address can be set to _255.255.255.255_ for a client. ENet will automatically respond to the broadcast and update the address to a server's actual IP. `Address.GetHost()` attempts to do a reverse lookup from the address. Returns a string with a resolved name or an IP address. @@ -319,7 +324,7 @@ Contains a managed pointer to the packet. `Packet.HasReferences` checks references to the packet. -`Packet.SetFreeCallback(PacketFreeCallback callback)` set callback to notify the programmer when an appropriate packet is being destroyed. A pointer `IntPtr` to a callback can be used instead of a reference to a delegate. +`Packet.SetFreeCallback(PacketFreeCallback callback)` sets callback to notify when an appropriate packet is being destroyed. A pointer `IntPtr` to a callback can be used instead of a reference to a delegate. `Packet.Create(byte[] data, int offset, int length, PacketFlags flags)` creates a packet that may be sent to a peer. The offset parameter indicates the starting point of data in an array, the length is the ending point of data in an array. All parameters are optional. Multiple packet flags can be specified at once. A pointer `IntPtr` to a native buffer can be used instead of a reference to a byte array. @@ -352,13 +357,13 @@ Contains a managed pointer to the peer and cached ID. `Peer.PacketsLost` returns a total number of packets that considered lost during the connection based on retransmission logic. -`Peer.PacketsThrottle` return a ratio of packets throttle depending on conditions of the connection to the peer. +`Peer.PacketsThrottle` returns a ratio of packets throttle depending on conditions of the connection to the peer. `Peer.BytesSent` returns a total number of bytes sent during the connection. `Peer.BytesReceived` returns a total number of bytes received during the connection. -`Peer.Data` set or get the user-supplied data. Should be used with an explicit cast to appropriate data type. +`Peer.Data` gets or sets the user-supplied data. Should be used with an explicit cast to appropriate data type. `Peer.ConfigureThrottle(uint interval, uint acceleration, uint deceleration, uint threshold)` configures throttle parameter for a peer. Unreliable packets are dropped by ENet in response to the varying conditions of the connection to the peer. The throttle represents a probability that an unreliable packet should not be dropped and thus sent by ENet to the peer. The lowest mean round-trip time from the sending of a reliable packet to the receipt of its acknowledgment is measured over an amount of time specified by the interval parameter in milliseconds. If a measured round-trip time happens to be significantly less than the mean round-trip time measured over the interval, then the throttle probability is increased to allow more traffic by an amount specified in the acceleration parameter, which is a ratio to the `Library.throttleScale` constant. If a measured round-trip time happens to be significantly greater than the mean round-trip time measured over the interval, then the throttle probability is decreased to limit traffic by an amount specified in the deceleration parameter, which is a ratio to the `Library.throttleScale` constant. When the throttle has a value of `Library.throttleScale`, no unreliable packets are dropped by ENet, and so 100% of all unreliable packets will be sent. When the throttle has a value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable packets will be sent. Intermediate values for the throttle represent intermediate probabilities between 0% and 100% of unreliable packets being sent. The bandwidth limits of the local and foreign hosts are taken into account to determine a sensible limit for the throttle probability above which it should not raise even in the best of conditions. To disable throttling the deceleration parameter should be set to zero. The threshold parameter can be used to reduce packet throttling relative to measured round-trip time in unstable network environments with high jitter and low average latency which is a common condition for Wi-Fi networks in crowded places. By default the threshold parameter set to `Library.throttleThreshold` in milliseconds. @@ -372,11 +377,11 @@ Contains a managed pointer to the peer and cached ID. `Peer.Timeout(uint timeoutLimit, uint timeoutMinimum, uint timeoutMaximum)` sets a timeout parameters for a peer. The timeout parameters control how and when a peer will timeout from a failure to acknowledge reliable traffic. Timeout values used in the semi-linear mechanism, where if a reliable packet is not acknowledged within an average round-trip time plus a variance tolerance until timeout reaches a set limit. If the timeout is thus at this limit and reliable packets have been sent but not acknowledged within a certain minimum time period, the peer will be disconnected. Alternatively, if reliable packets have been sent but not acknowledged for a certain maximum time period, the peer will be disconnected regardless of the current timeout limit value. -`Peer.Disconnect(uint data)` request a disconnection from a peer. +`Peer.Disconnect(uint data)` requests a disconnection from a peer. -`Peer.DisconnectNow(uint data)` force an immediate disconnection from a peer. +`Peer.DisconnectNow(uint data)` forces an immediate disconnection from a peer. -`Peer.DisconnectLater(uint data)` request a disconnection from a peer, but only after all queued outgoing packets are sent. +`Peer.DisconnectLater(uint data)` requests a disconnection from a peer, but only after all queued outgoing packets are sent. `Peer.Reset()` forcefully disconnects a peer. The foreign host represented by the peer is not notified of the disconnection and will timeout on its connection to the local host. @@ -412,11 +417,13 @@ Contains a managed pointer to the host. `Host.SetBandwidthLimit(uint incomingBandwidth, uint outgoingBandwidth)` adjusts the bandwidth limits of a host in bytes per second. -`Host.SetChannelLimit(int channelLimit)` limits the maximum allowed channels of future incoming connections. +`Host.SetChannelLimit(int channelLimit)` limits the maximum allowed channels of future incoming connections. `Host.SetMaxDuplicatePeers(ushort number)` limits the maximum allowed duplicate peers from the same host and prevents connection if exceeded. By default set to `Library.maxPeers`, can't be less than one. -`Host.Flush()` sends any queued packets on the specified host to its designated peers. +`Host.SetInterceptCallback(InterceptCallback callback)` sets callback to notify when a raw UDP packet is interecepted. A pointer `IntPtr` to a callback can be used instead of a reference to a delegate. + +`Host.Flush()` sends any queued packets on the specified host to its designated peers. #### Library Contains constant fields. diff --git a/Source/Managed/ENet.cs b/Source/Managed/ENet.cs index a835838..7f72a8b 100644 --- a/Source/Managed/ENet.cs +++ b/Source/Managed/ENet.cs @@ -89,6 +89,7 @@ internal struct ENetCallbacks { public delegate void FreeCallback(IntPtr memory); public delegate void NoMemoryCallback(); public delegate void PacketFreeCallback(Packet packet); + public delegate int InterceptCallback(ref Event @event, IntPtr receivedData, int receivedDataLength); internal static class ArrayPool { [ThreadStatic] @@ -653,6 +654,18 @@ public void SetMaxDuplicatePeers(ushort number) { Native.enet_host_set_max_duplicate_peers(nativeHost, number); } + public void SetInterceptCallback(IntPtr callback) { + IsCreated(); + + Native.enet_host_set_intercept_callback(nativeHost, callback); + } + + public void SetInterceptCallback(InterceptCallback callback) { + IsCreated(); + + Native.enet_host_set_intercept_callback(nativeHost, Marshal.GetFunctionPointerForDelegate(callback)); + } + public void Flush() { IsCreated(); @@ -1063,6 +1076,9 @@ internal static class Native { [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] internal static extern void enet_host_set_max_duplicate_peers(IntPtr host, ushort number); + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] + internal static extern void enet_host_set_intercept_callback(IntPtr host, IntPtr callback); + [DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)] internal static extern void enet_host_flush(IntPtr host); diff --git a/Source/Native/enet.h b/Source/Native/enet.h index 38e2339..3a6c566 100644 --- a/Source/Native/enet.h +++ b/Source/Native/enet.h @@ -603,9 +603,25 @@ extern "C" { size_t totalWaitingData; } ENetPeer; + typedef enum _ENetEventType { + ENET_EVENT_TYPE_NONE = 0, + ENET_EVENT_TYPE_CONNECT = 1, + ENET_EVENT_TYPE_DISCONNECT = 2, + ENET_EVENT_TYPE_RECEIVE = 3, + ENET_EVENT_TYPE_DISCONNECT_TIMEOUT = 4 + } ENetEventType; + + typedef struct _ENetEvent { + ENetEventType type; + ENetPeer* peer; + uint8_t channelID; + uint32_t data; + ENetPacket* packet; + } ENetEvent; + typedef uint32_t (ENET_CALLBACK *ENetChecksumCallback)(const ENetBuffer* buffers, size_t bufferCount); - typedef int (ENET_CALLBACK *ENetInterceptCallback)(struct _ENetHost* host, void* event); + typedef int (ENET_CALLBACK *ENetInterceptCallback)(ENetEvent* event, uint8_t* receivedData, int receivedDataLength); typedef struct _ENetHost { ENetSocket socket; @@ -646,22 +662,6 @@ extern "C" { size_t maximumWaitingData; } ENetHost; - typedef enum _ENetEventType { - ENET_EVENT_TYPE_NONE = 0, - ENET_EVENT_TYPE_CONNECT = 1, - ENET_EVENT_TYPE_DISCONNECT = 2, - ENET_EVENT_TYPE_RECEIVE = 3, - ENET_EVENT_TYPE_DISCONNECT_TIMEOUT = 4 - } ENetEventType; - - typedef struct _ENetEvent { - ENetEventType type; - ENetPeer* peer; - uint8_t channelID; - uint32_t data; - ENetPacket* packet; - } ENetEvent; - /* ======================================================================= @@ -731,7 +731,7 @@ extern "C" { ENET_API void* enet_packet_get_user_data(const ENetPacket*); ENET_API void enet_packet_set_user_data(ENetPacket*, void* userData); ENET_API int enet_packet_get_length(const ENetPacket*); - ENET_API void enet_packet_set_free_callback(ENetPacket*, const void*); + ENET_API void enet_packet_set_free_callback(ENetPacket*, ENetPacketFreeCallback); ENET_API int enet_packet_check_references(const ENetPacket*); ENET_API void enet_packet_dispose(ENetPacket*); @@ -741,6 +741,7 @@ extern "C" { ENET_API uint32_t enet_host_get_bytes_sent(const ENetHost*); ENET_API uint32_t enet_host_get_bytes_received(const ENetHost*); ENET_API void enet_host_set_max_duplicate_peers(ENetHost*, uint16_t); + ENET_API void enet_host_set_intercept_callback(ENetHost* host, ENetInterceptCallback callback); ENET_API uint32_t enet_peer_get_id(const ENetPeer*); ENET_API int enet_peer_get_ip(const ENetPeer*, char*, size_t); @@ -2460,7 +2461,7 @@ extern "C" { host->totalReceivedPackets++; if (host->interceptCallback != NULL) { - switch (host->interceptCallback(host, (void*)event)) { + switch (host->interceptCallback(event, host->receivedData, host->receivedDataLength)) { case 1: if (event != NULL && event->type != ENET_EVENT_TYPE_NONE) return 1; @@ -4866,8 +4867,8 @@ extern "C" { return packet->dataLength; } - void enet_packet_set_free_callback(ENetPacket* packet, const void* callback) { - packet->freeCallback = (ENetPacketFreeCallback)callback; + void enet_packet_set_free_callback(ENetPacket* packet, ENetPacketFreeCallback callback) { + packet->freeCallback = callback; } int enet_packet_check_references(const ENetPacket* packet) { @@ -4909,6 +4910,10 @@ extern "C" { host->duplicatePeers = number; } + void enet_host_set_intercept_callback(ENetHost* host, ENetInterceptCallback callback) { + host->interceptCallback = callback; + } + uint32_t enet_peer_get_id(const ENetPeer* peer) { return peer->incomingPeerID; }