Răsfoiți Sursa

[Net] Add generate_unique_id to MultiplayerPeer.

Used by ENetMultiplayerPeer and WebSocketServer to generate network IDs,
and exposed to the user for p2p networks (e.g. WebRTCMultiplayerPeer)
and custom MultiplayerPeer implementations.
Fabio Alessandrelli 4 ani în urmă
părinte
comite
1e8bf86379

+ 24 - 0
core/io/multiplayer_peer.cpp

@@ -30,6 +30,29 @@
 
 #include "multiplayer_peer.h"
 
+#include "core/os/os.h"
+
+uint32_t MultiplayerPeer::generate_unique_id() const {
+	uint32_t hash = 0;
+
+	while (hash == 0 || hash == 1) {
+		hash = hash_djb2_one_32(
+				(uint32_t)OS::get_singleton()->get_ticks_usec());
+		hash = hash_djb2_one_32(
+				(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)((uint64_t)this), hash); // Rely on ASLR heap
+		hash = hash_djb2_one_32(
+				(uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack
+
+		hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion
+	}
+
+	return hash;
+}
+
 void MultiplayerPeer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_transfer_mode", "mode"), &MultiplayerPeer::set_transfer_mode);
 	ClassDB::bind_method(D_METHOD("get_transfer_mode"), &MultiplayerPeer::get_transfer_mode);
@@ -41,6 +64,7 @@ void MultiplayerPeer::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("get_connection_status"), &MultiplayerPeer::get_connection_status);
 	ClassDB::bind_method(D_METHOD("get_unique_id"), &MultiplayerPeer::get_unique_id);
+	ClassDB::bind_method(D_METHOD("generate_unique_id"), &MultiplayerPeer::generate_unique_id);
 
 	ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "enable"), &MultiplayerPeer::set_refuse_new_connections);
 	ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &MultiplayerPeer::is_refusing_new_connections);

+ 1 - 0
core/io/multiplayer_peer.h

@@ -72,6 +72,7 @@ public:
 	virtual bool is_refusing_new_connections() const = 0;
 
 	virtual ConnectionStatus get_connection_status() const = 0;
+	uint32_t generate_unique_id() const;
 
 	MultiplayerPeer() {}
 };

+ 7 - 0
doc/classes/MultiplayerPeer.xml

@@ -12,6 +12,13 @@
 		<link title="WebRTC Signaling Demo">https://godotengine.org/asset-library/asset/537</link>
 	</tutorials>
 	<methods>
+		<method name="generate_unique_id" qualifiers="const">
+			<return type="int">
+			</return>
+			<description>
+				Returns a randomly generated integer that can be used as a network unique ID.
+			</description>
+		</method>
 		<method name="get_connection_status" qualifiers="const">
 			<return type="int" enum="MultiplayerPeer.ConnectionStatus">
 			</return>

+ 1 - 22
modules/enet/enet_multiplayer_peer.cpp

@@ -179,7 +179,7 @@ Error ENetMultiplayerPeer::create_client(const String &p_address, int p_port, in
 #endif
 	address.port = p_port;
 
-	unique_id = _gen_unique_id();
+	unique_id = generate_unique_id();
 
 	// Initiate connection, allocating enough channels
 	ENetPeer *peer = enet_host_connect(host, &address, channel_count, unique_id);
@@ -608,27 +608,6 @@ MultiplayerPeer::ConnectionStatus ENetMultiplayerPeer::get_connection_status() c
 	return connection_status;
 }
 
-uint32_t ENetMultiplayerPeer::_gen_unique_id() const {
-	uint32_t hash = 0;
-
-	while (hash == 0 || hash == 1) {
-		hash = hash_djb2_one_32(
-				(uint32_t)OS::get_singleton()->get_ticks_usec());
-		hash = hash_djb2_one_32(
-				(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)((uint64_t)this), hash); // Rely on ASLR heap
-		hash = hash_djb2_one_32(
-				(uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack
-
-		hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion
-	}
-
-	return hash;
-}
-
 int ENetMultiplayerPeer::get_unique_id() const {
 	ERR_FAIL_COND_V_MSG(!active, 0, "The multiplayer instance isn't currently active.");
 	return unique_id;

+ 0 - 1
modules/enet/enet_multiplayer_peer.h

@@ -96,7 +96,6 @@ private:
 
 	Packet current_packet;
 
-	uint32_t _gen_unique_id() const;
 	void _pop_current_packet();
 
 	Vector<uint8_t> src_compressor_mem;

+ 0 - 20
modules/websocket/websocket_multiplayer_peer.cpp

@@ -39,26 +39,6 @@ WebSocketMultiplayerPeer::~WebSocketMultiplayerPeer() {
 	_clear();
 }
 
-int WebSocketMultiplayerPeer::_gen_unique_id() const {
-	uint32_t hash = 0;
-
-	while (hash == 0 || hash == 1) {
-		hash = hash_djb2_one_32(
-				(uint32_t)OS::get_singleton()->get_ticks_usec());
-		hash = hash_djb2_one_32(
-				(uint32_t)OS::get_singleton()->get_unix_time(), hash);
-		hash = hash_djb2_one_32(
-				(uint32_t)OS::get_singleton()->get_data_path().hash64(), hash);
-		hash = hash_djb2_one_32(
-				(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
-		hash = hash & 0x7FFFFFFF; // make it compatible with unsigned, since negative id is used for exclusion
-	}
-
-	return hash;
-}
-
 void WebSocketMultiplayerPeer::_clear() {
 	_peer_map.clear();
 	if (_current_packet.data != nullptr) {

+ 0 - 1
modules/websocket/websocket_multiplayer_peer.h

@@ -75,7 +75,6 @@ protected:
 	void _send_add(int32_t p_peer_id);
 	void _send_sys(Ref<WebSocketPeer> p_peer, uint8_t p_type, int32_t p_peer_id);
 	void _send_del(int32_t p_peer_id);
-	int _gen_unique_id() const;
 
 public:
 	/* MultiplayerPeer */

+ 1 - 1
modules/websocket/wsl_server.cpp

@@ -207,7 +207,7 @@ void WSLServer::poll() {
 			continue;
 		}
 		// Creating new peer
-		int32_t id = _gen_unique_id();
+		int32_t id = generate_unique_id();
 
 		WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData);
 		data->obj = this;