Expose channels in NetworkedMultiplayerENet

This commit is contained in:
Fabio Alessandrelli 2018-05-12 19:42:00 +02:00
parent ca10cb6eea
commit f95e4c72df
3 changed files with 115 additions and 6 deletions

View file

@ -65,6 +65,20 @@
Disconnect the given peer. If "now" is set to true, the connection will be closed immediately without flushing queued messages. Disconnect the given peer. If "now" is set to true, the connection will be closed immediately without flushing queued messages.
</description> </description>
</method> </method>
<method name="get_last_packet_channel" qualifiers="const">
<return type="int">
</return>
<description>
Returns the channel of the last packet fetched via [method PacketPeer.get_packet]
</description>
</method>
<method name="get_packet_channel" qualifiers="const">
<return type="int">
</return>
<description>
Returns the channel of the next packet that will be retrieved via [method PacketPeer.get_packet_peer]
</description>
</method>
<method name="get_peer_address" qualifiers="const"> <method name="get_peer_address" qualifiers="const">
<return type="String"> <return type="String">
</return> </return>
@ -94,9 +108,18 @@
</method> </method>
</methods> </methods>
<members> <members>
<member name="always_ordered" type="bool" setter="set_always_ordered" getter="is_always_ordered">
Always use [code]TRANSFER_MODE_ORDERED[/code] in place of [code]TRANSFER_MODE_UNRELIABLE[/code]. This is the only way to use ordering with the RPC system.
</member>
<member name="channel_count" type="int" setter="set_channel_count" getter="get_channel_count">
The number of channels to be used by ENet. Default: [code]3[/code]. Channels are used to separate different kinds of data. In realiable or ordered mode, for example, the packet delivery order is ensured on a per channel basis.
</member>
<member name="compression_mode" type="int" setter="set_compression_mode" getter="get_compression_mode" enum="NetworkedMultiplayerENet.CompressionMode"> <member name="compression_mode" type="int" setter="set_compression_mode" getter="get_compression_mode" enum="NetworkedMultiplayerENet.CompressionMode">
The compression method used for network packets. Default is no compression. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all. The compression method used for network packets. Default is no compression. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all.
</member> </member>
<member name="transfer_channel" type="int" setter="set_transfer_channel" getter="get_transfer_channel">
Set the default channel to be used to transfer data. By default this value is [code]-1[/code] which means that ENet will only use 2 channels, one for reliable and one for unreliable packets. Channel [code]0[/code] is reserved, and cannot be used. Setting this member to any value between [code]0[/code] and [member channel_count] (excluded) will force ENet to use that channel for sending data.
</member>
</members> </members>
<constants> <constants>
<constant name="COMPRESS_NONE" value="0" enum="CompressionMode"> <constant name="COMPRESS_NONE" value="0" enum="CompressionMode">

View file

