| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  emws_client.cpp                                                      */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							| 
									
										
										
										
											2017-12-21 03:47:16 +01:00
										 |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							|  |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-01-01 20:13:46 +01:00
										 |  |  | /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2019-01-01 12:46:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | #ifdef JAVASCRIPT_ENABLED
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "emws_client.h"
 | 
					
						
							|  |  |  | #include "core/io/ip.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-03 05:46:38 +01:00
										 |  |  | #include "core/project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | #include "emscripten.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | void EMWSClient::_esws_on_connect(void *obj, char *proto) { | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 	EMWSClient *client = static_cast<EMWSClient *>(obj); | 
					
						
							|  |  |  | 	client->_is_connecting = false; | 
					
						
							|  |  |  | 	client->_on_connect(String(proto)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | void EMWSClient::_esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string) { | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 	EMWSClient *client = static_cast<EMWSClient *>(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-03 05:46:38 +01:00
										 |  |  | 	Error err = static_cast<EMWSPeer *>(*client->get_peer(1))->read_msg(p_data, p_data_size, p_is_string == 1); | 
					
						
							|  |  |  | 	if (err == OK) | 
					
						
							|  |  |  | 		client->_on_peer_packet(); | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | void EMWSClient::_esws_on_error(void *obj) { | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 	EMWSClient *client = static_cast<EMWSClient *>(obj); | 
					
						
							|  |  |  | 	client->_is_connecting = false; | 
					
						
							|  |  |  | 	client->_on_error(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | void EMWSClient::_esws_on_close(void *obj, int code, const char *reason, int was_clean) { | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 	EMWSClient *client = static_cast<EMWSClient *>(obj); | 
					
						
							| 
									
										
										
										
											2018-09-23 21:14:20 +02:00
										 |  |  | 	client->_on_close_request(code, String(reason)); | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 	client->_is_connecting = false; | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | 	client->disconnect_from_host(); | 
					
						
							| 
									
										
										
										
											2018-09-24 00:58:28 +02:00
										 |  |  | 	client->_on_disconnect(was_clean != 0); | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-11 18:39:03 +02:00
										 |  |  | Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocols, const Vector<String> p_custom_headers) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | 	if (_js_id) { | 
					
						
							|  |  |  | 		godot_js_websocket_destroy(_js_id); | 
					
						
							|  |  |  | 		_js_id = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-11 18:39:03 +02:00
										 |  |  | 	String proto_string; | 
					
						
							|  |  |  | 	for (int i = 0; i < p_protocols.size(); i++) { | 
					
						
							|  |  |  | 		if (i != 0) | 
					
						
							|  |  |  | 			proto_string += ","; | 
					
						
							|  |  |  | 		proto_string += p_protocols[i]; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	String str = "ws://"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 20:13:24 +02:00
										 |  |  | 	if (p_custom_headers.size()) { | 
					
						
							|  |  |  | 		WARN_PRINT_ONCE("Custom headers are not supported in in HTML5 platform."); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-07 15:38:03 +02:00
										 |  |  | 	if (p_ssl) { | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 		str = "wss://"; | 
					
						
							| 
									
										
										
										
											2019-10-07 15:38:03 +02:00
										 |  |  | 		if (ssl_cert.is_valid()) { | 
					
						
							|  |  |  | 			WARN_PRINT_ONCE("Custom SSL certificate is not supported in HTML5 platform."); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 	str += p_host + ":" + itos(p_port) + p_path; | 
					
						
							|  |  |  | 	_is_connecting = true; | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	_js_id = godot_js_websocket_create(this, str.utf8().get_data(), proto_string.utf8().get_data(), &_esws_on_connect, &_esws_on_message, &_esws_on_error, &_esws_on_close); | 
					
						
							|  |  |  | 	if (!_js_id) { | 
					
						
							| 
									
										
										
										
											2020-02-15 17:28:52 +01:00
										 |  |  | 		return FAILED; | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | 	static_cast<Ref<EMWSPeer> >(_peer)->set_sock(_js_id, _in_buf_size, _in_pkt_size); | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void EMWSClient::poll() { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<WebSocketPeer> EMWSClient::get_peer(int p_peer_id) const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return _peer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-15 17:28:52 +01:00
										 |  |  | 	if (_peer->is_connected_to_host()) { | 
					
						
							|  |  |  | 		if (_is_connecting) | 
					
						
							|  |  |  | 			return CONNECTION_CONNECTING; | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 		return CONNECTION_CONNECTED; | 
					
						
							| 
									
										
										
										
											2020-02-15 17:28:52 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return CONNECTION_DISCONNECTED; | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-23 21:14:20 +02:00
										 |  |  | void EMWSClient::disconnect_from_host(int p_code, String p_reason) { | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-23 21:14:20 +02:00
										 |  |  | 	_peer->close(p_code, p_reason); | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | IP_Address EMWSClient::get_connected_host() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-04 12:58:06 +02:00
										 |  |  | 	ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export."); | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | uint16_t EMWSClient::get_connected_port() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-04 12:58:06 +02:00
										 |  |  | 	ERR_FAIL_V_MSG(0, "Not supported in HTML5 export."); | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-03 05:46:38 +01:00
										 |  |  | int EMWSClient::get_max_packet_size() const { | 
					
						
							|  |  |  | 	return (1 << _in_buf_size) - PROTO_SIZE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 17:19:23 +02:00
										 |  |  | Error EMWSClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) { | 
					
						
							|  |  |  | 	_in_buf_size = nearest_shift(p_in_buffer - 1) + 10; | 
					
						
							|  |  |  | 	_in_pkt_size = nearest_shift(p_in_packets - 1); | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | EMWSClient::EMWSClient() { | 
					
						
							| 
									
										
										
										
											2018-12-26 17:51:12 +01:00
										 |  |  | 	_in_buf_size = nearest_shift((int)GLOBAL_GET(WSC_IN_BUF) - 1) + 10; | 
					
						
							|  |  |  | 	_in_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_IN_PKT) - 1); | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 	_is_connecting = false; | 
					
						
							|  |  |  | 	_peer = Ref<EMWSPeer>(memnew(EMWSPeer)); | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | 	_js_id = 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | EMWSClient::~EMWSClient() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	disconnect_from_host(); | 
					
						
							|  |  |  | 	_peer = Ref<EMWSPeer>(); | 
					
						
							| 
									
										
										
										
											2020-10-17 23:31:30 +02:00
										 |  |  | 	if (_js_id) { | 
					
						
							|  |  |  | 		godot_js_websocket_destroy(_js_id); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-21 03:13:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif // JAVASCRIPT_ENABLED
 |