1 /** 2 PacketPeer implementation using the ENet library. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.networkedmultiplayerenet; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.meta; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.object; 22 import godot.classdb; 23 import godot.networkedmultiplayerpeer; 24 import godot.packetpeer; 25 import godot.reference; 26 /** 27 PacketPeer implementation using the ENet library. 28 29 A PacketPeer implementation that should be passed to $(D SceneTree.setNetworkPeer) after being initialized as either a client or server. Events can then be handled by connecting to $(D SceneTree) signals. 30 */ 31 @GodotBaseClass struct NetworkedMultiplayerENet 32 { 33 enum string _GODOT_internal_name = "NetworkedMultiplayerENet"; 34 public: 35 @nogc nothrow: 36 union { godot_object _godot_object; NetworkedMultiplayerPeer _GODOT_base; } 37 alias _GODOT_base this; 38 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 39 package(godot) __gshared bool _classBindingInitialized = false; 40 package(godot) static struct _classBinding 41 { 42 __gshared: 43 @GodotName("create_server") GodotMethod!(GodotError, long, long, long, long) createServer; 44 @GodotName("create_client") GodotMethod!(GodotError, String, long, long, long, long) createClient; 45 @GodotName("close_connection") GodotMethod!(void, long) closeConnection; 46 @GodotName("disconnect_peer") GodotMethod!(void, long, bool) disconnectPeer; 47 @GodotName("set_compression_mode") GodotMethod!(void, long) setCompressionMode; 48 @GodotName("get_compression_mode") GodotMethod!(NetworkedMultiplayerENet.CompressionMode) getCompressionMode; 49 @GodotName("set_bind_ip") GodotMethod!(void, String) setBindIp; 50 @GodotName("get_peer_address") GodotMethod!(String, long) getPeerAddress; 51 @GodotName("get_peer_port") GodotMethod!(long, long) getPeerPort; 52 @GodotName("get_packet_channel") GodotMethod!(long) getPacketChannel; 53 @GodotName("get_last_packet_channel") GodotMethod!(long) getLastPacketChannel; 54 @GodotName("set_transfer_channel") GodotMethod!(void, long) setTransferChannel; 55 @GodotName("get_transfer_channel") GodotMethod!(long) getTransferChannel; 56 @GodotName("set_channel_count") GodotMethod!(void, long) setChannelCount; 57 @GodotName("get_channel_count") GodotMethod!(long) getChannelCount; 58 @GodotName("set_always_ordered") GodotMethod!(void, bool) setAlwaysOrdered; 59 @GodotName("is_always_ordered") GodotMethod!(bool) isAlwaysOrdered; 60 } 61 bool opEquals(in NetworkedMultiplayerENet other) const { return _godot_object.ptr is other._godot_object.ptr; } 62 NetworkedMultiplayerENet opAssign(T : typeof(null))(T n) { _godot_object.ptr = null; } 63 bool opEquals(typeof(null) n) const { return _godot_object.ptr is null; } 64 mixin baseCasts; 65 static NetworkedMultiplayerENet _new() 66 { 67 static godot_class_constructor constructor; 68 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("NetworkedMultiplayerENet"); 69 if(constructor is null) return typeof(this).init; 70 return cast(NetworkedMultiplayerENet)(constructor()); 71 } 72 @disable new(size_t s); 73 /// 74 enum CompressionMode : int 75 { 76 /** 77 No compression. 78 */ 79 compressNone = 0, 80 /** 81 ENet's buildin range encoding. 82 */ 83 compressRangeCoder = 1, 84 /** 85 FastLZ compression. 86 */ 87 compressFastlz = 2, 88 /** 89 zlib compression. 90 */ 91 compressZlib = 3, 92 /** 93 ZStandard compression. 94 */ 95 compressZstd = 4, 96 } 97 /// 98 enum Constants : int 99 { 100 compressNone = 0, 101 compressRangeCoder = 1, 102 compressFastlz = 2, 103 compressZlib = 3, 104 compressZstd = 4, 105 } 106 /** 107 Create server that listens to connections via `port`. The port needs to be an available, unused port between 0 and 65535. Note that ports below 1024 are privileged and may require elevated permissions depending on the platform. To change the interface the server listens on, use $(D setBindIp). The default IP is the wildcard `*`, which listens on all available interfaces. `max_clients` is the maximum number of clients that are allowed at once, any number up to 4096 may be used, although the achievable number of simultaneous clients may be far lower and depends on the application. For additional details on the bandwidth parameters, see $(D createClient). Returns `OK` if a server was created, `ERR_ALREADY_IN_USE` if this NetworkedMultiplayerEnet instance already has an open connection (in which case you need to call $(D closeConnection) first) or `ERR_CANT_CREATE` if the server could not be created. 108 */ 109 GodotError createServer(in long port, in long max_clients = 32, in long in_bandwidth = 0, in long out_bandwidth = 0) 110 { 111 checkClassBinding!(typeof(this))(); 112 return ptrcall!(GodotError)(_classBinding.createServer, _godot_object, port, max_clients, in_bandwidth, out_bandwidth); 113 } 114 /** 115 Create client that connects to a server at `address` using specified `port`. The given address needs to be either a fully qualified domain nome (e.g. `www.example.com`) or an IP address in IPv4 or IPv6 format (e.g. `192.168.1.1`). The `port` is the port the server is listening on. The `in_bandwidth` and `out_bandwidth` parameters can be used to limit the incoming and outgoing bandwidth to the given number of bytes per second. The default of 0 means unlimited bandwidth. Note that ENet will strategically drop packets on specific sides of a connection between peers to ensure the peer's bandwidth is not overwhelmed. The bandwidth parameters also determine the window size of a connection which limits the amount of reliable packets that may be in transit at any given time. Returns `OK` if a client was created, `ERR_ALREADY_IN_USE` if this NetworkedMultiplayerEnet instance already has an open connection (in which case you need to call $(D closeConnection) first) or `ERR_CANT_CREATE` if the client could not be created. If `client_port` is specified, the client will also listen to the given port, this is useful in some NAT traversal technique. 116 */ 117 GodotError createClient(StringArg0)(in StringArg0 address, in long port, in long in_bandwidth = 0, in long out_bandwidth = 0, in long client_port = 0) 118 { 119 checkClassBinding!(typeof(this))(); 120 return ptrcall!(GodotError)(_classBinding.createClient, _godot_object, address, port, in_bandwidth, out_bandwidth, client_port); 121 } 122 /** 123 Closes the connection. Ignored if no connection is currently established. If this is a server it tries to notify all clients before forcibly disconnecting them. If this is a client it simply closes the connection to the server. 124 */ 125 void closeConnection(in long wait_usec = 100) 126 { 127 checkClassBinding!(typeof(this))(); 128 ptrcall!(void)(_classBinding.closeConnection, _godot_object, wait_usec); 129 } 130 /** 131 Disconnect the given peer. If "now" is set to true, the connection will be closed immediately without flushing queued messages. 132 */ 133 void disconnectPeer(in long id, in bool now = false) 134 { 135 checkClassBinding!(typeof(this))(); 136 ptrcall!(void)(_classBinding.disconnectPeer, _godot_object, id, now); 137 } 138 /** 139 140 */ 141 void setCompressionMode(in long mode) 142 { 143 checkClassBinding!(typeof(this))(); 144 ptrcall!(void)(_classBinding.setCompressionMode, _godot_object, mode); 145 } 146 /** 147 148 */ 149 NetworkedMultiplayerENet.CompressionMode getCompressionMode() const 150 { 151 checkClassBinding!(typeof(this))(); 152 return ptrcall!(NetworkedMultiplayerENet.CompressionMode)(_classBinding.getCompressionMode, _godot_object); 153 } 154 /** 155 The IP used when creating a server. This is set to the wildcard `*` by default, which binds to all available interfaces. The given IP needs to be in IPv4 or IPv6 address format, for example: `192.168.1.1`. 156 */ 157 void setBindIp(StringArg0)(in StringArg0 ip) 158 { 159 checkClassBinding!(typeof(this))(); 160 ptrcall!(void)(_classBinding.setBindIp, _godot_object, ip); 161 } 162 /** 163 Returns the IP address of the given peer. 164 */ 165 String getPeerAddress(in long id) const 166 { 167 checkClassBinding!(typeof(this))(); 168 return ptrcall!(String)(_classBinding.getPeerAddress, _godot_object, id); 169 } 170 /** 171 Returns the remote port of the given peer. 172 */ 173 long getPeerPort(in long id) const 174 { 175 checkClassBinding!(typeof(this))(); 176 return ptrcall!(long)(_classBinding.getPeerPort, _godot_object, id); 177 } 178 /** 179 Returns the channel of the next packet that will be retrieved via $(D PacketPeer.getPacket) 180 */ 181 long getPacketChannel() const 182 { 183 checkClassBinding!(typeof(this))(); 184 return ptrcall!(long)(_classBinding.getPacketChannel, _godot_object); 185 } 186 /** 187 Returns the channel of the last packet fetched via $(D PacketPeer.getPacket) 188 */ 189 long getLastPacketChannel() const 190 { 191 checkClassBinding!(typeof(this))(); 192 return ptrcall!(long)(_classBinding.getLastPacketChannel, _godot_object); 193 } 194 /** 195 196 */ 197 void setTransferChannel(in long channel) 198 { 199 checkClassBinding!(typeof(this))(); 200 ptrcall!(void)(_classBinding.setTransferChannel, _godot_object, channel); 201 } 202 /** 203 204 */ 205 long getTransferChannel() const 206 { 207 checkClassBinding!(typeof(this))(); 208 return ptrcall!(long)(_classBinding.getTransferChannel, _godot_object); 209 } 210 /** 211 212 */ 213 void setChannelCount(in long channels) 214 { 215 checkClassBinding!(typeof(this))(); 216 ptrcall!(void)(_classBinding.setChannelCount, _godot_object, channels); 217 } 218 /** 219 220 */ 221 long getChannelCount() const 222 { 223 checkClassBinding!(typeof(this))(); 224 return ptrcall!(long)(_classBinding.getChannelCount, _godot_object); 225 } 226 /** 227 228 */ 229 void setAlwaysOrdered(in bool ordered) 230 { 231 checkClassBinding!(typeof(this))(); 232 ptrcall!(void)(_classBinding.setAlwaysOrdered, _godot_object, ordered); 233 } 234 /** 235 236 */ 237 bool isAlwaysOrdered() const 238 { 239 checkClassBinding!(typeof(this))(); 240 return ptrcall!(bool)(_classBinding.isAlwaysOrdered, _godot_object); 241 } 242 /** 243 The compression method used for network packets. Default is no compression. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all. 244 */ 245 @property NetworkedMultiplayerENet.CompressionMode compressionMode() 246 { 247 return getCompressionMode(); 248 } 249 /// ditto 250 @property void compressionMode(long v) 251 { 252 setCompressionMode(v); 253 } 254 /** 255 Set the default channel to be used to transfer data. By default this value is `-1` which means that ENet will only use 2 channels, one for reliable and one for unreliable packets. Channel `0` is reserved, and cannot be used. Setting this member to any value between `0` and $(D channelCount) (excluded) will force ENet to use that channel for sending data. 256 */ 257 @property long transferChannel() 258 { 259 return getTransferChannel(); 260 } 261 /// ditto 262 @property void transferChannel(long v) 263 { 264 setTransferChannel(v); 265 } 266 /** 267 The number of channels to be used by ENet. Default: `3`. Channels are used to separate different kinds of data. In realiable or ordered mode, for example, the packet delivery order is ensured on a per channel basis. 268 */ 269 @property long channelCount() 270 { 271 return getChannelCount(); 272 } 273 /// ditto 274 @property void channelCount(long v) 275 { 276 setChannelCount(v); 277 } 278 /** 279 Always use `TRANSFER_MODE_ORDERED` in place of `TRANSFER_MODE_UNRELIABLE`. This is the only way to use ordering with the RPC system. 280 */ 281 @property bool alwaysOrdered() 282 { 283 return isAlwaysOrdered(); 284 } 285 /// ditto 286 @property void alwaysOrdered(bool v) 287 { 288 setAlwaysOrdered(v); 289 } 290 }