@ -55,6 +55,22 @@ int NetworkedMultiplayerENet::get_packet_peer() const {
return incoming_packets.front()->get().from; return incoming_packets.front()->get().from;
} }
int NetworkedMultiplayerENet::get_packet_channel() const {
ERR_FAIL_COND_V(!active, -1);
ERR_FAIL_COND_V(incoming_packets.size() == 0, -1);
return incoming_packets.front()->get().channel;
}
int NetworkedMultiplayerENet::get_last_packet_channel() const {
ERR_FAIL_COND_V(!active, -1);
ERR_FAIL_COND_V(!current_packet.packet, -1);
return current_packet.channel;
}
Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) { Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) {
ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
@ -83,7 +99,7 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
host = enet_host_create(&address /* the address to bind the server host to */, host = enet_host_create(&address /* the address to bind the server host to */,
p_max_clients /* allow up to 32 clients and/or outgoing connections */, p_max_clients /* allow up to 32 clients and/or outgoing connections */,
SYSCH_MAX /* allow up to SYSCH_MAX channels to be used */, channel_count /* allow up to channel_count to be used */,
p_in_bandwidth /* limit incoming bandwith if > 0 */, p_in_bandwidth /* limit incoming bandwith if > 0 */,
p_out_bandwidth /* limit outgoing bandwith if > 0 */); p_out_bandwidth /* limit outgoing bandwith if > 0 */);
@ -127,13 +143,13 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
host = enet_host_create(&c_client /* create a client host */, host = enet_host_create(&c_client /* create a client host */,
1 /* only allow 1 outgoing connection */, 1 /* only allow 1 outgoing connection */,
SYSCH_MAX /* allow up to SYSCH_MAX channels to be used */, channel_count /* allow up to channel_count to be used */,
p_in_bandwidth /* limit incoming bandwith if > 0 */, p_in_bandwidth /* limit incoming bandwith if > 0 */,
p_out_bandwidth /* limit outgoing bandwith if > 0 */); p_out_bandwidth /* limit outgoing bandwith if > 0 */);
} else { } else {
host = enet_host_create(NULL /* create a client host */, host = enet_host_create(NULL /* create a client host */,
1 /* only allow 1 outgoing connection */, 1 /* only allow 1 outgoing connection */,
SYSCH_MAX /* allow up to SYSCH_MAX channels to be used */, channel_count /* allow up to channel_count to be used */,
p_in_bandwidth /* limit incoming bandwith if > 0 */, p_in_bandwidth /* limit incoming bandwith if > 0 */,
p_out_bandwidth /* limit outgoing bandwith if > 0 */); p_out_bandwidth /* limit outgoing bandwith if > 0 */);
} }
@ -167,7 +183,7 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
unique_id = _gen_unique_id(); unique_id = _gen_unique_id();
// Initiate connection, allocating enough channels // Initiate connection, allocating enough channels
ENetPeer *peer = enet_host_connect(host, &address, SYSCH_MAX, unique_id); ENetPeer *peer = enet_host_connect(host, &address, channel_count, unique_id);
if (peer == NULL) { if (peer == NULL) {
enet_host_destroy(host); enet_host_destroy(host);
@ -316,7 +332,7 @@ void NetworkedMultiplayerENet::poll() {
} }
enet_packet_destroy(event.packet); enet_packet_destroy(event.packet);
} else if (event.channelID < SYSCH_MAX) { } else if (event.channelID < channel_count) {
Packet packet; Packet packet;
packet.packet = event.packet; packet.packet = event.packet;
@ -330,6 +346,7 @@ void NetworkedMultiplayerENet::poll() {
uint32_t flags = decode_uint32(&event.packet->data[8]); uint32_t flags = decode_uint32(&event.packet->data[8]);
packet.from = source; packet.from = source;
packet.channel = event.channelID;
if (server) { if (server) {
// Someone is cheating and trying to fake the source! // Someone is cheating and trying to fake the source!
@ -496,6 +513,9 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
switch (transfer_mode) { switch (transfer_mode) {
case TRANSFER_MODE_UNRELIABLE: { case TRANSFER_MODE_UNRELIABLE: {
if (always_ordered)
packet_flags = 0;
else
packet_flags = ENET_PACKET_FLAG_UNSEQUENCED; packet_flags = ENET_PACKET_FLAG_UNSEQUENCED;
channel = SYSCH_UNRELIABLE; channel = SYSCH_UNRELIABLE;
} break; } break;
@ -509,6 +529,9 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
} break; } break;
} }
if (transfer_channel > SYSCH_CONFIG)
channel = transfer_channel;
Map<int, ENetPeer *>::Element *E = NULL; Map<int, ENetPeer *>::Element *E = NULL;
if (target_peer != 0) { if (target_peer != 0) {
@ -572,6 +595,7 @@ void NetworkedMultiplayerENet::_pop_current_packet() {
enet_packet_destroy(current_packet.packet); enet_packet_destroy(current_packet.packet);
current_packet.packet = NULL; current_packet.packet = NULL;
current_packet.from = 0; current_packet.from = 0;
current_packet.channel = -1;
} }
} }
@ -759,6 +783,40 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
#endif #endif
} }
void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
ERR_FAIL_COND(p_channel < -1 || p_channel >= channel_count);
if (p_channel == SYSCH_CONFIG) {
ERR_EXPLAIN("Channel " + itos(SYSCH_CONFIG) + " is reserved");
ERR_FAIL();
}
transfer_channel = p_channel;
}
int NetworkedMultiplayerENet::get_transfer_channel() const {
return transfer_channel;
}
void NetworkedMultiplayerENet::set_channel_count(int p_channel) {
ERR_FAIL_COND(active);
ERR_FAIL_COND(p_channel < SYSCH_MAX);
channel_count = p_channel;
}
int NetworkedMultiplayerENet::get_channel_count() const {
return channel_count;
}
void NetworkedMultiplayerENet::set_always_ordered(bool p_ordered) {
always_ordered = p_ordered;
}
bool NetworkedMultiplayerENet::is_always_ordered() const {
return always_ordered;
}
void NetworkedMultiplayerENet::_bind_methods() { 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_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0));
@ -771,7 +829,19 @@ void NetworkedMultiplayerENet::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &NetworkedMultiplayerENet::get_peer_address); ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &NetworkedMultiplayerENet::get_peer_address);
ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &NetworkedMultiplayerENet::get_peer_port); ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &NetworkedMultiplayerENet::get_peer_port);
ClassDB::bind_method(D_METHOD("get_packet_channel"), &NetworkedMultiplayerENet::get_packet_channel);
ClassDB::bind_method(D_METHOD("get_last_packet_channel"), &NetworkedMultiplayerENet::get_last_packet_channel);
ClassDB::bind_method(D_METHOD("set_transfer_channel", "channel"), &NetworkedMultiplayerENet::set_transfer_channel);
ClassDB::bind_method(D_METHOD("get_transfer_channel"), &NetworkedMultiplayerENet::get_transfer_channel);
ClassDB::bind_method(D_METHOD("set_channel_count", "channels"), &NetworkedMultiplayerENet::set_channel_count);
ClassDB::bind_method(D_METHOD("get_channel_count"), &NetworkedMultiplayerENet::get_channel_count);
ClassDB::bind_method(D_METHOD("set_always_ordered", "ordered"), &NetworkedMultiplayerENet::set_always_ordered);
ClassDB::bind_method(D_METHOD("is_always_ordered"), &NetworkedMultiplayerENet::is_always_ordered);
ADD_PROPERTY(PropertyInfo(Variant::INT, "compression_mode", PROPERTY_HINT_ENUM, "None,Range Coder,FastLZ,ZLib,ZStd"), "set_compression_mode", "get_compression_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "compression_mode", PROPERTY_HINT_ENUM, "None,Range Coder,FastLZ,ZLib,ZStd"), "set_compression_mode", "get_compression_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "transfer_channel"), "set_transfer_channel", "get_transfer_channel");
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel_count"), "set_channel_count", "get_channel_count");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "always_ordered"), "set_always_ordered", "is_always_ordered");
BIND_ENUM_CONSTANT(COMPRESS_NONE); BIND_ENUM_CONSTANT(COMPRESS_NONE);
BIND_ENUM_CONSTANT(COMPRESS_RANGE_CODER); BIND_ENUM_CONSTANT(COMPRESS_RANGE_CODER);
@ -789,6 +859,9 @@ NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
target_peer = 0; target_peer = 0;
current_packet.packet = NULL; current_packet.packet = NULL;
transfer_mode = TRANSFER_MODE_RELIABLE; transfer_mode = TRANSFER_MODE_RELIABLE;
channel_count = SYSCH_MAX;
transfer_channel = -1;
always_ordered = false;
connection_status = CONNECTION_DISCONNECTED; connection_status = CONNECTION_DISCONNECTED;
compression_mode = COMPRESS_NONE; compression_mode = COMPRESS_NONE;
enet_compressor.context = this; enet_compressor.context = this;

View file

@ -68,6 +68,9 @@ private:
int target_peer; int target_peer;
TransferMode transfer_mode; TransferMode transfer_mode;
int transfer_channel;
int channel_count;
bool always_ordered;
ENetEvent event; ENetEvent event;
ENetPeer *peer; ENetPeer *peer;
@ -83,6 +86,7 @@ private:
ENetPacket *packet; ENetPacket *packet;
int from; int from;
int channel;
}; };
CompressionMode compression_mode; CompressionMode compression_mode;
@ -145,6 +149,15 @@ public:
void set_compression_mode(CompressionMode p_mode); void set_compression_mode(CompressionMode p_mode);
CompressionMode get_compression_mode() const; CompressionMode get_compression_mode() const;
int get_packet_channel() const;
int get_last_packet_channel() const;
void set_transfer_channel(int p_channel);
int get_transfer_channel() const;
void set_channel_count(int p_channel);
int get_channel_count() const;
void set_always_ordered(bool p_ordered);
bool is_always_ordered() const;
NetworkedMultiplayerENet(); NetworkedMultiplayerENet();
~NetworkedMultiplayerENet(); ~NetworkedMultiplayerENet();