1 /*************************************************************************/
2 /*  networked_multiplayer_enet.h                                         */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #ifndef NETWORKED_MULTIPLAYER_ENET_H
32 #define NETWORKED_MULTIPLAYER_ENET_H
33 
34 #include "core/crypto/crypto.h"
35 #include "core/io/compression.h"
36 #include "core/io/networked_multiplayer_peer.h"
37 
38 #include <enet/enet.h>
39 
40 class NetworkedMultiplayerENet : public NetworkedMultiplayerPeer {
41 
42 	GDCLASS(NetworkedMultiplayerENet, NetworkedMultiplayerPeer);
43 
44 public:
45 	enum CompressionMode {
46 		COMPRESS_NONE,
47 		COMPRESS_RANGE_CODER,
48 		COMPRESS_FASTLZ,
49 		COMPRESS_ZLIB,
50 		COMPRESS_ZSTD
51 	};
52 
53 private:
54 	enum {
55 		SYSMSG_ADD_PEER,
56 		SYSMSG_REMOVE_PEER
57 	};
58 
59 	enum {
60 		SYSCH_CONFIG,
61 		SYSCH_RELIABLE,
62 		SYSCH_UNRELIABLE,
63 		SYSCH_MAX
64 	};
65 
66 	bool active;
67 	bool server;
68 
69 	uint32_t unique_id;
70 
71 	int target_peer;
72 	TransferMode transfer_mode;
73 	int transfer_channel;
74 	int channel_count;
75 	bool always_ordered;
76 
77 	ENetEvent event;
78 	ENetPeer *peer;
79 	ENetHost *host;
80 
81 	bool refuse_connections;
82 	bool server_relay;
83 
84 	ConnectionStatus connection_status;
85 
86 	Map<int, ENetPeer *> peer_map;
87 
88 	struct Packet {
89 
90 		ENetPacket *packet;
91 		int from;
92 		int channel;
93 	};
94 
95 	CompressionMode compression_mode;
96 
97 	List<Packet> incoming_packets;
98 
99 	Packet current_packet;
100 
101 	uint32_t _gen_unique_id() const;
102 	void _pop_current_packet();
103 
104 	Vector<uint8_t> src_compressor_mem;
105 	Vector<uint8_t> dst_compressor_mem;
106 
107 	ENetCompressor enet_compressor;
108 	static size_t enet_compress(void *context, const ENetBuffer *inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 *outData, size_t outLimit);
109 	static size_t enet_decompress(void *context, const enet_uint8 *inData, size_t inLimit, enet_uint8 *outData, size_t outLimit);
110 	static void enet_compressor_destroy(void *context);
111 	void _setup_compressor();
112 
113 	IP_Address bind_ip;
114 
115 	bool dtls_enabled;
116 	Ref<CryptoKey> dtls_key;
117 	Ref<X509Certificate> dtls_cert;
118 	bool dtls_verify;
119 
120 protected:
121 	static void _bind_methods();
122 
123 public:
124 	virtual void set_transfer_mode(TransferMode p_mode);
125 	virtual TransferMode get_transfer_mode() const;
126 	virtual void set_target_peer(int p_peer);
127 
128 	virtual int get_packet_peer() const;
129 
130 	virtual IP_Address get_peer_address(int p_peer_id) const;
131 	virtual int get_peer_port(int p_peer_id) const;
132 
133 	Error create_server(int p_port, int p_max_clients = 32, int p_in_bandwidth = 0, int p_out_bandwidth = 0);
134 	Error create_client(const String &p_address, int p_port, int p_in_bandwidth = 0, int p_out_bandwidth = 0, int p_client_port = 0);
135 
136 	void close_connection(uint32_t wait_usec = 100);
137 
138 	void disconnect_peer(int p_peer, bool now = false);
139 
140 	virtual void poll();
141 
142 	virtual bool is_server() const;
143 
144 	virtual int get_available_packet_count() const;
145 	virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); ///< buffer is GONE after next get_packet
146 	virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
147 
148 	virtual int get_max_packet_size() const;
149 
150 	virtual ConnectionStatus get_connection_status() const;
151 
152 	virtual void set_refuse_new_connections(bool p_enable);
153 	virtual bool is_refusing_new_connections() const;
154 
155 	virtual int get_unique_id() const;
156 
157 	void set_compression_mode(CompressionMode p_mode);
158 	CompressionMode get_compression_mode() const;
159 
160 	int get_packet_channel() const;
161 	int get_last_packet_channel() const;
162 	void set_transfer_channel(int p_channel);
163 	int get_transfer_channel() const;
164 	void set_channel_count(int p_channel);
165 	int get_channel_count() const;
166 	void set_always_ordered(bool p_ordered);
167 	bool is_always_ordered() const;
168 	void set_server_relay_enabled(bool p_enabled);
169 	bool is_server_relay_enabled() const;
170 
171 	NetworkedMultiplayerENet();
172 	~NetworkedMultiplayerENet();
173 
174 	void set_bind_ip(const IP_Address &p_ip);
175 	void set_dtls_enabled(bool p_enabled);
176 	bool is_dtls_enabled() const;
177 	void set_dtls_verify_enabled(bool p_enabled);
178 	bool is_dtls_verify_enabled() const;
179 	void set_dtls_key(Ref<CryptoKey> p_key);
180 	void set_dtls_certificate(Ref<X509Certificate> p_cert);
181 };
182 
183 VARIANT_ENUM_CAST(NetworkedMultiplayerENet::CompressionMode);
184 
185 #endif // NETWORKED_MULTIPLAYER_ENET_H
186