1 /*************************************************************************/
2 /*  networked_multiplayer_enet.cpp                                       */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #include "networked_multiplayer_enet.h"
32 #include "core/io/ip.h"
33 #include "core/io/marshalls.h"
34 #include "core/os/os.h"
35 
set_transfer_mode(TransferMode p_mode)36 void NetworkedMultiplayerENet::set_transfer_mode(TransferMode p_mode) {
37 
38 	transfer_mode = p_mode;
39 }
get_transfer_mode() const40 NetworkedMultiplayerPeer::TransferMode NetworkedMultiplayerENet::get_transfer_mode() const {
41 
42 	return transfer_mode;
43 }
44 
set_target_peer(int p_peer)45 void NetworkedMultiplayerENet::set_target_peer(int p_peer) {
46 
47 	target_peer = p_peer;
48 }
49 
get_packet_peer() const50 int NetworkedMultiplayerENet::get_packet_peer() const {
51 
52 	ERR_FAIL_COND_V_MSG(!active, 1, "The multiplayer instance isn't currently active.");
53 	ERR_FAIL_COND_V(incoming_packets.size() == 0, 1);
54 
55 	return incoming_packets.front()->get().from;
56 }
57 
get_packet_channel() const58 int NetworkedMultiplayerENet::get_packet_channel() const {
59 
60 	ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
61 	ERR_FAIL_COND_V(incoming_packets.size() == 0, -1);
62 
63 	return incoming_packets.front()->get().channel;
64 }
65 
get_last_packet_channel() const66 int NetworkedMultiplayerENet::get_last_packet_channel() const {
67 
68 	ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
69 	ERR_FAIL_COND_V(!current_packet.packet, -1);
70 
71 	return current_packet.channel;
72 }
73 
create_server(int p_port,int p_max_clients,int p_in_bandwidth,int p_out_bandwidth)74 Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) {
75 
76 	ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
77 	ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The port number must be set between 0 and 65535 (inclusive).");
78 	ERR_FAIL_COND_V_MSG(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER, "The number of clients must be set between 1 and 4095 (inclusive).");
79 	ERR_FAIL_COND_V_MSG(p_in_bandwidth < 0, ERR_INVALID_PARAMETER, "The incoming bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
80 	ERR_FAIL_COND_V_MSG(p_out_bandwidth < 0, ERR_INVALID_PARAMETER, "The outgoing bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
81 	ERR_FAIL_COND_V(dtls_enabled && (dtls_key.is_null() || dtls_cert.is_null()), ERR_INVALID_PARAMETER);
82 
83 	ENetAddress address;
84 	memset(&address, 0, sizeof(address));
85 
86 #ifdef GODOT_ENET
87 	if (bind_ip.is_wildcard()) {
88 		address.wildcard = 1;
89 	} else {
90 		enet_address_set_ip(&address, bind_ip.get_ipv6(), 16);
91 	}
92 #else
93 	if (bind_ip.is_wildcard()) {
94 		address.host = 0;
95 	} else {
96 		ERR_FAIL_COND_V(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER);
97 		address.host = *(uint32_t *)bind_ip.get_ipv4();
98 	}
99 #endif
100 	address.port = p_port;
101 
102 	host = enet_host_create(&address /* the address to bind the server host to */,
103 			p_max_clients /* allow up to 32 clients and/or outgoing connections */,
104 			channel_count /* allow up to channel_count to be used */,
105 			p_in_bandwidth /* limit incoming bandwidth if > 0 */,
106 			p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
107 
108 	ERR_FAIL_COND_V_MSG(!host, ERR_CANT_CREATE, "Couldn't create an ENet multiplayer server.");
109 #ifdef GODOT_ENET
110 	if (dtls_enabled) {
111 		enet_host_dtls_server_setup(host, dtls_key.ptr(), dtls_cert.ptr());
112 	}
113 	enet_host_refuse_new_connections(host, refuse_connections);
114 #endif
115 
116 	_setup_compressor();
117 	active = true;
118 	server = true;
119 	refuse_connections = false;
120 	unique_id = 1;
121 	connection_status = CONNECTION_CONNECTED;
122 	return OK;
123 }
create_client(const String & p_address,int p_port,int p_in_bandwidth,int p_out_bandwidth,int p_client_port)124 Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_port, int p_in_bandwidth, int p_out_bandwidth, int p_client_port) {
125 
126 	ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
127 	ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The server port number must be set between 0 and 65535 (inclusive).");
128 	ERR_FAIL_COND_V_MSG(p_client_port < 0 || p_client_port > 65535, ERR_INVALID_PARAMETER, "The client port number must be set between 0 and 65535 (inclusive).");
129 	ERR_FAIL_COND_V_MSG(p_in_bandwidth < 0, ERR_INVALID_PARAMETER, "The incoming bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
130 	ERR_FAIL_COND_V_MSG(p_out_bandwidth < 0, ERR_INVALID_PARAMETER, "The outgoing bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
131 
132 	if (p_client_port != 0) {
133 		ENetAddress c_client;
134 
135 #ifdef GODOT_ENET
136 		if (bind_ip.is_wildcard()) {
137 			c_client.wildcard = 1;
138 		} else {
139 			enet_address_set_ip(&c_client, bind_ip.get_ipv6(), 16);
140 		}
141 #else
142 		if (bind_ip.is_wildcard()) {
143 			c_client.host = 0;
144 		} else {
145 			ERR_FAIL_COND_V_MSG(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER, "Wildcard IP addresses are only permitted in IPv4, not IPv6.");
146 			c_client.host = *(uint32_t *)bind_ip.get_ipv4();
147 		}
148 #endif
149 
150 		c_client.port = p_client_port;
151 
152 		host = enet_host_create(&c_client /* create a client host */,
153 				1 /* only allow 1 outgoing connection */,
154 				channel_count /* allow up to channel_count to be used */,
155 				p_in_bandwidth /* limit incoming bandwidth if > 0 */,
156 				p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
157 	} else {
158 		host = enet_host_create(NULL /* create a client host */,
159 				1 /* only allow 1 outgoing connection */,
160 				channel_count /* allow up to channel_count to be used */,
161 				p_in_bandwidth /* limit incoming bandwidth if > 0 */,
162 				p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
163 	}
164 
165 	ERR_FAIL_COND_V_MSG(!host, ERR_CANT_CREATE, "Couldn't create the ENet client host.");
166 #ifdef GODOT_ENET
167 	if (dtls_enabled) {
168 		enet_host_dtls_client_setup(host, dtls_cert.ptr(), dtls_verify, p_address.utf8().get_data());
169 	}
170 	enet_host_refuse_new_connections(host, refuse_connections);
171 #endif
172 
173 	_setup_compressor();
174 
175 	IP_Address ip;
176 	if (p_address.is_valid_ip_address()) {
177 		ip = p_address;
178 	} else {
179 #ifdef GODOT_ENET
180 		ip = IP::get_singleton()->resolve_hostname(p_address);
181 #else
182 		ip = IP::get_singleton()->resolve_hostname(p_address, IP::TYPE_IPV4);
183 #endif
184 
185 		ERR_FAIL_COND_V_MSG(!ip.is_valid(), ERR_CANT_RESOLVE, "Couldn't resolve the server IP address or domain name.");
186 	}
187 
188 	ENetAddress address;
189 #ifdef GODOT_ENET
190 	enet_address_set_ip(&address, ip.get_ipv6(), 16);
191 #else
192 	ERR_FAIL_COND_V_MSG(!ip.is_ipv4(), ERR_INVALID_PARAMETER, "Connecting to an IPv6 server isn't supported when using vanilla ENet. Recompile Godot with the bundled ENet library.");
193 	address.host = *(uint32_t *)ip.get_ipv4();
194 #endif
195 	address.port = p_port;
196 
197 	unique_id = _gen_unique_id();
198 
199 	// Initiate connection, allocating enough channels
200 	ENetPeer *peer = enet_host_connect(host, &address, channel_count, unique_id);
201 
202 	if (peer == NULL) {
203 		enet_host_destroy(host);
204 		ERR_FAIL_COND_V_MSG(!peer, ERR_CANT_CREATE, "Couldn't connect to the ENet multiplayer server.");
205 	}
206 
207 	// Technically safe to ignore the peer or anything else.
208 
209 	connection_status = CONNECTION_CONNECTING;
210 	active = true;
211 	server = false;
212 	refuse_connections = false;
213 
214 	return OK;
215 }
216 
poll()217 void NetworkedMultiplayerENet::poll() {
218 
219 	ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
220 
221 	_pop_current_packet();
222 
223 	ENetEvent event;
224 	/* Keep servicing until there are no available events left in queue. */
225 	while (true) {
226 
227 		if (!host || !active) // Might have been disconnected while emitting a notification
228 			return;
229 
230 		int ret = enet_host_service(host, &event, 0);
231 
232 		if (ret < 0) {
233 			// Error, do something?
234 			break;
235 		} else if (ret == 0) {
236 			break;
237 		}
238 
239 		switch (event.type) {
240 			case ENET_EVENT_TYPE_CONNECT: {
241 				// Store any relevant client information here.
242 
243 				if (server && refuse_connections) {
244 					enet_peer_reset(event.peer);
245 					break;
246 				}
247 
248 				// A client joined with an invalid ID (negative values, 0, and 1 are reserved).
249 				// Probably trying to exploit us.
250 				if (server && ((int)event.data < 2 || peer_map.has((int)event.data))) {
251 					enet_peer_reset(event.peer);
252 					ERR_CONTINUE(true);
253 				}
254 
255 				int *new_id = memnew(int);
256 				*new_id = event.data;
257 
258 				if (*new_id == 0) { // Data zero is sent by server (enet won't let you configure this). Server is always 1.
259 					*new_id = 1;
260 				}
261 
262 				event.peer->data = new_id;
263 
264 				peer_map[*new_id] = event.peer;
265 
266 				connection_status = CONNECTION_CONNECTED; // If connecting, this means it connected to something!
267 
268 				emit_signal("peer_connected", *new_id);
269 
270 				if (server) {
271 					// Do not notify other peers when server_relay is disabled.
272 					if (!server_relay)
273 						break;
274 
275 					// Someone connected, notify all the peers available
276 					for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
277 
278 						if (E->key() == *new_id)
279 							continue;
280 						// Send existing peers to new peer
281 						ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
282 						encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);
283 						encode_uint32(E->key(), &packet->data[4]);
284 						enet_peer_send(event.peer, SYSCH_CONFIG, packet);
285 						// Send the new peer to existing peers
286 						packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
287 						encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);
288 						encode_uint32(*new_id, &packet->data[4]);
289 						enet_peer_send(E->get(), SYSCH_CONFIG, packet);
290 					}
291 				} else {
292 
293 					emit_signal("connection_succeeded");
294 				}
295 
296 			} break;
297 			case ENET_EVENT_TYPE_DISCONNECT: {
298 
299 				// Reset the peer's client information.
300 
301 				int *id = (int *)event.peer->data;
302 
303 				if (!id) {
304 					if (!server) {
305 						emit_signal("connection_failed");
306 					}
307 					// Never fully connected.
308 					break;
309 				}
310 
311 				if (!server) {
312 
313 					// Client just disconnected from server.
314 					emit_signal("server_disconnected");
315 					close_connection();
316 					return;
317 				} else if (server_relay) {
318 
319 					// Server just received a client disconnect and is in relay mode, notify everyone else.
320 					for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
321 
322 						if (E->key() == *id)
323 							continue;
324 
325 						ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
326 						encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);
327 						encode_uint32(*id, &packet->data[4]);
328 						enet_peer_send(E->get(), SYSCH_CONFIG, packet);
329 					}
330 				}
331 
332 				emit_signal("peer_disconnected", *id);
333 				peer_map.erase(*id);
334 				memdelete(id);
335 			} break;
336 			case ENET_EVENT_TYPE_RECEIVE: {
337 
338 				if (event.channelID == SYSCH_CONFIG) {
339 					// Some config message
340 					ERR_CONTINUE(event.packet->dataLength < 8);
341 
342 					// Only server can send config messages
343 					ERR_CONTINUE(server);
344 
345 					int msg = decode_uint32(&event.packet->data[0]);
346 					int id = decode_uint32(&event.packet->data[4]);
347 
348 					switch (msg) {
349 						case SYSMSG_ADD_PEER: {
350 
351 							peer_map[id] = NULL;
352 							emit_signal("peer_connected", id);
353 
354 						} break;
355 						case SYSMSG_REMOVE_PEER: {
356 
357 							peer_map.erase(id);
358 							emit_signal("peer_disconnected", id);
359 						} break;
360 					}
361 
362 					enet_packet_destroy(event.packet);
363 				} else if (event.channelID < channel_count) {
364 
365 					Packet packet;
366 					packet.packet = event.packet;
367 
368 					uint32_t *id = (uint32_t *)event.peer->data;
369 
370 					ERR_CONTINUE(event.packet->dataLength < 8);
371 
372 					uint32_t source = decode_uint32(&event.packet->data[0]);
373 					int target = decode_uint32(&event.packet->data[4]);
374 
375 					packet.from = source;
376 					packet.channel = event.channelID;
377 
378 					if (server) {
379 						// Someone is cheating and trying to fake the source!
380 						ERR_CONTINUE(source != *id);
381 
382 						packet.from = *id;
383 
384 						if (target == 1) {
385 							// To myself and only myself
386 							incoming_packets.push_back(packet);
387 						} else if (!server_relay) {
388 							// No other destination is allowed when server is not relaying
389 							continue;
390 						} else if (target == 0) {
391 							// Re-send to everyone but sender :|
392 
393 							incoming_packets.push_back(packet);
394 							// And make copies for sending
395 							for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
396 
397 								if (uint32_t(E->key()) == source) // Do not resend to self
398 									continue;
399 
400 								ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, packet.packet->flags);
401 
402 								enet_peer_send(E->get(), event.channelID, packet2);
403 							}
404 
405 						} else if (target < 0) {
406 							// To all but one
407 
408 							// And make copies for sending
409 							for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
410 
411 								if (uint32_t(E->key()) == source || E->key() == -target) // Do not resend to self, also do not send to excluded
412 									continue;
413 
414 								ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, packet.packet->flags);
415 
416 								enet_peer_send(E->get(), event.channelID, packet2);
417 							}
418 
419 							if (-target != 1) {
420 								// Server is not excluded
421 								incoming_packets.push_back(packet);
422 							} else {
423 								// Server is excluded, erase packet
424 								enet_packet_destroy(packet.packet);
425 							}
426 
427 						} else {
428 							// To someone else, specifically
429 							ERR_CONTINUE(!peer_map.has(target));
430 							enet_peer_send(peer_map[target], event.channelID, packet.packet);
431 						}
432 					} else {
433 
434 						incoming_packets.push_back(packet);
435 					}
436 
437 					// Destroy packet later
438 				} else {
439 					ERR_CONTINUE(true);
440 				}
441 
442 			} break;
443 			case ENET_EVENT_TYPE_NONE: {
444 				// Do nothing
445 			} break;
446 		}
447 	}
448 }
449 
is_server() const450 bool NetworkedMultiplayerENet::is_server() const {
451 	ERR_FAIL_COND_V_MSG(!active, false, "The multiplayer instance isn't currently active.");
452 
453 	return server;
454 }
455 
close_connection(uint32_t wait_usec)456 void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
457 
458 	ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
459 
460 	_pop_current_packet();
461 
462 	bool peers_disconnected = false;
463 	for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
464 		if (E->get()) {
465 			enet_peer_disconnect_now(E->get(), unique_id);
466 			int *id = (int *)(E->get()->data);
467 			memdelete(id);
468 			peers_disconnected = true;
469 		}
470 	}
471 
472 	if (peers_disconnected) {
473 		enet_host_flush(host);
474 
475 		if (wait_usec > 0) {
476 			OS::get_singleton()->delay_usec(wait_usec); // Wait for disconnection packets to send
477 		}
478 	}
479 
480 	enet_host_destroy(host);
481 	active = false;
482 	incoming_packets.clear();
483 	peer_map.clear();
484 	unique_id = 1; // Server is 1
485 	connection_status = CONNECTION_DISCONNECTED;
486 }
487 
disconnect_peer(int p_peer,bool now)488 void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
489 
490 	ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
491 	ERR_FAIL_COND_MSG(!is_server(), "Can't disconnect a peer when not acting as a server.");
492 	ERR_FAIL_COND_MSG(!peer_map.has(p_peer), vformat("Peer ID %d not found in the list of peers.", p_peer));
493 
494 	if (now) {
495 		int *id = (int *)peer_map[p_peer]->data;
496 		enet_peer_disconnect_now(peer_map[p_peer], 0);
497 
498 		// enet_peer_disconnect_now doesn't generate ENET_EVENT_TYPE_DISCONNECT,
499 		// notify everyone else, send disconnect signal & remove from peer_map like in poll()
500 		if (server_relay) {
501 			for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
502 
503 				if (E->key() == p_peer) {
504 					continue;
505 				}
506 
507 				ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
508 				encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);
509 				encode_uint32(p_peer, &packet->data[4]);
510 				enet_peer_send(E->get(), SYSCH_CONFIG, packet);
511 			}
512 		}
513 
514 		if (id)
515 			memdelete(id);
516 
517 		emit_signal("peer_disconnected", p_peer);
518 		peer_map.erase(p_peer);
519 	} else {
520 		enet_peer_disconnect_later(peer_map[p_peer], 0);
521 	}
522 }
523 
get_available_packet_count() const524 int NetworkedMultiplayerENet::get_available_packet_count() const {
525 
526 	return incoming_packets.size();
527 }
528 
get_packet(const uint8_t ** r_buffer,int & r_buffer_size)529 Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
530 
531 	ERR_FAIL_COND_V_MSG(incoming_packets.size() == 0, ERR_UNAVAILABLE, "No incoming packets available.");
532 
533 	_pop_current_packet();
534 
535 	current_packet = incoming_packets.front()->get();
536 	incoming_packets.pop_front();
537 
538 	*r_buffer = (const uint8_t *)(&current_packet.packet->data[8]);
539 	r_buffer_size = current_packet.packet->dataLength - 8;
540 
541 	return OK;
542 }
543 
put_packet(const uint8_t * p_buffer,int p_buffer_size)544 Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
545 
546 	ERR_FAIL_COND_V_MSG(!active, ERR_UNCONFIGURED, "The multiplayer instance isn't currently active.");
547 	ERR_FAIL_COND_V_MSG(connection_status != CONNECTION_CONNECTED, ERR_UNCONFIGURED, "The multiplayer instance isn't currently connected to any server or client.");
548 
549 	int packet_flags = 0;
550 	int channel = SYSCH_RELIABLE;
551 
552 	switch (transfer_mode) {
553 		case TRANSFER_MODE_UNRELIABLE: {
554 			if (always_ordered)
555 				packet_flags = 0;
556 			else
557 				packet_flags = ENET_PACKET_FLAG_UNSEQUENCED;
558 			channel = SYSCH_UNRELIABLE;
559 		} break;
560 		case TRANSFER_MODE_UNRELIABLE_ORDERED: {
561 			packet_flags = 0;
562 			channel = SYSCH_UNRELIABLE;
563 		} break;
564 		case TRANSFER_MODE_RELIABLE: {
565 			packet_flags = ENET_PACKET_FLAG_RELIABLE;
566 			channel = SYSCH_RELIABLE;
567 		} break;
568 	}
569 
570 	if (transfer_channel > SYSCH_CONFIG)
571 		channel = transfer_channel;
572 
573 	Map<int, ENetPeer *>::Element *E = NULL;
574 
575 	if (target_peer != 0) {
576 
577 		E = peer_map.find(ABS(target_peer));
578 		ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, vformat("Invalid target peer: %d", target_peer));
579 	}
580 
581 	ENetPacket *packet = enet_packet_create(NULL, p_buffer_size + 8, packet_flags);
582 	encode_uint32(unique_id, &packet->data[0]); // Source ID
583 	encode_uint32(target_peer, &packet->data[4]); // Dest ID
584 	copymem(&packet->data[8], p_buffer, p_buffer_size);
585 
586 	if (server) {
587 
588 		if (target_peer == 0) {
589 			enet_host_broadcast(host, channel, packet);
590 		} else if (target_peer < 0) {
591 			// Send to all but one
592 			// and make copies for sending
593 
594 			int exclude = -target_peer;
595 
596 			for (Map<int, ENetPeer *>::Element *F = peer_map.front(); F; F = F->next()) {
597 
598 				if (F->key() == exclude) // Exclude packet
599 					continue;
600 
601 				ENetPacket *packet2 = enet_packet_create(packet->data, packet->dataLength, packet_flags);
602 
603 				enet_peer_send(F->get(), channel, packet2);
604 			}
605 
606 			enet_packet_destroy(packet); // Original packet no longer needed
607 		} else {
608 			enet_peer_send(E->get(), channel, packet);
609 		}
610 	} else {
611 
612 		ERR_FAIL_COND_V(!peer_map.has(1), ERR_BUG);
613 		enet_peer_send(peer_map[1], channel, packet); // Send to server for broadcast
614 	}
615 
616 	enet_host_flush(host);
617 
618 	return OK;
619 }
620 
get_max_packet_size() const621 int NetworkedMultiplayerENet::get_max_packet_size() const {
622 
623 	return 1 << 24; // Anything is good
624 }
625 
_pop_current_packet()626 void NetworkedMultiplayerENet::_pop_current_packet() {
627 
628 	if (current_packet.packet) {
629 		enet_packet_destroy(current_packet.packet);
630 		current_packet.packet = NULL;
631 		current_packet.from = 0;
632 		current_packet.channel = -1;
633 	}
634 }
635 
get_connection_status() const636 NetworkedMultiplayerPeer::ConnectionStatus NetworkedMultiplayerENet::get_connection_status() const {
637 
638 	return connection_status;
639 }
640 
_gen_unique_id() const641 uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {
642 
643 	uint32_t hash = 0;
644 
645 	while (hash == 0 || hash == 1) {
646 
647 		hash = hash_djb2_one_32(
648 				(uint32_t)OS::get_singleton()->get_ticks_usec());
649 		hash = hash_djb2_one_32(
650 				(uint32_t)OS::get_singleton()->get_unix_time(), hash);
651 		hash = hash_djb2_one_32(
652 				(uint32_t)OS::get_singleton()->get_user_data_dir().hash64(), hash);
653 		hash = hash_djb2_one_32(
654 				(uint32_t)((uint64_t)this), hash); // Rely on ASLR heap
655 		hash = hash_djb2_one_32(
656 				(uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack
657 
658 		hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion
659 	}
660 
661 	return hash;
662 }
663 
get_unique_id() const664 int NetworkedMultiplayerENet::get_unique_id() const {
665 
666 	ERR_FAIL_COND_V_MSG(!active, 0, "The multiplayer instance isn't currently active.");
667 	return unique_id;
668 }
669 
set_refuse_new_connections(bool p_enable)670 void NetworkedMultiplayerENet::set_refuse_new_connections(bool p_enable) {
671 
672 	refuse_connections = p_enable;
673 #ifdef GODOT_ENET
674 	if (active) {
675 		enet_host_refuse_new_connections(host, p_enable);
676 	}
677 #endif
678 }
679 
is_refusing_new_connections() const680 bool NetworkedMultiplayerENet::is_refusing_new_connections() const {
681 
682 	return refuse_connections;
683 }
684 
set_compression_mode(CompressionMode p_mode)685 void NetworkedMultiplayerENet::set_compression_mode(CompressionMode p_mode) {
686 
687 	compression_mode = p_mode;
688 }
689 
get_compression_mode() const690 NetworkedMultiplayerENet::CompressionMode NetworkedMultiplayerENet::get_compression_mode() const {
691 
692 	return compression_mode;
693 }
694 
enet_compress(void * context,const ENetBuffer * inBuffers,size_t inBufferCount,size_t inLimit,enet_uint8 * outData,size_t outLimit)695 size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 *outData, size_t outLimit) {
696 
697 	NetworkedMultiplayerENet *enet = (NetworkedMultiplayerENet *)(context);
698 
699 	if (size_t(enet->src_compressor_mem.size()) < inLimit) {
700 		enet->src_compressor_mem.resize(inLimit);
701 	}
702 
703 	int total = inLimit;
704 	int ofs = 0;
705 	while (total) {
706 		for (size_t i = 0; i < inBufferCount; i++) {
707 			int to_copy = MIN(total, int(inBuffers[i].dataLength));
708 			copymem(&enet->src_compressor_mem.write[ofs], inBuffers[i].data, to_copy);
709 			ofs += to_copy;
710 			total -= to_copy;
711 		}
712 	}
713 
714 	Compression::Mode mode;
715 
716 	switch (enet->compression_mode) {
717 		case COMPRESS_FASTLZ: {
718 			mode = Compression::MODE_FASTLZ;
719 		} break;
720 		case COMPRESS_ZLIB: {
721 			mode = Compression::MODE_DEFLATE;
722 		} break;
723 		case COMPRESS_ZSTD: {
724 			mode = Compression::MODE_ZSTD;
725 		} break;
726 		default: {
727 			ERR_FAIL_V_MSG(0, vformat("Invalid ENet compression mode: %d", enet->compression_mode));
728 		}
729 	}
730 
731 	int req_size = Compression::get_max_compressed_buffer_size(ofs, mode);
732 	if (enet->dst_compressor_mem.size() < req_size) {
733 		enet->dst_compressor_mem.resize(req_size);
734 	}
735 	int ret = Compression::compress(enet->dst_compressor_mem.ptrw(), enet->src_compressor_mem.ptr(), ofs, mode);
736 
737 	if (ret < 0)
738 		return 0;
739 
740 	if (ret > int(outLimit))
741 		return 0; // Do not bother
742 
743 	copymem(outData, enet->dst_compressor_mem.ptr(), ret);
744 
745 	return ret;
746 }
747 
enet_decompress(void * context,const enet_uint8 * inData,size_t inLimit,enet_uint8 * outData,size_t outLimit)748 size_t NetworkedMultiplayerENet::enet_decompress(void *context, const enet_uint8 *inData, size_t inLimit, enet_uint8 *outData, size_t outLimit) {
749 
750 	NetworkedMultiplayerENet *enet = (NetworkedMultiplayerENet *)(context);
751 	int ret = -1;
752 	switch (enet->compression_mode) {
753 		case COMPRESS_FASTLZ: {
754 
755 			ret = Compression::decompress(outData, outLimit, inData, inLimit, Compression::MODE_FASTLZ);
756 		} break;
757 		case COMPRESS_ZLIB: {
758 
759 			ret = Compression::decompress(outData, outLimit, inData, inLimit, Compression::MODE_DEFLATE);
760 		} break;
761 		case COMPRESS_ZSTD: {
762 
763 			ret = Compression::decompress(outData, outLimit, inData, inLimit, Compression::MODE_ZSTD);
764 		} break;
765 		default: {
766 		}
767 	}
768 	if (ret < 0) {
769 		return 0;
770 	} else {
771 		return ret;
772 	}
773 }
774 
_setup_compressor()775 void NetworkedMultiplayerENet::_setup_compressor() {
776 
777 	switch (compression_mode) {
778 
779 		case COMPRESS_NONE: {
780 
781 			enet_host_compress(host, NULL);
782 		} break;
783 		case COMPRESS_RANGE_CODER: {
784 			enet_host_compress_with_range_coder(host);
785 		} break;
786 		case COMPRESS_FASTLZ:
787 		case COMPRESS_ZLIB:
788 		case COMPRESS_ZSTD: {
789 
790 			enet_host_compress(host, &enet_compressor);
791 		} break;
792 	}
793 }
794 
enet_compressor_destroy(void * context)795 void NetworkedMultiplayerENet::enet_compressor_destroy(void *context) {
796 
797 	// Nothing to do
798 }
799 
get_peer_address(int p_peer_id) const800 IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
801 
802 	ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), IP_Address(), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
803 	ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, IP_Address(), "Can't get the address of peers other than the server (ID -1) when acting as a client.");
804 	ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == NULL, IP_Address(), vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
805 
806 	IP_Address out;
807 #ifdef GODOT_ENET
808 	out.set_ipv6((uint8_t *)&(peer_map[p_peer_id]->address.host));
809 #else
810 	out.set_ipv4((uint8_t *)&(peer_map[p_peer_id]->address.host));
811 #endif
812 
813 	return out;
814 }
815 
get_peer_port(int p_peer_id) const816 int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
817 
818 	ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), 0, vformat("Peer ID %d not found in the list of peers.", p_peer_id));
819 	ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, 0, "Can't get the address of peers other than the server (ID -1) when acting as a client.");
820 	ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == NULL, 0, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
821 #ifdef GODOT_ENET
822 	return peer_map[p_peer_id]->address.port;
823 #else
824 	return peer_map[p_peer_id]->address.port;
825 #endif
826 }
827 
set_transfer_channel(int p_channel)828 void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
829 
830 	ERR_FAIL_COND_MSG(p_channel < -1 || p_channel >= channel_count, vformat("The transfer channel must be set between 0 and %d, inclusive (got %d).", channel_count - 1, p_channel));
831 	ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, vformat("The channel %d is reserved.", SYSCH_CONFIG));
832 	transfer_channel = p_channel;
833 }
834 
get_transfer_channel() const835 int NetworkedMultiplayerENet::get_transfer_channel() const {
836 	return transfer_channel;
837 }
838 
set_channel_count(int p_channel)839 void NetworkedMultiplayerENet::set_channel_count(int p_channel) {
840 
841 	ERR_FAIL_COND_MSG(active, "The channel count can't be set while the multiplayer instance is active.");
842 	ERR_FAIL_COND_MSG(p_channel < SYSCH_MAX, vformat("The channel count must be greater than or equal to %d to account for reserved channels (got %d).", SYSCH_MAX, p_channel));
843 	channel_count = p_channel;
844 }
845 
get_channel_count() const846 int NetworkedMultiplayerENet::get_channel_count() const {
847 	return channel_count;
848 }
849 
set_always_ordered(bool p_ordered)850 void NetworkedMultiplayerENet::set_always_ordered(bool p_ordered) {
851 	always_ordered = p_ordered;
852 }
853 
is_always_ordered() const854 bool NetworkedMultiplayerENet::is_always_ordered() const {
855 	return always_ordered;
856 }
857 
set_server_relay_enabled(bool p_enabled)858 void NetworkedMultiplayerENet::set_server_relay_enabled(bool p_enabled) {
859 	ERR_FAIL_COND_MSG(active, "Server relaying can't be toggled while the multiplayer instance is active.");
860 
861 	server_relay = p_enabled;
862 }
863 
is_server_relay_enabled() const864 bool NetworkedMultiplayerENet::is_server_relay_enabled() const {
865 	return server_relay;
866 }
867 
_bind_methods()868 void NetworkedMultiplayerENet::_bind_methods() {
869 
870 	ClassDB::bind_method(D_METHOD("create_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0));
871 	ClassDB::bind_method(D_METHOD("create_client", "address", "port", "in_bandwidth", "out_bandwidth", "client_port"), &NetworkedMultiplayerENet::create_client, DEFVAL(0), DEFVAL(0), DEFVAL(0));
872 	ClassDB::bind_method(D_METHOD("close_connection", "wait_usec"), &NetworkedMultiplayerENet::close_connection, DEFVAL(100));
873 	ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "now"), &NetworkedMultiplayerENet::disconnect_peer, DEFVAL(false));
874 	ClassDB::bind_method(D_METHOD("set_compression_mode", "mode"), &NetworkedMultiplayerENet::set_compression_mode);
875 	ClassDB::bind_method(D_METHOD("get_compression_mode"), &NetworkedMultiplayerENet::get_compression_mode);
876 	ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &NetworkedMultiplayerENet::set_bind_ip);
877 	ClassDB::bind_method(D_METHOD("set_dtls_enabled", "enabled"), &NetworkedMultiplayerENet::set_dtls_enabled);
878 	ClassDB::bind_method(D_METHOD("is_dtls_enabled"), &NetworkedMultiplayerENet::is_dtls_enabled);
879 	ClassDB::bind_method(D_METHOD("set_dtls_key", "key"), &NetworkedMultiplayerENet::set_dtls_key);
880 	ClassDB::bind_method(D_METHOD("set_dtls_certificate", "certificate"), &NetworkedMultiplayerENet::set_dtls_certificate);
881 	ClassDB::bind_method(D_METHOD("set_dtls_verify_enabled", "enabled"), &NetworkedMultiplayerENet::set_dtls_verify_enabled);
882 	ClassDB::bind_method(D_METHOD("is_dtls_verify_enabled"), &NetworkedMultiplayerENet::is_dtls_verify_enabled);
883 	ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &NetworkedMultiplayerENet::get_peer_address);
884 	ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &NetworkedMultiplayerENet::get_peer_port);
885 
886 	ClassDB::bind_method(D_METHOD("get_packet_channel"), &NetworkedMultiplayerENet::get_packet_channel);
887 	ClassDB::bind_method(D_METHOD("get_last_packet_channel"), &NetworkedMultiplayerENet::get_last_packet_channel);
888 	ClassDB::bind_method(D_METHOD("set_transfer_channel", "channel"), &NetworkedMultiplayerENet::set_transfer_channel);
889 	ClassDB::bind_method(D_METHOD("get_transfer_channel"), &NetworkedMultiplayerENet::get_transfer_channel);
890 	ClassDB::bind_method(D_METHOD("set_channel_count", "channels"), &NetworkedMultiplayerENet::set_channel_count);
891 	ClassDB::bind_method(D_METHOD("get_channel_count"), &NetworkedMultiplayerENet::get_channel_count);
892 	ClassDB::bind_method(D_METHOD("set_always_ordered", "ordered"), &NetworkedMultiplayerENet::set_always_ordered);
893 	ClassDB::bind_method(D_METHOD("is_always_ordered"), &NetworkedMultiplayerENet::is_always_ordered);
894 	ClassDB::bind_method(D_METHOD("set_server_relay_enabled", "enabled"), &NetworkedMultiplayerENet::set_server_relay_enabled);
895 	ClassDB::bind_method(D_METHOD("is_server_relay_enabled"), &NetworkedMultiplayerENet::is_server_relay_enabled);
896 
897 	ADD_PROPERTY(PropertyInfo(Variant::INT, "compression_mode", PROPERTY_HINT_ENUM, "None,Range Coder,FastLZ,ZLib,ZStd"), "set_compression_mode", "get_compression_mode");
898 	ADD_PROPERTY(PropertyInfo(Variant::INT, "transfer_channel"), "set_transfer_channel", "get_transfer_channel");
899 	ADD_PROPERTY(PropertyInfo(Variant::INT, "channel_count"), "set_channel_count", "get_channel_count");
900 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "always_ordered"), "set_always_ordered", "is_always_ordered");
901 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "server_relay"), "set_server_relay_enabled", "is_server_relay_enabled");
902 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dtls_verify"), "set_dtls_verify_enabled", "is_dtls_verify_enabled");
903 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_dtls"), "set_dtls_enabled", "is_dtls_enabled");
904 
905 	BIND_ENUM_CONSTANT(COMPRESS_NONE);
906 	BIND_ENUM_CONSTANT(COMPRESS_RANGE_CODER);
907 	BIND_ENUM_CONSTANT(COMPRESS_FASTLZ);
908 	BIND_ENUM_CONSTANT(COMPRESS_ZLIB);
909 	BIND_ENUM_CONSTANT(COMPRESS_ZSTD);
910 }
911 
NetworkedMultiplayerENet()912 NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
913 
914 	active = false;
915 	server = false;
916 	refuse_connections = false;
917 	server_relay = true;
918 	unique_id = 0;
919 	target_peer = 0;
920 	current_packet.packet = NULL;
921 	transfer_mode = TRANSFER_MODE_RELIABLE;
922 	channel_count = SYSCH_MAX;
923 	transfer_channel = -1;
924 	always_ordered = false;
925 	connection_status = CONNECTION_DISCONNECTED;
926 	compression_mode = COMPRESS_NONE;
927 	enet_compressor.context = this;
928 	enet_compressor.compress = enet_compress;
929 	enet_compressor.decompress = enet_decompress;
930 	enet_compressor.destroy = enet_compressor_destroy;
931 
932 	bind_ip = IP_Address("*");
933 
934 	dtls_enabled = false;
935 	dtls_verify = true;
936 }
937 
~NetworkedMultiplayerENet()938 NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
939 
940 	if (active) {
941 		close_connection();
942 	}
943 }
944 
945 // Sets IP for ENet to bind when using create_server or create_client
946 // if no IP is set, then ENet bind to ENET_HOST_ANY
set_bind_ip(const IP_Address & p_ip)947 void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) {
948 	ERR_FAIL_COND_MSG(!p_ip.is_valid() && !p_ip.is_wildcard(), vformat("Invalid bind IP address: %s", String(p_ip)));
949 
950 	bind_ip = p_ip;
951 }
952 
set_dtls_enabled(bool p_enabled)953 void NetworkedMultiplayerENet::set_dtls_enabled(bool p_enabled) {
954 	ERR_FAIL_COND(active);
955 	dtls_enabled = p_enabled;
956 }
957 
is_dtls_enabled() const958 bool NetworkedMultiplayerENet::is_dtls_enabled() const {
959 	return dtls_enabled;
960 }
961 
set_dtls_verify_enabled(bool p_enabled)962 void NetworkedMultiplayerENet::set_dtls_verify_enabled(bool p_enabled) {
963 	ERR_FAIL_COND(active);
964 	dtls_verify = p_enabled;
965 }
966 
is_dtls_verify_enabled() const967 bool NetworkedMultiplayerENet::is_dtls_verify_enabled() const {
968 	return dtls_verify;
969 }
970 
set_dtls_key(Ref<CryptoKey> p_key)971 void NetworkedMultiplayerENet::set_dtls_key(Ref<CryptoKey> p_key) {
972 	ERR_FAIL_COND(active);
973 	dtls_key = p_key;
974 }
975 
set_dtls_certificate(Ref<X509Certificate> p_cert)976 void NetworkedMultiplayerENet::set_dtls_certificate(Ref<X509Certificate> p_cert) {
977 	ERR_FAIL_COND(active);
978 	dtls_cert = p_cert;
979 }
980