diff options
| -rw-r--r-- | modules/enet/networked_multiplayer_enet.cpp | 116 | ||||
| -rw-r--r-- | modules/enet/networked_multiplayer_enet.h | 2 | 
2 files changed, 72 insertions, 46 deletions
| diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index f3f4acd768..0f62714440 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -115,9 +115,6 @@ Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port  #endif  	address.port = p_port; -	//enet_address_set_host (& address, "localhost"); -	//address.port = p_port; -  	unique_id = _gen_unique_id();  	/* Initiate the connection, allocating the enough channels */ @@ -128,7 +125,7 @@ Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port  		ERR_FAIL_COND_V(!peer, ERR_CANT_CREATE);  	} -	//technically safe to ignore the peer or anything else. +	// Technically safe to ignore the peer or anything else.  	connection_status = CONNECTION_CONNECTING;  	active = true; @@ -148,13 +145,13 @@ void NetworkedMultiplayerENet::poll() {  	/* Wait up to 1000 milliseconds for an event. */  	while (true) { -		if (!host || !active) //might have been disconnected while emitting a notification +		if (!host || !active) // Might have been disconnected while emitting a notification  			return;  		int ret = enet_host_service(host, &event, 1);  		if (ret < 0) { -			//error, do something? +			// Error, do something?  			break;  		} else if (ret == 0) {  			break; @@ -172,7 +169,7 @@ void NetworkedMultiplayerENet::poll() {  				int *new_id = memnew(int);  				*new_id = event.data; -				if (*new_id == 0) { //data zero is sent by server (enet won't let you configure this). Server is always 1 +				if (*new_id == 0) { // Data zero is sent by server (enet won't let you configure this). Server is always 1  					*new_id = 1;  				} @@ -180,22 +177,22 @@ void NetworkedMultiplayerENet::poll() {  				peer_map[*new_id] = event.peer; -				connection_status = CONNECTION_CONNECTED; //if connecting, this means it connected t something! +				connection_status = CONNECTION_CONNECTED; // If connecting, this means it connected to something!  				emit_signal("peer_connected", *new_id);  				if (server) { -					//someone connected, let it know of all the peers available +					// Someone connected, notify all the peers available  					for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {  						if (E->key() == *new_id)  							continue; -						//send existing peers to new peer +						// Send existing peers to new peer  						ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);  						encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);  						encode_uint32(E->key(), &packet->data[4]);  						enet_peer_send(event.peer, SYSCH_CONFIG, packet); -						//send the new peer to existing peers +						// Send the new peer to existing peers  						packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);  						encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);  						encode_uint32(*new_id, &packet->data[4]); @@ -220,12 +217,12 @@ void NetworkedMultiplayerENet::poll() {  				} else {  					if (server) { -						//someone disconnected, let it know to everyone else +						// Someone disconnected, notify everyone else  						for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {  							if (E->key() == *id)  								continue; -							//send the new peer to existing peers +  							ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);  							encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);  							encode_uint32(*id, &packet->data[4]); @@ -246,7 +243,7 @@ void NetworkedMultiplayerENet::poll() {  			case ENET_EVENT_TYPE_RECEIVE: {  				if (event.channelID == SYSCH_CONFIG) { -					//some config message +					// Some config message  					ERR_CONTINUE(event.packet->dataLength < 8);  					// Only server can send config messages @@ -292,13 +289,13 @@ void NetworkedMultiplayerENet::poll() {  						packet.from = *id;  						if (target == 0) { -							//re-send the everyone but sender :| +							// Re-send to everyone but sender :|  							incoming_packets.push_back(packet); -							//and make copies for sending +							// And make copies for sending  							for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { -								if (uint32_t(E->key()) == source) //do not resend to self +								if (uint32_t(E->key()) == source) // Do not resend to self  									continue;  								ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, flags); @@ -307,12 +304,12 @@ void NetworkedMultiplayerENet::poll() {  							}  						} else if (target < 0) { -							//to all but one +							// To all but one -							//and make copies for sending +							// And make copies for sending  							for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { -								if (uint32_t(E->key()) == source || E->key() == -target) //do not resend to self, also do not send to excluded +								if (uint32_t(E->key()) == source || E->key() == -target) // Do not resend to self, also do not send to excluded  									continue;  								ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, flags); @@ -321,18 +318,18 @@ void NetworkedMultiplayerENet::poll() {  							}  							if (-target != 1) { -								//server is not excluded +								// Server is not excluded  								incoming_packets.push_back(packet);  							} else { -								//server is excluded, erase packet +								// Server is excluded, erase packet  								enet_packet_destroy(packet.packet);  							}  						} else if (target == 1) { -							//to myself and only myself +							// To myself and only myself  							incoming_packets.push_back(packet);  						} else { -							//to someone else, specifically +							// To someone else, specifically  							ERR_CONTINUE(!peer_map.has(target));  							enet_peer_send(peer_map[target], event.channelID, packet.packet);  						} @@ -341,14 +338,14 @@ void NetworkedMultiplayerENet::poll() {  						incoming_packets.push_back(packet);  					} -					//destroy packet later.. +					// Destroy packet later..  				} else {  					ERR_CONTINUE(true);  				}  			} break;  			case ENET_EVENT_TYPE_NONE: { -				//do nothing +				// Do nothing  			} break;  		}  	} @@ -377,16 +374,46 @@ void NetworkedMultiplayerENet::close_connection() {  	if (peers_disconnected) {  		enet_host_flush(host); -		OS::get_singleton()->delay_usec(100); //wait 100ms for disconnection packets to send +		OS::get_singleton()->delay_usec(100); // Wait 100ms for disconnection packets to send  	}  	enet_host_destroy(host);  	active = false;  	incoming_packets.clear(); -	unique_id = 1; //server is 1 +	unique_id = 1; // Server is 1  	connection_status = CONNECTION_DISCONNECTED;  } +void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) { + +	ERR_FAIL_COND(!active); +	ERR_FAIL_COND(!is_server()); +	ERR_FAIL_COND(!peer_map.has(p_peer)) + +	if (now) { +		enet_peer_disconnect_now(peer_map[p_peer], 0); + +		// enet_peer_disconnect_now doesn't generate ENET_EVENT_TYPE_DISCONNECT, +		// notify everyone else, send disconnect signal & remove from peer_map like in poll() + +		for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { + +			if (E->key() == p_peer) +				continue; + +			ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE); +			encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]); +			encode_uint32(p_peer, &packet->data[4]); +			enet_peer_send(E->get(), SYSCH_CONFIG, packet); +		} + +		emit_signal("peer_disconnected", p_peer); +		peer_map.erase(p_peer); +	} else { +		enet_peer_disconnect_later(peer_map[p_peer], 0); +	} +} +  int NetworkedMultiplayerENet::get_available_packet_count() const {  	return incoming_packets.size(); @@ -440,9 +467,9 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer  	}  	ENetPacket *packet = enet_packet_create(NULL, p_buffer_size + 12, packet_flags); -	encode_uint32(unique_id, &packet->data[0]); //source ID -	encode_uint32(target_peer, &packet->data[4]); //dest ID -	encode_uint32(packet_flags, &packet->data[8]); //dest ID +	encode_uint32(unique_id, &packet->data[0]); // Source ID +	encode_uint32(target_peer, &packet->data[4]); // Dest ID +	encode_uint32(packet_flags, &packet->data[8]); // Dest ID  	copymem(&packet->data[12], p_buffer, p_buffer_size);  	if (server) { @@ -450,14 +477,14 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer  		if (target_peer == 0) {  			enet_host_broadcast(host, channel, packet);  		} else if (target_peer < 0) { -			//send to all but one -			//and make copies for sending +			// Send to all but one +			// and make copies for sending  			int exclude = -target_peer;  			for (Map<int, ENetPeer *>::Element *F = peer_map.front(); F; F = F->next()) { -				if (F->key() == exclude) // exclude packet +				if (F->key() == exclude) // Exclude packet  					continue;  				ENetPacket *packet2 = enet_packet_create(packet->data, packet->dataLength, packet_flags); @@ -465,14 +492,14 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer  				enet_peer_send(F->get(), channel, packet2);  			} -			enet_packet_destroy(packet); //original packet no longer needed +			enet_packet_destroy(packet); // Original packet no longer needed  		} else {  			enet_peer_send(E->get(), channel, packet);  		}  	} else {  		ERR_FAIL_COND_V(!peer_map.has(1), ERR_BUG); -		enet_peer_send(peer_map[1], channel, packet); //send to server for broadcast.. +		enet_peer_send(peer_map[1], channel, packet); // Send to server for broadcast..  	}  	enet_host_flush(host); @@ -482,7 +509,7 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer  int NetworkedMultiplayerENet::get_max_packet_size() const { -	return 1 << 24; //anything is good +	return 1 << 24; // Anything is good  }  void NetworkedMultiplayerENet::_pop_current_packet() { @@ -511,16 +538,12 @@ uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {  				(uint32_t)OS::get_singleton()->get_unix_time(), hash);  		hash = hash_djb2_one_32(  				(uint32_t)OS::get_singleton()->get_user_data_dir().hash64(), hash); -		/* -		hash = hash_djb2_one_32( -					(uint32_t)OS::get_singleton()->get_unique_id().hash64(), hash ); -		*/  		hash = hash_djb2_one_32( -				(uint32_t)((uint64_t)this), hash); //rely on aslr heap +				(uint32_t)((uint64_t)this), hash); // Rely on ASLR heap  		hash = hash_djb2_one_32( -				(uint32_t)((uint64_t)&hash), hash); //rely on aslr stack +				(uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack -		hash = hash & 0x7FFFFFFF; // make it compatible with unsigned, since negatie id is used for exclusion +		hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion  	}  	return hash; @@ -596,7 +619,7 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *  		return 0;  	if (ret > int(outLimit)) -		return 0; //do not bother +		return 0; // Do not bother  	copymem(outData, enet->dst_compressor_mem.ptr(), ret); @@ -659,6 +682,7 @@ void NetworkedMultiplayerENet::_bind_methods() {  	ClassDB::bind_method(D_METHOD("create_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0));  	ClassDB::bind_method(D_METHOD("create_client", "ip", "port", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_client, DEFVAL(0), DEFVAL(0));  	ClassDB::bind_method(D_METHOD("close_connection"), &NetworkedMultiplayerENet::close_connection); +	ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "now"), &NetworkedMultiplayerENet::disconnect_peer, DEFVAL(false));  	ClassDB::bind_method(D_METHOD("set_compression_mode", "mode"), &NetworkedMultiplayerENet::set_compression_mode);  	ClassDB::bind_method(D_METHOD("get_compression_mode"), &NetworkedMultiplayerENet::get_compression_mode);  	ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &NetworkedMultiplayerENet::set_bind_ip); @@ -696,7 +720,7 @@ NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {  	close_connection();  } -// sets IP for ENet to bind when using create_server +// Sets IP for ENet to bind when using create_server  // if no IP is set, then ENet bind to ENET_HOST_ANY  void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) {  	ERR_FAIL_COND(!p_ip.is_valid() && !p_ip.is_wildcard()); diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h index 440e9b5400..f93f24fd49 100644 --- a/modules/enet/networked_multiplayer_enet.h +++ b/modules/enet/networked_multiplayer_enet.h @@ -120,6 +120,8 @@ public:  	void close_connection(); +	void disconnect_peer(int p_peer, bool now = false); +  	virtual void poll();  	virtual bool is_server() const; |