diff options
author | Fabio Alessandrelli <fabio.alessandrelli@gmail.com> | 2021-09-28 12:57:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-28 12:57:45 +0200 |
commit | d18cbdf5e4a1132bfc5f581195f6bf7c3b9bed79 (patch) | |
tree | e87200b01a5b55ec516b528be52f382954efe4e5 /core | |
parent | 97f050067819c7d1fbef0cb38b071ff31b2b2188 (diff) | |
parent | 2d810e8cd948f1e25e514986dc6f9a7cb7c52026 (diff) | |
download | redot-engine-d18cbdf5e4a1132bfc5f581195f6bf7c3b9bed79.tar.gz |
Merge pull request #52481 from Faless/net/4.x_native_peers
[Net] Extension system for network peers, webrtc.
Diffstat (limited to 'core')
-rw-r--r-- | core/io/packet_peer.cpp | 46 | ||||
-rw-r--r-- | core/io/packet_peer.h | 23 | ||||
-rw-r--r-- | core/io/stream_peer.cpp | 57 | ||||
-rw-r--r-- | core/io/stream_peer.h | 25 | ||||
-rw-r--r-- | core/multiplayer/multiplayer_peer.cpp | 181 | ||||
-rw-r--r-- | core/multiplayer/multiplayer_peer.h | 80 | ||||
-rw-r--r-- | core/register_core_types.cpp | 3 | ||||
-rw-r--r-- | core/variant/native_ptr.h | 1 |
8 files changed, 408 insertions, 8 deletions
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 8da44fd290..87d2b66e5b 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -138,6 +138,7 @@ Error PacketPeer::_get_packet_error() const { void PacketPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &PacketPeer::_bnd_get_var, DEFVAL(false)); ClassDB::bind_method(D_METHOD("put_var", "var", "full_objects"), &PacketPeer::put_var, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_packet"), &PacketPeer::_get_packet); ClassDB::bind_method(D_METHOD("put_packet", "buffer"), &PacketPeer::_put_packet); ClassDB::bind_method(D_METHOD("get_packet_error"), &PacketPeer::_get_packet_error); @@ -151,6 +152,51 @@ void PacketPeer::_bind_methods() { /***************/ +int PacketPeerExtension::get_available_packet_count() const { + int count; + if (GDVIRTUAL_CALL(_get_available_packet_count, count)) { + return count; + } + WARN_PRINT_ONCE("PacketPeerExtension::_get_available_packet_count is unimplemented!"); + return -1; +} + +Error PacketPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { + int err; + if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) { + return (Error)err; + } + WARN_PRINT_ONCE("PacketPeerExtension::_get_packet_native is unimplemented!"); + return FAILED; +} + +Error PacketPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + int err; + if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) { + return (Error)err; + } + WARN_PRINT_ONCE("PacketPeerExtension::_put_packet_native is unimplemented!"); + return FAILED; +} + +int PacketPeerExtension::get_max_packet_size() const { + int size; + if (GDVIRTUAL_CALL(_get_max_packet_size, size)) { + return size; + } + WARN_PRINT_ONCE("PacketPeerExtension::_get_max_packet_size is unimplemented!"); + return 0; +} + +void PacketPeerExtension::_bind_methods() { + GDVIRTUAL_BIND(_get_packet, "r_buffer", "r_buffer_size"); + GDVIRTUAL_BIND(_put_packet, "p_buffer", "p_buffer_size"); + GDVIRTUAL_BIND(_get_available_packet_count); + GDVIRTUAL_BIND(_get_max_packet_size); +} + +/***************/ + void PacketPeerStream::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stream_peer", "peer"), &PacketPeerStream::set_stream_peer); ClassDB::bind_method(D_METHOD("get_stream_peer"), &PacketPeerStream::get_stream_peer); diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index 9a345af3d0..bc1f4aaabf 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -35,6 +35,10 @@ #include "core/object/class_db.h" #include "core/templates/ring_buffer.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" +#include "core/variant/native_ptr.h" + class PacketPeer : public RefCounted { GDCLASS(PacketPeer, RefCounted); @@ -73,6 +77,25 @@ public: ~PacketPeer() {} }; +class PacketPeerExtension : public PacketPeer { + GDCLASS(PacketPeerExtension, PacketPeer); + +protected: + static void _bind_methods(); + +public: + virtual int get_available_packet_count() const override; + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) override; ///< buffer is GONE after next get_packet + virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override; + virtual int get_max_packet_size() const override; + + /* GDExtension */ + GDVIRTUAL0RC(int, _get_available_packet_count); + GDVIRTUAL2R(int, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>); + GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int); + GDVIRTUAL0RC(int, _get_max_packet_size); +}; + class PacketPeerStream : public PacketPeer { GDCLASS(PacketPeerStream, PacketPeer); diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 27f8d4e88f..8ab025dda1 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -410,6 +410,63 @@ void StreamPeer::_bind_methods() { //////////////////////////////// +int StreamPeerExtension::get_available_bytes() const { + int count; + if (GDVIRTUAL_CALL(_get_available_bytes, count)) { + return count; + } + WARN_PRINT_ONCE("StreamPeerExtension::_get_available_bytes is unimplemented!"); + return -1; +} + +Error StreamPeerExtension::get_data(uint8_t *r_buffer, int p_bytes) { + int err; + int received = 0; + if (GDVIRTUAL_CALL(_get_data, r_buffer, p_bytes, &received, err)) { + return (Error)err; + } + WARN_PRINT_ONCE("StreamPeerExtension::_get_data is unimplemented!"); + return FAILED; +} + +Error StreamPeerExtension::get_partial_data(uint8_t *r_buffer, int p_bytes, int &r_received) { + int err; + if (GDVIRTUAL_CALL(_get_partial_data, r_buffer, p_bytes, &r_received, err)) { + return (Error)err; + } + WARN_PRINT_ONCE("StreamPeerExtension::_get_partial_data is unimplemented!"); + return FAILED; +} + +Error StreamPeerExtension::put_data(const uint8_t *p_data, int p_bytes) { + int err; + int sent = 0; + if (GDVIRTUAL_CALL(_put_data, p_data, p_bytes, &sent, err)) { + return (Error)err; + } + WARN_PRINT_ONCE("StreamPeerExtension::_put_data is unimplemented!"); + return FAILED; +} + +Error StreamPeerExtension::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) { + int err; + if (GDVIRTUAL_CALL(_put_data, p_data, p_bytes, &r_sent, err)) { + return (Error)err; + } + WARN_PRINT_ONCE("StreamPeerExtension::_put_partial_data is unimplemented!"); + return FAILED; +} + +void StreamPeerExtension::_bind_methods() { + GDVIRTUAL_BIND(_get_data, "r_buffer", "r_bytes", "r_received"); + GDVIRTUAL_BIND(_get_partial_data, "r_buffer", "r_bytes", "r_received"); + GDVIRTUAL_BIND(_put_data, "p_data", "p_bytes", "r_sent"); + GDVIRTUAL_BIND(_put_partial_data, "p_data", "p_bytes", "r_sent"); + GDVIRTUAL_BIND(_get_available_bytes); +} + +//////////////////////////////// + void StreamPeerBuffer::_bind_methods() { ClassDB::bind_method(D_METHOD("seek", "position"), &StreamPeerBuffer::seek); ClassDB::bind_method(D_METHOD("get_size"), &StreamPeerBuffer::get_size); diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index effc3850af..89432951c5 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -33,6 +33,10 @@ #include "core/object/ref_counted.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" +#include "core/variant/native_ptr.h" + class StreamPeer : public RefCounted { GDCLASS(StreamPeer, RefCounted); OBJ_CATEGORY("Networking"); @@ -58,6 +62,7 @@ public: virtual int get_available_bytes() const = 0; + /* helpers */ void set_big_endian(bool p_big_endian); bool is_big_endian_enabled() const; @@ -92,6 +97,26 @@ public: StreamPeer() {} }; +class StreamPeerExtension : public StreamPeer { + GDCLASS(StreamPeerExtension, StreamPeer); + +protected: + static void _bind_methods(); + +public: + virtual Error put_data(const uint8_t *p_data, int p_bytes) override; + virtual Error put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) override; + virtual Error get_data(uint8_t *p_buffer, int p_bytes) override; + virtual Error get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) override; + virtual int get_available_bytes() const override; + + GDVIRTUAL3R(int, _put_data, GDNativeConstPtr<const uint8_t>, int, GDNativePtr<int>); + GDVIRTUAL3R(int, _put_partial_data, GDNativeConstPtr<const uint8_t>, int, GDNativePtr<int>); + GDVIRTUAL3R(int, _get_data, GDNativePtr<uint8_t>, int, GDNativePtr<int>); + GDVIRTUAL3R(int, _get_partial_data, GDNativePtr<uint8_t>, int, GDNativePtr<int>); + GDVIRTUAL0RC(int, _get_available_bytes); +}; + class StreamPeerBuffer : public StreamPeer { GDCLASS(StreamPeerBuffer, StreamPeer); diff --git a/core/multiplayer/multiplayer_peer.cpp b/core/multiplayer/multiplayer_peer.cpp index 40847102d8..3c33948e2f 100644 --- a/core/multiplayer/multiplayer_peer.cpp +++ b/core/multiplayer/multiplayer_peer.cpp @@ -53,6 +53,30 @@ uint32_t MultiplayerPeer::generate_unique_id() const { return hash; } +void MultiplayerPeer::set_transfer_channel(int p_channel) { + transfer_channel = p_channel; +} + +int MultiplayerPeer::get_transfer_channel() const { + return transfer_channel; +} + +void MultiplayerPeer::set_transfer_mode(Multiplayer::TransferMode p_mode) { + transfer_mode = p_mode; +} + +Multiplayer::TransferMode MultiplayerPeer::get_transfer_mode() const { + return transfer_mode; +} + +void MultiplayerPeer::set_refuse_new_connections(bool p_enable) { + refuse_connections = p_enable; +} + +bool MultiplayerPeer::is_refusing_new_connections() const { + return refuse_connections; +} + void MultiplayerPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transfer_channel", "channel"), &MultiplayerPeer::set_transfer_channel); ClassDB::bind_method(D_METHOD("get_transfer_channel"), &MultiplayerPeer::get_transfer_channel); @@ -88,3 +112,160 @@ void MultiplayerPeer::_bind_methods() { ADD_SIGNAL(MethodInfo("connection_succeeded")); ADD_SIGNAL(MethodInfo("connection_failed")); } + +/*************/ + +int MultiplayerPeerExtension::get_available_packet_count() const { + int count; + if (GDVIRTUAL_CALL(_get_available_packet_count, count)) { + return count; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_available_packet_count is unimplemented!"); + return -1; +} + +Error MultiplayerPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { + int err; + if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) { + return (Error)err; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_packet_native is unimplemented!"); + return FAILED; +} + +Error MultiplayerPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + int err; + if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) { + return (Error)err; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_put_packet_native is unimplemented!"); + return FAILED; +} + +int MultiplayerPeerExtension::get_max_packet_size() const { + int size; + if (GDVIRTUAL_CALL(_get_max_packet_size, size)) { + return size; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_max_packet_size is unimplemented!"); + return 0; +} + +void MultiplayerPeerExtension::set_transfer_channel(int p_channel) { + if (GDVIRTUAL_CALL(_set_transfer_channel, p_channel)) { + return; + } + MultiplayerPeer::set_transfer_channel(p_channel); +} + +int MultiplayerPeerExtension::get_transfer_channel() const { + int channel; + if (GDVIRTUAL_CALL(_get_transfer_channel, channel)) { + return channel; + } + return MultiplayerPeer::get_transfer_channel(); +} + +void MultiplayerPeerExtension::set_transfer_mode(Multiplayer::TransferMode p_mode) { + if (GDVIRTUAL_CALL(_set_transfer_mode, p_mode)) { + return; + } + MultiplayerPeer::set_transfer_mode(p_mode); +} + +Multiplayer::TransferMode MultiplayerPeerExtension::get_transfer_mode() const { + int mode; + if (GDVIRTUAL_CALL(_get_transfer_mode, mode)) { + return (Multiplayer::TransferMode)mode; + } + return MultiplayerPeer::get_transfer_mode(); +} + +void MultiplayerPeerExtension::set_target_peer(int p_peer_id) { + if (GDVIRTUAL_CALL(_set_target_peer, p_peer_id)) { + return; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_set_target_peer is unimplemented!"); +} + +int MultiplayerPeerExtension::get_packet_peer() const { + int peer; + if (GDVIRTUAL_CALL(_get_packet_peer, peer)) { + return peer; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_packet_peer is unimplemented!"); + return 0; +} + +bool MultiplayerPeerExtension::is_server() const { + bool server; + if (GDVIRTUAL_CALL(_is_server, server)) { + return server; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_is_server is unimplemented!"); + return false; +} + +void MultiplayerPeerExtension::poll() { + int err; + if (GDVIRTUAL_CALL(_poll, err)) { + return; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_poll is unimplemented!"); +} + +int MultiplayerPeerExtension::get_unique_id() const { + int id; + if (GDVIRTUAL_CALL(_get_unique_id, id)) { + return id; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_unique_id is unimplemented!"); + return 0; +} + +void MultiplayerPeerExtension::set_refuse_new_connections(bool p_enable) { + if (GDVIRTUAL_CALL(_set_refuse_new_connections, p_enable)) { + return; + } + MultiplayerPeer::set_refuse_new_connections(p_enable); +} + +bool MultiplayerPeerExtension::is_refusing_new_connections() const { + bool refusing; + if (GDVIRTUAL_CALL(_is_refusing_new_connections, refusing)) { + return refusing; + } + return MultiplayerPeer::is_refusing_new_connections(); +} + +MultiplayerPeer::ConnectionStatus MultiplayerPeerExtension::get_connection_status() const { + int status; + if (GDVIRTUAL_CALL(_get_connection_status, status)) { + return (ConnectionStatus)status; + } + WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_connection_status is unimplemented!"); + return CONNECTION_DISCONNECTED; +} + +void MultiplayerPeerExtension::_bind_methods() { + GDVIRTUAL_BIND(_get_packet, "r_buffer", "r_buffer_size"); + GDVIRTUAL_BIND(_put_packet, "p_buffer", "p_buffer_size"); + GDVIRTUAL_BIND(_get_available_packet_count); + GDVIRTUAL_BIND(_get_max_packet_size); + + GDVIRTUAL_BIND(_set_transfer_channel, "p_channel"); + GDVIRTUAL_BIND(_get_transfer_channel); + + GDVIRTUAL_BIND(_set_transfer_mode, "p_mode"); + GDVIRTUAL_BIND(_get_transfer_mode); + + GDVIRTUAL_BIND(_set_target_peer, "p_peer"); + + GDVIRTUAL_BIND(_get_packet_peer); + GDVIRTUAL_BIND(_is_server); + GDVIRTUAL_BIND(_poll); + GDVIRTUAL_BIND(_get_unique_id); + GDVIRTUAL_BIND(_set_refuse_new_connections, "p_enable"); + GDVIRTUAL_BIND(_is_refusing_new_connections); + GDVIRTUAL_BIND(_get_connection_status); +} diff --git a/core/multiplayer/multiplayer_peer.h b/core/multiplayer/multiplayer_peer.h index ba00c3b41b..126ba9e645 100644 --- a/core/multiplayer/multiplayer_peer.h +++ b/core/multiplayer/multiplayer_peer.h @@ -34,12 +34,21 @@ #include "core/io/packet_peer.h" #include "core/multiplayer/multiplayer.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" +#include "core/variant/native_ptr.h" + class MultiplayerPeer : public PacketPeer { GDCLASS(MultiplayerPeer, PacketPeer); protected: static void _bind_methods(); +private: + int transfer_channel = 0; + Multiplayer::TransferMode transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; + bool refuse_connections = false; + public: enum { TARGET_PEER_BROADCAST = 0, @@ -52,10 +61,13 @@ public: CONNECTION_CONNECTED, }; - virtual void set_transfer_channel(int p_channel) = 0; - virtual int get_transfer_channel() const = 0; - virtual void set_transfer_mode(Multiplayer::TransferMode p_mode) = 0; - virtual Multiplayer::TransferMode get_transfer_mode() const = 0; + virtual void set_transfer_channel(int p_channel); + virtual int get_transfer_channel() const; + virtual void set_transfer_mode(Multiplayer::TransferMode p_mode); + virtual Multiplayer::TransferMode get_transfer_mode() const; + virtual void set_refuse_new_connections(bool p_enable); + virtual bool is_refusing_new_connections() const; + virtual void set_target_peer(int p_peer_id) = 0; virtual int get_packet_peer() const = 0; @@ -66,15 +78,67 @@ public: virtual int get_unique_id() const = 0; - virtual void set_refuse_new_connections(bool p_enable) = 0; - virtual bool is_refusing_new_connections() const = 0; - virtual ConnectionStatus get_connection_status() const = 0; + uint32_t generate_unique_id() const; MultiplayerPeer() {} }; -VARIANT_ENUM_CAST(MultiplayerPeer::ConnectionStatus) +VARIANT_ENUM_CAST(MultiplayerPeer::ConnectionStatus); + +class MultiplayerPeerExtension : public MultiplayerPeer { + GDCLASS(MultiplayerPeerExtension, MultiplayerPeer); + +protected: + static void _bind_methods(); + +public: + /* PacketPeer */ + virtual int get_available_packet_count() const override; + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) override; ///< buffer is GONE after next get_packet + virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override; + virtual int get_max_packet_size() const override; + + /* MultiplayerPeer */ + virtual void set_transfer_channel(int p_channel) override; + virtual int get_transfer_channel() const override; + virtual void set_transfer_mode(Multiplayer::TransferMode p_mode) override; + virtual Multiplayer::TransferMode get_transfer_mode() const override; + virtual void set_target_peer(int p_peer_id) override; + + virtual int get_packet_peer() const override; + + virtual bool is_server() const override; + + virtual void poll() override; + + virtual int get_unique_id() const override; + + virtual void set_refuse_new_connections(bool p_enable) override; + virtual bool is_refusing_new_connections() const override; + + virtual ConnectionStatus get_connection_status() const override; + + /* PacketPeer GDExtension */ + GDVIRTUAL0RC(int, _get_available_packet_count); + GDVIRTUAL2R(int, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>); + GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int); + GDVIRTUAL0RC(int, _get_max_packet_size); + + /* MultiplayerPeer GDExtension */ + GDVIRTUAL1(_set_transfer_channel, int); + GDVIRTUAL0RC(int, _get_transfer_channel); + GDVIRTUAL1(_set_transfer_mode, int); + GDVIRTUAL0RC(int, _get_transfer_mode); + GDVIRTUAL1(_set_target_peer, int); + GDVIRTUAL0RC(int, _get_packet_peer); + GDVIRTUAL0RC(bool, _is_server); + GDVIRTUAL0R(int, _poll); + GDVIRTUAL0RC(int, _get_unique_id); + GDVIRTUAL1(_set_refuse_new_connections, bool); + GDVIRTUAL0RC(bool, _is_refusing_new_connections); + GDVIRTUAL0RC(int, _get_connection_status); +}; #endif // NETWORKED_MULTIPLAYER_PEER_H diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 3a037f9dd1..e33c21cc00 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -169,11 +169,13 @@ void register_core_types() { GDREGISTER_VIRTUAL_CLASS(IP); GDREGISTER_VIRTUAL_CLASS(StreamPeer); + GDREGISTER_CLASS(StreamPeerExtension); GDREGISTER_CLASS(StreamPeerBuffer); GDREGISTER_CLASS(StreamPeerTCP); GDREGISTER_CLASS(TCPServer); GDREGISTER_VIRTUAL_CLASS(PacketPeer); + GDREGISTER_CLASS(PacketPeerExtension); GDREGISTER_CLASS(PacketPeerStream); GDREGISTER_CLASS(PacketPeerUDP); GDREGISTER_CLASS(UDPServer); @@ -197,6 +199,7 @@ void register_core_types() { ResourceLoader::add_resource_format_loader(resource_format_loader_crypto); GDREGISTER_VIRTUAL_CLASS(MultiplayerPeer); + GDREGISTER_VIRTUAL_CLASS(MultiplayerPeerExtension); GDREGISTER_VIRTUAL_CLASS(MultiplayerReplicator); GDREGISTER_CLASS(MultiplayerAPI); GDREGISTER_CLASS(MainLoop); diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h index b4ec0df7d6..b7e8d92f62 100644 --- a/core/variant/native_ptr.h +++ b/core/variant/native_ptr.h @@ -117,6 +117,7 @@ GDVIRTUAL_NATIVE_PTR(char16_t) GDVIRTUAL_NATIVE_PTR(char32_t) GDVIRTUAL_NATIVE_PTR(wchar_t) GDVIRTUAL_NATIVE_PTR(uint8_t) +GDVIRTUAL_NATIVE_PTR(uint8_t *) GDVIRTUAL_NATIVE_PTR(int8_t) GDVIRTUAL_NATIVE_PTR(uint16_t) GDVIRTUAL_NATIVE_PTR(int16_t) |