diff options
author | Max Hilbrunner <mhilbrunner@users.noreply.github.com> | 2018-05-12 23:50:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-12 23:50:26 +0200 |
commit | ca10cb6eea0f86e0ec2fe24a142006cbc6db21c6 (patch) | |
tree | 8d41045ad2cfc1578102a512eba8193e98003832 | |
parent | 81b1d3c846de263cf843e9e0e9d7c0c0a94f65c8 (diff) | |
parent | 0ad07a823cec6de4b1ca1563ec4292c5f8d20198 (diff) |
Merge pull request #18823 from Faless/multiplayer_raw
Allow sending raw bytes via the Multiplayer API
-rw-r--r-- | core/io/multiplayer_api.cpp | 39 | ||||
-rw-r--r-- | core/io/multiplayer_api.h | 3 | ||||
-rw-r--r-- | doc/classes/MultiplayerAPI.xml | 26 | ||||
-rw-r--r-- | doc/classes/NetworkedMultiplayerPeer.xml | 3 | ||||
-rw-r--r-- | doc/classes/Node.xml | 12 |
5 files changed, 72 insertions, 11 deletions
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 0ede7e87cb..456d29520f 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -76,7 +76,7 @@ Ref<NetworkedMultiplayerPeer> MultiplayerAPI::get_network_peer() const { void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) { ERR_FAIL_COND(root_node == NULL); - ERR_FAIL_COND(p_packet_len < 5); + ERR_FAIL_COND(p_packet_len < 1); uint8_t packet_type = p_packet[0]; @@ -123,6 +123,11 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_ } } break; + + case NETWORK_COMMAND_RAW: { + + _process_raw(p_from, p_packet, p_packet_len); + } break; } } @@ -259,6 +264,8 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) { + ERR_FAIL_COND(p_packet_len < 2); + String paths; paths.parse_utf8((const char *)&p_packet[1], p_packet_len - 1); @@ -648,6 +655,34 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const _send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1); } +Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to) { + + ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA); + ERR_FAIL_COND_V(!network_peer.is_valid(), ERR_UNCONFIGURED); + ERR_FAIL_COND_V(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED); + + MAKE_ROOM(p_data.size() + 1); + PoolVector<uint8_t>::Read r = p_data.read(); + packet_cache[0] = NETWORK_COMMAND_RAW; + memcpy(&packet_cache[1], &r[0], p_data.size()); + network_peer->set_target_peer(p_to); + return network_peer->put_packet(packet_cache.ptr(), p_data.size() + 1); +} + +void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) { + + ERR_FAIL_COND(p_packet_len < 2); + + PoolVector<uint8_t> out; + int len = p_packet_len - 1; + out.resize(len); + { + PoolVector<uint8_t>::Write w = out.write(); + memcpy(&w[0], &p_packet[1], len); + } + emit_signal("network_peer_packet", p_from, out); +} + int MultiplayerAPI::get_network_unique_id() const { ERR_FAIL_COND_V(!network_peer.is_valid(), 0); @@ -686,6 +721,7 @@ Vector<int> MultiplayerAPI::get_network_connected_peers() const { void MultiplayerAPI::_bind_methods() { ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node); + ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST)); ClassDB::bind_method(D_METHOD("has_network_peer"), &MultiplayerAPI::has_network_peer); ClassDB::bind_method(D_METHOD("get_network_peer"), &MultiplayerAPI::get_network_peer); ClassDB::bind_method(D_METHOD("get_network_unique_id"), &MultiplayerAPI::get_network_unique_id); @@ -708,6 +744,7 @@ void MultiplayerAPI::_bind_methods() { ADD_SIGNAL(MethodInfo("network_peer_connected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("network_peer_disconnected", PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("network_peer_packet", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::POOL_BYTE_ARRAY, "packet"))); ADD_SIGNAL(MethodInfo("connected_to_server")); ADD_SIGNAL(MethodInfo("connection_failed")); ADD_SIGNAL(MethodInfo("server_disconnected")); diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h index cc60890ced..25f445004d 100644 --- a/core/io/multiplayer_api.h +++ b/core/io/multiplayer_api.h @@ -43,6 +43,7 @@ protected: Node *_process_get_node(int p_from, const uint8_t *p_packet, int p_packet_len); void _process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); void _process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); + void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len); void _send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount); bool _send_confirm_path(NodePath p_path, PathSentCache *psc, int p_from); @@ -53,6 +54,7 @@ public: NETWORK_COMMAND_REMOTE_SET, NETWORK_COMMAND_SIMPLIFY_PATH, NETWORK_COMMAND_CONFIRM_PATH, + NETWORK_COMMAND_RAW, }; void poll(); @@ -60,6 +62,7 @@ public: void set_root_node(Node *p_node); void set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer); Ref<NetworkedMultiplayerPeer> get_network_peer() const; + Error send_bytes(PoolVector<uint8_t> p_data, int p_to = NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST); // Called by Node.rpc void rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount); diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml index b2ed712554..f6950d0fbc 100644 --- a/doc/classes/MultiplayerAPI.xml +++ b/doc/classes/MultiplayerAPI.xml @@ -61,10 +61,21 @@ </return> <description> Method used for polling the MultiplayerAPI. - You only need to worry about this if you are using [memeber Node.custom_multplayer] override. + You only need to worry about this if you are using [member Node.custom_multplayer] override. SceneTree will poll the default MultiplayerAPI for you. </description> </method> + <method name="send_bytes"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="bytes" type="PoolByteArray"> + </argument> + <argument index="1" name="id" type="int" default="0"> + </argument> + <description> + Sends the given raw [code]bytes[/code] to a specific peer identified by [code]id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer]). Default ID is [code]0[/code], i.e. broadcast to all peers. + </description> + </method> <method name="set_root_node"> <return type="void"> </return> @@ -78,7 +89,7 @@ </methods> <members> <member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer"> - The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server()]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to slave. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals. + The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to slave. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals. </member> <member name="refuse_new_network_connections" type="bool" setter="set_refuse_new_network_connections" getter="is_refusing_new_network_connections"> If [code]true[/code] the MultiplayerAPI's [member network_peer] refuses new incoming connections. @@ -109,9 +120,18 @@ Emitted whenever this MultiplayerAPI's [member network_peer] disconnects from a peer. Clients get notified when other clients disconnect from the same server. </description> </signal> + <signal name="network_peer_packet"> + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="packet" type="PoolByteArray"> + </argument> + <description> + Emitted whenever this MultiplayerAPI's [member network_peer] receive a [code]packet[/code] with custom data (see [method send_bytes]). ID is the peer ID of the peer that sent the packet. + </description> + </signal> <signal name="server_disconnected"> <description> - Emitted whenever this MultiplayerAPI's [member network_peer] disconnected from server. Only emitted on clients. + Emitted whenever this MultiplayerAPI's [member network_peer] disconnects from server. Only emitted on clients. </description> </signal> </signals> diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/NetworkedMultiplayerPeer.xml index 71614c5f76..2780334384 100644 --- a/doc/classes/NetworkedMultiplayerPeer.xml +++ b/doc/classes/NetworkedMultiplayerPeer.xml @@ -46,7 +46,8 @@ <argument index="0" name="id" type="int"> </argument> <description> - The peer to which packets will be sent. Default value: [code]0[/code]. + Sets the peer to which packets will be sent. + The [code]id[/code] can be one of: [code]TARGET_PEER_BROADCAST[/code] to send to all connected peers, [code]TARGET_PEER_SERVER[/code] to send to the peer acting as server, a valid peer ID to send to that specific peer, a negative peer ID to send to all peers except that one. Default: [code]TARGET_PEER_BROADCAST[/code] </description> </method> </methods> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index c11b8aacaa..05ac6b1c0e 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -586,7 +586,7 @@ <argument index="1" name="method" type="String"> </argument> <description> - Sends a [method rpc] to a specific peer identified by [code]peer_id[/code]. Returns an empty [Variant]. + Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer]). Returns an empty [Variant]. </description> </method> <method name="rpc_unreliable" qualifiers="vararg"> @@ -606,7 +606,7 @@ <argument index="1" name="method" type="String"> </argument> <description> - Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] using an unreliable protocol. Returns an empty [Variant]. + Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] using an unreliable protocol (see [method NetworkedMultiplayerPeer.set_target_peer]). Returns an empty [Variant]. </description> </method> <method name="rset"> @@ -641,7 +641,7 @@ <argument index="2" name="value" type="Variant"> </argument> <description> - Remotely changes the property's value on a specific peer identified by [code]peer_id[/code]. + Remotely changes the property's value on a specific peer identified by [code]peer_id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer]). </description> </method> <method name="rset_unreliable"> @@ -665,7 +665,7 @@ <argument index="2" name="value" type="Variant"> </argument> <description> - Remotely changes property's value on a specific peer identified by [code]peer_id[/code] using an unreliable protocol. + Remotely changes property's value on a specific peer identified by [code]peer_id[/code] using an unreliable protocol (see [method NetworkedMultiplayerPeer.set_target_peer]). </description> </method> <method name="set_display_folded"> @@ -703,7 +703,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> - Enables or disables internal physics for this node. Internal physics processing happens in isolation from the normal [method]_physics_process[/code] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or physics processing is disabled for scripting ([method set_physics_process]). Only useful for advanced uses to manipulate built-in nodes behaviour. + Enables or disables internal physics for this node. Internal physics processing happens in isolation from the normal [method _physics_process] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or physics processing is disabled for scripting ([method set_physics_process]). Only useful for advanced uses to manipulate built-in nodes behaviour. </description> </method> <method name="set_process"> @@ -730,7 +730,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> - Enables or disabled internal processing for this node. Internal processing happens in isolation from the normal [method]_process[/code] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or processing is disabled for scripting ([method set_process]). Only useful for advanced uses to manipulate built-in nodes behaviour. + Enables or disabled internal processing for this node. Internal processing happens in isolation from the normal [method _process] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or processing is disabled for scripting ([method set_process]). Only useful for advanced uses to manipulate built-in nodes behaviour. </description> </method> <method name="set_process_unhandled_input"> |