diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub
deleted file mode 100644
index 2381470..0000000
--- a/modules/websocket/SCsub
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-Import("env_modules")
-
-env_ws = env_modules.Clone()
-
-thirdparty_obj = []
-
-if env["platform"] == "javascript":
- # Our JavaScript/C++ interface.
- env.AddJSLibraries(["library_pandemonium_websocket.js"])
-
-elif env["builtin_wslay"]:
- # Thirdparty source files
- thirdparty_dir = "#thirdparty/wslay/"
- thirdparty_sources = [
- "wslay_net.c",
- "wslay_event.c",
- "wslay_queue.c",
- "wslay_frame.c",
- ]
- thirdparty_sources = [thirdparty_dir + s for s in thirdparty_sources]
-
- env_ws.Prepend(CPPPATH=[thirdparty_dir])
- env_ws.Append(CPPDEFINES=["HAVE_CONFIG_H"])
-
- if env["platform"] == "windows" or env["platform"] == "uwp":
- env_ws.Append(CPPDEFINES=["HAVE_WINSOCK2_H"])
- else:
- env_ws.Append(CPPDEFINES=["HAVE_NETINET_IN_H"])
-
- env_thirdparty = env_ws.Clone()
- env_thirdparty.disable_warnings()
- env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
- env.modules_sources += thirdparty_obj
-
-
-# Pandemonium source files
-
-module_obj = []
-
-env_ws.add_source_files(module_obj, "*.cpp")
-env.modules_sources += module_obj
-
-# Needed to force rebuilding the module files when the thirdparty library is updated.
-env.Depends(module_obj, thirdparty_obj)
diff --git a/modules/websocket/config.py b/modules/websocket/config.py
deleted file mode 100644
index d372240..0000000
--- a/modules/websocket/config.py
+++ /dev/null
@@ -1,14 +0,0 @@
-def can_build(env, platform):
- return True
-
-
-def configure(env):
- pass
-
-
-def get_doc_classes():
- return ["WebSocketClient", "WebSocketMultiplayerPeer", "WebSocketPeer", "WebSocketServer"]
-
-
-def get_doc_path():
- return "doc_classes"
diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml
deleted file mode 100644
index 3423866..0000000
--- a/modules/websocket/doc_classes/WebSocketClient.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
- A WebSocket client implementation.
-
-
- This class implements a WebSocket client compatible with any RFC 6455-compliant WebSocket server.
- This client can be optionally used as a network peer for the [MultiplayerAPI].
- After starting the client ([method connect_to_url]), you will need to [method NetworkedMultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]).
- You will receive appropriate signals when connecting, disconnecting, or when new data is available.
-
-
-
-
-
-
-
-
-
-
-
- Connects to the given URL requesting one of the given [code]protocols[/code] as sub-protocol. If the list empty (default), no sub-protocol will be requested.
- If [code]true[/code] is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI], connections to non-Godot servers will not work, and [signal data_received] will not be emitted.
- If [code]false[/code] is passed instead (default), you must call [PacketPeer] functions ([code]put_packet[/code], [code]get_packet[/code], etc.) on the [WebSocketPeer] returned via [code]get_peer(1)[/code] and not on this object directly (e.g. [code]get_peer(1).put_packet(data)[/code]).
- You can optionally pass a list of [code]custom_headers[/code] to be added to the handshake HTTP request.
- [b]Note:[/b] To avoid mixed content warnings or errors in HTML5, you may have to use a [code]url[/code] that starts with [code]wss://[/code] (secure) instead of [code]ws://[/code]. When doing so, make sure to use the fully qualified domain name that matches the one defined in the server's SSL certificate. Do not connect directly via the IP address for [code]wss://[/code] connections, as it won't match with the SSL certificate.
- [b]Note:[/b] Specifying [code]custom_headers[/code] is not supported in HTML5 exports due to browsers restrictions.
-
-
-
-
-
-
-
- Disconnects this client from the connected host. See [method WebSocketPeer.close] for more information.
-
-
-
-
-
- Return the IP address of the currently connected host.
-
-
-
-
-
- Return the IP port of the currently connected host.
-
-
-
-
-
- If specified, this [X509Certificate] will be the only one accepted when connecting to an SSL host. Any other certificate provided by the server will be regarded as invalid.
- [b]Note:[/b] Specifying a custom [code]trusted_ssl_certificate[/code] is not supported in HTML5 exports due to browsers restrictions.
-
-
- If [code]true[/code], SSL certificate verification is enabled.
- [b]Note:[/b] You must specify the certificates to be used in the Project Settings for it to work when exported.
-
-
-
-
-
-
- Emitted when the connection to the server is closed. [code]was_clean_close[/code] will be [code]true[/code] if the connection was shutdown cleanly.
-
-
-
-
- Emitted when the connection to the server fails.
-
-
-
-
-
- Emitted when a connection with the server is established, [code]protocol[/code] will contain the sub-protocol agreed with the server.
-
-
-
-
- Emitted when a WebSocket message is received.
- [b]Note:[/b] This signal is [i]not[/i] emitted when used as high-level multiplayer peer.
-
-
-
-
-
-
- Emitted when the server requests a clean close. You should keep polling until you get a [signal connection_closed] signal to achieve the clean close. See [method WebSocketPeer.close] for more details.
-
-
-
-
-
-
diff --git a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
deleted file mode 100644
index c2046d9..0000000
--- a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
- Base class for WebSocket server and client.
-
-
- Base class for WebSocket server and client, allowing them to be used as network peer for the [MultiplayerAPI].
-
-
-
-
-
-
-
-
- Returns the [WebSocketPeer] associated to the given [code]peer_id[/code].
-
-
-
-
-
-
-
-
-
- Configures the buffer sizes for this WebSocket peer. Default values can be specified in the Project Settings under [code]network/limits[/code]. For server, values are meant per connected peer.
- The first two parameters define the size and queued packets limits of the input buffer, the last two of the output buffer.
- Buffer sizes are expressed in KiB, so [code]4 = 2^12 = 4096 bytes[/code]. All parameters will be rounded up to the nearest power of two.
- [b]Note:[/b] HTML5 exports only use the input buffer since the output one is managed by browsers.
-
-
-
-
-
-
-
- Emitted when a packet is received from a peer.
- [b]Note:[/b] This signal is only emitted when the client or server is configured to use Godot multiplayer API.
-
-
-
-
-
-
diff --git a/modules/websocket/doc_classes/WebSocketPeer.xml b/modules/websocket/doc_classes/WebSocketPeer.xml
deleted file mode 100644
index 06f2c26..0000000
--- a/modules/websocket/doc_classes/WebSocketPeer.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
- A class representing a specific WebSocket connection.
-
-
- This class represents a specific WebSocket connection, allowing you to do lower level operations with it.
- You can choose to write to the socket in binary or text mode, and you can recognize the mode used for writing by the other peer.
-
-
-
-
-
-
-
-
-
- Closes this WebSocket connection. [code]code[/code] is the status code for the closure (see RFC 6455 section 7.4 for a list of valid status codes). [code]reason[/code] is the human readable reason for closing the connection (can be any UTF-8 string that's smaller than 123 bytes).
- [b]Note:[/b] To achieve a clean close, you will need to keep polling until either [signal WebSocketClient.connection_closed] or [signal WebSocketServer.client_disconnected] is received.
- [b]Note:[/b] The HTML5 export might not support all status codes. Please refer to browser-specific documentation for more details.
-
-
-
-
-
- Returns the IP address of the connected peer.
- [b]Note:[/b] Not available in the HTML5 export.
-
-
-
-
-
- Returns the remote port of the connected peer.
- [b]Note:[/b] Not available in the HTML5 export.
-
-
-
-
-
- Returns the current amount of data in the outbound websocket buffer. [b]Note:[/b] HTML5 exports use WebSocket.bufferedAmount, while other platforms use an internal buffer.
-
-
-
-
-
- Gets the current selected write mode. See [enum WriteMode].
-
-
-
-
-
- Returns [code]true[/code] if this peer is currently connected.
-
-
-
-
-
-
- Disable Nagle's algorithm on the underling TCP socket (default). See [method StreamPeerTCP.set_no_delay] for more information.
- [b]Note:[/b] Not available in the HTML5 export.
-
-
-
-
-
-
- Sets the socket to use the given [enum WriteMode].
-
-
-
-
-
- Returns [code]true[/code] if the last received packet was sent as a text payload. See [enum WriteMode].
-
-
-
-
-
- Specifies that WebSockets messages should be transferred as text payload (only valid UTF-8 is allowed).
-
-
- Specifies that WebSockets messages should be transferred as binary payload (any byte combination is allowed).
-
-
-
diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml
deleted file mode 100644
index 37e8d2c..0000000
--- a/modules/websocket/doc_classes/WebSocketServer.xml
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
- A WebSocket server implementation.
-
-
- This class implements a WebSocket server that can also support the high-level multiplayer API.
- After starting the server ([method listen]), you will need to [method NetworkedMultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]). When clients connect, disconnect, or send data, you will receive the appropriate signal.
- [b]Note:[/b] Not available in HTML5 exports.
-
-
-
-
-
-
-
-
-
-
- Disconnects the peer identified by [code]id[/code] from the server. See [method WebSocketPeer.close] for more information.
-
-
-
-
-
-
- Returns the IP address of the given peer.
-
-
-
-
-
-
- Returns the remote port of the given peer.
-
-
-
-
-
-
- Returns [code]true[/code] if a peer with the given ID is connected.
-
-
-
-
-
- Returns [code]true[/code] if the server is actively listening on a port.
-
-
-
-
-
-
-
-
- Starts listening on the given port.
- You can specify the desired subprotocols via the "protocols" array. If the list empty (default), no sub-protocol will be requested.
- If [code]true[/code] is passed as [code]gd_mp_api[/code], the server will behave like a network peer for the [MultiplayerAPI], connections from non-Godot clients will not work, and [signal data_received] will not be emitted.
- If [code]false[/code] is passed instead (default), you must call [PacketPeer] functions ([code]put_packet[/code], [code]get_packet[/code], etc.), on the [WebSocketPeer] returned via [code]get_peer(id)[/code] to communicate with the peer with given [code]id[/code] (e.g. [code]get_peer(id).get_available_packet_count[/code]).
-
-
-
-
-
-
- Sets additional headers to be sent to clients during the HTTP handshake.
-
-
-
-
-
- Stops the server and clear its state.
-
-
-
-
-
- When not set to [code]*[/code] will restrict incoming connections to the specified IP address. Setting [code]bind_ip[/code] to [code]127.0.0.1[/code] will cause the server to listen only to the local host.
-
-
- When using SSL (see [member private_key] and [member ssl_certificate]), you can set this to a valid [X509Certificate] to be provided as additional CA chain information during the SSL handshake.
-
-
- The time in seconds before a pending client (i.e. a client that has not yet finished the HTTP handshake) is considered stale and forcefully disconnected.
-
-
- When set to a valid [CryptoKey] (along with [member ssl_certificate]) will cause the server to require SSL instead of regular TCP (i.e. the [code]wss://[/code] protocol).
-
-
- When set to a valid [X509Certificate] (along with [member private_key]) will cause the server to require SSL instead of regular TCP (i.e. the [code]wss://[/code] protocol).
-
-
-
-
-
-
-
-
- Emitted when a client requests a clean close. You should keep polling until you get a [signal client_disconnected] signal with the same [code]id[/code] to achieve the clean close. See [method WebSocketPeer.close] for more details.
-
-
-
-
-
-
- Emitted when a new client connects. "protocol" will be the sub-protocol agreed with the client.
-
-
-
-
-
-
- Emitted when a client disconnects. [code]was_clean_close[/code] will be [code]true[/code] if the connection was shutdown cleanly.
-
-
-
-
-
- Emitted when a new message is received.
- [b]Note:[/b] This signal is [i]not[/i] emitted when used as high-level multiplayer peer.
-
-
-
-
-
-
diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp
deleted file mode 100644
index abb3c09..0000000
--- a/modules/websocket/emws_client.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*************************************************************************/
-/* emws_client.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifdef JAVASCRIPT_ENABLED
-
-#include "emws_client.h"
-#include "core/io/ip.h"
-#include "core/config/project_settings.h"
-#include "emscripten.h"
-
-void EMWSClient::_esws_on_connect(void *obj, char *proto) {
- EMWSClient *client = static_cast(obj);
- client->_is_connecting = false;
- client->_on_connect(String(proto));
-}
-
-void EMWSClient::_esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string) {
- EMWSClient *client = static_cast(obj);
-
- Error err = static_cast(*client->get_peer(1))->read_msg(p_data, p_data_size, p_is_string == 1);
- if (err == OK)
- client->_on_peer_packet();
-}
-
-void EMWSClient::_esws_on_error(void *obj) {
- EMWSClient *client = static_cast(obj);
- client->_is_connecting = false;
- client->_on_error();
-}
-
-void EMWSClient::_esws_on_close(void *obj, int code, const char *reason, int was_clean) {
- EMWSClient *client = static_cast(obj);
- client->_on_close_request(code, String(reason));
- client->_is_connecting = false;
- client->disconnect_from_host();
- client->_on_disconnect(was_clean != 0);
-}
-
-Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector p_protocols, const Vector p_custom_headers) {
- if (_js_id) {
- pandemonium_js_websocket_destroy(_js_id);
- _js_id = 0;
- }
-
- String proto_string;
- for (int i = 0; i < p_protocols.size(); i++) {
- if (i != 0)
- proto_string += ",";
- proto_string += p_protocols[i];
- }
-
- String str = "ws://";
-
- if (p_custom_headers.size()) {
- WARN_PRINT_ONCE("Custom headers are not supported in in HTML5 platform.");
- }
- if (p_ssl) {
- str = "wss://";
- if (ssl_cert.is_valid()) {
- WARN_PRINT_ONCE("Custom SSL certificate is not supported in HTML5 platform.");
- }
- }
- str += p_host + ":" + itos(p_port) + p_path;
- _is_connecting = true;
-
- _js_id = pandemonium_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) {
- return FAILED;
- }
-
- static_cast[>(_peer)->set_sock(_js_id, _in_buf_size, _in_pkt_size, _out_buf_size);
-
- return OK;
-}
-
-void EMWSClient::poll() {
-}
-
-Ref EMWSClient::get_peer(int p_peer_id) const {
- return _peer;
-}
-
-NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const {
- if (_peer->is_connected_to_host()) {
- if (_is_connecting)
- return CONNECTION_CONNECTING;
- return CONNECTION_CONNECTED;
- }
-
- return CONNECTION_DISCONNECTED;
-}
-
-void EMWSClient::disconnect_from_host(int p_code, String p_reason) {
- _peer->close(p_code, p_reason);
-}
-
-IP_Address EMWSClient::get_connected_host() const {
- ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export.");
-}
-
-uint16_t EMWSClient::get_connected_port() const {
- ERR_FAIL_V_MSG(0, "Not supported in HTML5 export.");
-}
-
-int EMWSClient::get_max_packet_size() const {
- return (1 << _in_buf_size) - PROTO_SIZE;
-}
-
-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);
- _out_buf_size = nearest_shift(p_out_buffer - 1) + 10;
- return OK;
-}
-
-EMWSClient::EMWSClient() {
- _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);
- _out_buf_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_BUF) - 1) + 10;
- _is_connecting = false;
- _peer = Ref(memnew(EMWSPeer));
- _js_id = 0;
-}
-
-EMWSClient::~EMWSClient() {
- disconnect_from_host();
- _peer = Ref();
- if (_js_id) {
- pandemonium_js_websocket_destroy(_js_id);
- }
-}
-
-#endif // JAVASCRIPT_ENABLED
diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h
deleted file mode 100644
index d636490..0000000
--- a/modules/websocket/emws_client.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef EMWSCLIENT_H
-#define EMWSCLIENT_H
-/*************************************************************************/
-/* emws_client.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifdef JAVASCRIPT_ENABLED
-
-#include "core/error/error_list.h"
-#include "emws_peer.h"
-#include "websocket_client.h"
-
-class EMWSClient : public WebSocketClient {
- GDCIIMPL(EMWSClient, WebSocketClient);
-
-private:
- int _js_id;
- bool _is_connecting;
- int _in_buf_size;
- int _in_pkt_size;
- int _out_buf_size;
-
- static void _esws_on_connect(void *obj, char *proto);
- static void _esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string);
- static void _esws_on_error(void *obj);
- static void _esws_on_close(void *obj, int code, const char *reason, int was_clean);
-
-public:
- Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets);
- Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector p_protocol = Vector(), const Vector p_custom_headers = Vector());
- Ref get_peer(int p_peer_id) const;
- void disconnect_from_host(int p_code = 1000, String p_reason = "");
- IP_Address get_connected_host() const;
- uint16_t get_connected_port() const;
- virtual ConnectionStatus get_connection_status() const;
- int get_max_packet_size() const;
- virtual void poll();
- EMWSClient();
- ~EMWSClient();
-};
-
-#endif // JAVASCRIPT_ENABLED
-
-#endif // EMWSCLIENT_H
diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp
deleted file mode 100644
index aaff7c7..0000000
--- a/modules/websocket/emws_peer.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*************************************************************************/
-/* emws_peer.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifdef JAVASCRIPT_ENABLED
-
-#include "emws_peer.h"
-#include "core/io/ip.h"
-
-void EMWSPeer::set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size) {
- peer_sock = p_sock;
- _in_buffer.resize(p_in_pkt_size, p_in_buf_size);
- _packet_buffer.resize((1 << p_in_buf_size));
- _out_buf_size = p_out_buf_size;
-}
-
-void EMWSPeer::set_write_mode(WriteMode p_mode) {
- write_mode = p_mode;
-}
-
-EMWSPeer::WriteMode EMWSPeer::get_write_mode() const {
- return write_mode;
-}
-
-Error EMWSPeer::read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_string) {
- uint8_t is_string = p_is_string ? 1 : 0;
- return _in_buffer.write_packet(p_data, p_size, &is_string);
-}
-
-Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_FAIL_COND_V(_out_buf_size && ((uint64_t)pandemonium_js_websocket_buffered_amount(peer_sock) + p_buffer_size >= (1ULL << _out_buf_size)), ERR_OUT_OF_MEMORY);
-
- int is_bin = write_mode == WebSocketPeer::WRITE_MODE_BINARY ? 1 : 0;
-
- if (pandemonium_js_websocket_send(peer_sock, p_buffer, p_buffer_size, is_bin) != 0) {
- return FAILED;
- }
-
- return OK;
-};
-
-Error EMWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- if (_in_buffer.packets_left() == 0)
- return ERR_UNAVAILABLE;
-
- PoolVector::Write rw = _packet_buffer.write();
- int read = 0;
- Error err = _in_buffer.read_packet(rw.ptr(), _packet_buffer.size(), &_is_string, read);
- ERR_FAIL_COND_V(err != OK, err);
-
- *r_buffer = rw.ptr();
- r_buffer_size = read;
-
- return OK;
-};
-
-int EMWSPeer::get_available_packet_count() const {
- return _in_buffer.packets_left();
-};
-
-int EMWSPeer::get_current_outbound_buffered_amount() const {
- if (peer_sock != -1) {
- return pandemonium_js_websocket_buffered_amount(peer_sock);
- }
- return 0;
-}
-
-bool EMWSPeer::was_string_packet() const {
- return _is_string;
-};
-
-bool EMWSPeer::is_connected_to_host() const {
- return peer_sock != -1;
-};
-
-void EMWSPeer::close(int p_code, String p_reason) {
- if (peer_sock != -1) {
- pandemonium_js_websocket_close(peer_sock, p_code, p_reason.utf8().get_data());
- }
- _is_string = 0;
- _in_buffer.clear();
- peer_sock = -1;
-};
-
-IP_Address EMWSPeer::get_connected_host() const {
- ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export.");
-};
-
-uint16_t EMWSPeer::get_connected_port() const {
- ERR_FAIL_V_MSG(0, "Not supported in HTML5 export.");
-};
-
-void EMWSPeer::set_no_delay(bool p_enabled) {
- ERR_FAIL_MSG("'set_no_delay' is not supported in HTML5 export.");
-}
-
-EMWSPeer::EMWSPeer() {
- _out_buf_size = 0;
- peer_sock = -1;
- write_mode = WRITE_MODE_BINARY;
- close();
-};
-
-EMWSPeer::~EMWSPeer() {
- close();
-};
-
-#endif // JAVASCRIPT_ENABLED
diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h
deleted file mode 100644
index 2ac07f5..0000000
--- a/modules/websocket/emws_peer.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef EMWSPEER_H
-#define EMWSPEER_H
-/*************************************************************************/
-/* emws_peer.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifdef JAVASCRIPT_ENABLED
-
-#include "core/error/error_list.h"
-#include "core/io/packet_peer.h"
-#include "core/containers/ring_buffer.h"
-#include "emscripten.h"
-#include "packet_buffer.h"
-#include "websocket_peer.h"
-
-extern "C" {
-typedef void (*WSOnOpen)(void *p_ref, char *p_protocol);
-typedef void (*WSOnMessage)(void *p_ref, const uint8_t *p_buf, int p_buf_len, int p_is_string);
-typedef void (*WSOnClose)(void *p_ref, int p_code, const char *p_reason, int p_is_clean);
-typedef void (*WSOnError)(void *p_ref);
-
-extern int pandemonium_js_websocket_create(void *p_ref, const char *p_url, const char *p_proto, WSOnOpen p_on_open, WSOnMessage p_on_message, WSOnError p_on_error, WSOnClose p_on_close);
-extern int pandemonium_js_websocket_send(int p_id, const uint8_t *p_buf, int p_buf_len, int p_raw);
-extern int pandemonium_js_websocket_buffered_amount(int p_id);
-extern void pandemonium_js_websocket_close(int p_id, int p_code, const char *p_reason);
-extern void pandemonium_js_websocket_destroy(int p_id);
-}
-
-class EMWSPeer : public WebSocketPeer {
- GDCIIMPL(EMWSPeer, WebSocketPeer);
-
-private:
- int peer_sock;
- WriteMode write_mode;
-
- PoolVector _packet_buffer;
- PacketBuffer _in_buffer;
- uint8_t _is_string;
- int _out_buf_size;
-
-public:
- Error read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_string);
- void set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size);
- virtual int get_available_packet_count() const;
- virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size);
- virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
- virtual int get_max_packet_size() const { return _packet_buffer.size(); };
- virtual int get_current_outbound_buffered_amount() const;
-
- virtual void close(int p_code = 1000, String p_reason = "");
- virtual bool is_connected_to_host() const;
- virtual IP_Address get_connected_host() const;
- virtual uint16_t get_connected_port() const;
-
- virtual WriteMode get_write_mode() const;
- virtual void set_write_mode(WriteMode p_mode);
- virtual bool was_string_packet() const;
- virtual void set_no_delay(bool p_enabled);
-
- EMWSPeer();
- ~EMWSPeer();
-};
-
-#endif // JAVASCRIPT_ENABLED
-
-#endif // LSWPEER_H
diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp
deleted file mode 100644
index 9422bf2..0000000
--- a/modules/websocket/emws_server.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*************************************************************************/
-/* emws_server.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifdef JAVASCRIPT_ENABLED
-
-#include "emws_server.h"
-#include "core/os/os.h"
-
-void EMWSServer::set_extra_headers(const Vector &p_headers) {
-}
-
-Error EMWSServer::listen(int p_port, Vector p_protocols, bool gd_mp_api) {
- return FAILED;
-}
-
-bool EMWSServer::is_listening() const {
- return false;
-}
-
-void EMWSServer::stop() {
-}
-
-bool EMWSServer::has_peer(int p_id) const {
- return false;
-}
-
-Ref EMWSServer::get_peer(int p_id) const {
- return NULL;
-}
-
-PoolVector EMWSServer::get_protocols() const {
- PoolVector out;
-
- return out;
-}
-
-IP_Address EMWSServer::get_peer_address(int p_peer_id) const {
- return IP_Address();
-}
-
-int EMWSServer::get_peer_port(int p_peer_id) const {
- return 0;
-}
-
-void EMWSServer::disconnect_peer(int p_peer_id, int p_code, String p_reason) {
-}
-
-void EMWSServer::poll() {
-}
-
-int EMWSServer::get_max_packet_size() const {
- return 0;
-}
-
-Error EMWSServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) {
- return OK;
-}
-
-EMWSServer::EMWSServer() {
-}
-
-EMWSServer::~EMWSServer() {
-}
-
-#endif // JAVASCRIPT_ENABLED
diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h
deleted file mode 100644
index c892cd8..0000000
--- a/modules/websocket/emws_server.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef EMWSSERVER_H
-#define EMWSSERVER_H
-/*************************************************************************/
-/* emws_server.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifdef JAVASCRIPT_ENABLED
-
-#include "core/object/reference.h"
-#include "emws_peer.h"
-#include "websocket_server.h"
-
-class EMWSServer : public WebSocketServer {
- GDCIIMPL(EMWSServer, WebSocketServer);
-
-public:
- Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets);
- void set_extra_headers(const Vector &p_headers);
- Error listen(int p_port, Vector p_protocols = Vector(), bool gd_mp_api = false);
- void stop();
- bool is_listening() const;
- bool has_peer(int p_id) const;
- Ref get_peer(int p_id) const;
- IP_Address get_peer_address(int p_peer_id) const;
- int get_peer_port(int p_peer_id) const;
- void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = "");
- int get_max_packet_size() const;
- virtual void poll();
- virtual PoolVector get_protocols() const;
-
- EMWSServer();
- ~EMWSServer();
-};
-
-#endif
-
-#endif // LWSSERVER_H
diff --git a/modules/websocket/library_pandemonium_websocket.js b/modules/websocket/library_pandemonium_websocket.js
deleted file mode 100644
index c1207c2..0000000
--- a/modules/websocket/library_pandemonium_websocket.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/*************************************************************************/
-/* library_pandemonium_websocket.js */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-const PandemoniumWebSocket = {
- // Our socket implementation that forwards events to C++.
- $PandemoniumWebSocket__deps: ['$IDHandler', '$PandemoniumRuntime'],
- $PandemoniumWebSocket: {
- // Connection opened, report selected protocol
- _onopen: function(p_id, callback, event) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
- return; // Pandemonium object is gone.
- }
- const c_str = PandemoniumRuntime.allocString(ref.protocol);
- callback(c_str);
- PandemoniumRuntime.free(c_str);
- },
-
- // Message received, report content and type (UTF8 vs binary)
- _onmessage: function(p_id, callback, event) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
- return; // Pandemonium object is gone.
- }
- let buffer;
- let is_string = 0;
- if (event.data instanceof ArrayBuffer) {
- buffer = new Uint8Array(event.data);
- } else if (event.data instanceof Blob) {
- PandemoniumRuntime.error('Blob type not supported');
- return;
- } else if (typeof event.data === 'string') {
- is_string = 1;
- const enc = new TextEncoder('utf-8');
- buffer = new Uint8Array(enc.encode(event.data));
- } else {
- PandemoniumRuntime.error('Unknown message type');
- return;
- }
- const len = buffer.length * buffer.BYTES_PER_ELEMENT;
- const out = PandemoniumRuntime.malloc(len);
- HEAPU8.set(buffer, out);
- callback(out, len, is_string);
- PandemoniumRuntime.free(out);
- },
-
- // An error happened, 'onclose' will be called after this.
- _onerror: function(p_id, callback, event) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
- return; // Pandemonium object is gone.
- }
- callback();
- },
-
- // Connection is closed, this is always fired. Report close code, reason, and clean status.
- _onclose: function(p_id, callback, event) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
- return; // Pandemonium object is gone.
- }
- const c_str = PandemoniumRuntime.allocString(event.reason);
- callback(event.code, c_str, event.wasClean ? 1 : 0);
- PandemoniumRuntime.free(c_str);
- },
-
- // Send a message
- send: function(p_id, p_data) {
- const ref = IDHandler.get(p_id);
- if (!ref || ref.readyState !== ref.OPEN) {
- return 1; // Pandemonium object is gone or socket is not in a ready state.
- }
- ref.send(p_data);
- return 0;
- },
-
- // Get current bufferedAmount
- bufferedAmount: function(p_id) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
- return 0; // Pandemonium object is gone.
- }
- return ref.bufferedAmount;
- },
-
- create: function(socket, p_on_open, p_on_message, p_on_error, p_on_close) {
- const id = IDHandler.add(socket);
- socket.onopen = PandemoniumWebSocket._onopen.bind(null, id, p_on_open);
- socket.onmessage = PandemoniumWebSocket._onmessage.bind(null, id, p_on_message);
- socket.onerror = PandemoniumWebSocket._onerror.bind(null, id, p_on_error);
- socket.onclose = PandemoniumWebSocket._onclose.bind(null, id, p_on_close);
- return id;
- },
-
- // Closes the JavaScript WebSocket (if not already closing) associated to a given C++ object.
- close: function(p_id, p_code, p_reason) {
- const ref = IDHandler.get(p_id);
- if (ref && ref.readyState < ref.CLOSING) {
- const code = p_code;
- const reason = PandemoniumRuntime.parseString(p_reason);
- ref.close(code, reason);
- }
- },
-
- // Deletes the reference to a C++ object (closing any connected socket if necessary).
- destroy: function(p_id) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
- return;
- }
- PandemoniumWebSocket.close(p_id, 3001, '');
- IDHandler.remove(p_id);
- ref.onopen = null;
- ref.onmessage = null;
- ref.onerror = null;
- ref.onclose = null;
- },
- },
-
- pandemonium_js_websocket_create__sig: 'iiiiiiii',
- pandemonium_js_websocket_create: function(p_ref, p_url, p_proto, p_on_open, p_on_message, p_on_error, p_on_close) {
- const on_open = PandemoniumRuntime.get_func(p_on_open).bind(null, p_ref);
- const on_message = PandemoniumRuntime.get_func(p_on_message).bind(null, p_ref);
- const on_error = PandemoniumRuntime.get_func(p_on_error).bind(null, p_ref);
- const on_close = PandemoniumRuntime.get_func(p_on_close).bind(null, p_ref);
- const url = PandemoniumRuntime.parseString(p_url);
- const protos = PandemoniumRuntime.parseString(p_proto);
- let socket = null;
- try {
- if (protos) {
- socket = new WebSocket(url, protos.split(','));
- } else {
- socket = new WebSocket(url);
- }
- } catch (e) {
- return 0;
- }
- socket.binaryType = 'arraybuffer';
- return PandemoniumWebSocket.create(socket, on_open, on_message, on_error, on_close);
- },
-
- pandemonium_js_websocket_send__sig: 'iiiii',
- pandemonium_js_websocket_send: function(p_id, p_buf, p_buf_len, p_raw) {
- const bytes_array = new Uint8Array(p_buf_len);
- let i = 0;
- for (i = 0; i < p_buf_len; i++) {
- bytes_array[i] = PandemoniumRuntime.getHeapValue(p_buf + i, 'i8');
- }
- let out = bytes_array.buffer;
- if (!p_raw) {
- out = new TextDecoder('utf-8').decode(bytes_array);
- }
- return PandemoniumWebSocket.send(p_id, out);
- },
-
- pandemonium_js_websocket_buffered_amount__sig: 'ii',
- pandemonium_js_websocket_buffered_amount: function(p_id) {
- return PandemoniumWebSocket.bufferedAmount(p_id);
- },
-
- pandemonium_js_websocket_close__sig: 'viii',
- pandemonium_js_websocket_close: function(p_id, p_code, p_reason) {
- const code = p_code;
- const reason = PandemoniumRuntime.parseString(p_reason);
- PandemoniumWebSocket.close(p_id, code, reason);
- },
-
- pandemonium_js_websocket_destroy__sig: 'vi',
- pandemonium_js_websocket_destroy: function(p_id) {
- PandemoniumWebSocket.destroy(p_id);
- },
-};
-
-autoAddDeps(PandemoniumWebSocket, '$PandemoniumWebSocket');
-mergeInto(LibraryManager.library, PandemoniumWebSocket);
diff --git a/modules/websocket/packet_buffer.h b/modules/websocket/packet_buffer.h
deleted file mode 100644
index 654c17f..0000000
--- a/modules/websocket/packet_buffer.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef PACKET_BUFFER_H
-#define PACKET_BUFFER_H
-/*************************************************************************/
-/* packet_buffer.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "core/containers/ring_buffer.h"
-
-template
-class PacketBuffer {
-private:
- typedef struct {
- uint32_t size;
- T info;
- } _Packet;
-
- RingBuffer<_Packet> _packets;
- RingBuffer _payload;
-
-public:
- Error write_packet(const uint8_t *p_payload, uint32_t p_size, const T *p_info) {
-#ifdef TOOLS_ENABLED
- // Verbose buffer warnings
- if (p_payload && _payload.space_left() < (int32_t)p_size) {
- ERR_PRINT("Buffer payload full! Dropping data.");
- ERR_FAIL_V(ERR_OUT_OF_MEMORY);
- }
- if (p_info && _packets.space_left() < 1) {
- ERR_PRINT("Too many packets in queue! Dropping data.");
- ERR_FAIL_V(ERR_OUT_OF_MEMORY);
- }
-#else
- ERR_FAIL_COND_V(p_payload && (uint32_t)_payload.space_left() < p_size, ERR_OUT_OF_MEMORY);
- ERR_FAIL_COND_V(p_info && _packets.space_left() < 1, ERR_OUT_OF_MEMORY);
-#endif
-
- // If p_info is NULL, only the payload is written
- if (p_info) {
- _Packet p;
- p.size = p_size;
- memcpy(&p.info, p_info, sizeof(T));
- _packets.write(p);
- }
-
- // If p_payload is NULL, only the packet information is written.
- if (p_payload) {
- _payload.write((const uint8_t *)p_payload, p_size);
- }
-
- return OK;
- }
-
- Error read_packet(uint8_t *r_payload, int p_bytes, T *r_info, int &r_read) {
- ERR_FAIL_COND_V(_packets.data_left() < 1, ERR_UNAVAILABLE);
- _Packet p;
- _packets.read(&p, 1);
- ERR_FAIL_COND_V(_payload.data_left() < (int)p.size, ERR_BUG);
- ERR_FAIL_COND_V(p_bytes < (int)p.size, ERR_OUT_OF_MEMORY);
-
- r_read = p.size;
- memcpy(r_info, &p.info, sizeof(T));
- _payload.read(r_payload, p.size);
- return OK;
- }
-
- void discard_payload(int p_size) {
- _packets.decrease_write(p_size);
- }
-
- void resize(int p_pkt_shift, int p_buf_shift) {
- _packets.resize(p_pkt_shift);
- _payload.resize(p_buf_shift);
- }
-
- int packets_left() const {
- return _packets.data_left();
- }
-
- void clear() {
- _payload.resize(0);
- _packets.resize(0);
- }
-
- PacketBuffer() {
- clear();
- }
-
- ~PacketBuffer() {
- clear();
- }
-};
-
-#endif // PACKET_BUFFER_H
diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp
deleted file mode 100644
index 4261583..0000000
--- a/modules/websocket/register_types.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*************************************************************************/
-/* register_types.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "register_types.h"
-#include "core/config/project_settings.h"
-#include "core/error/error_macros.h"
-#ifdef JAVASCRIPT_ENABLED
-#include "emscripten.h"
-#include "emws_client.h"
-#include "emws_peer.h"
-#include "emws_server.h"
-#else
-#include "wsl_client.h"
-#include "wsl_server.h"
-#endif
-
-void register_websocket_types(ModuleRegistrationLevel p_level) {
- if (p_level == MODULE_REGISTRATION_LEVEL_DRIVER) {
-#define _SET_HINT(NAME, _VAL_, _MAX_) \
- GLOBAL_DEF(NAME, _VAL_); \
- ProjectSettings::get_singleton()->set_custom_property_info(NAME, PropertyInfo(Variant::INT, NAME, PROPERTY_HINT_RANGE, "2," #_MAX_ ",1,or_greater"));
-
- // Client buffers project settings
- _SET_HINT(WSC_IN_BUF, 64, 4096);
- _SET_HINT(WSC_IN_PKT, 1024, 16384);
- _SET_HINT(WSC_OUT_BUF, 64, 4096);
- _SET_HINT(WSC_OUT_PKT, 1024, 16384);
-
- // Server buffers project settings
- _SET_HINT(WSS_IN_BUF, 64, 4096);
- _SET_HINT(WSS_IN_PKT, 1024, 16384);
- _SET_HINT(WSS_OUT_BUF, 64, 4096);
- _SET_HINT(WSS_OUT_PKT, 1024, 16384);
-
-#ifdef JAVASCRIPT_ENABLED
- EMWSPeer::make_default();
- EMWSClient::make_default();
- EMWSServer::make_default();
-#else
- WSLPeer::make_default();
- WSLClient::make_default();
- WSLServer::make_default();
-#endif
- }
-
- if (p_level == MODULE_REGISTRATION_LEVEL_SCENE) {
- ClassDB::register_virtual_class();
- ClassDB::register_custom_instance_class();
- ClassDB::register_custom_instance_class();
- ClassDB::register_custom_instance_class();
- }
-}
-
-void unregister_websocket_types(ModuleRegistrationLevel p_level) {}
diff --git a/modules/websocket/register_types.h b/modules/websocket/register_types.h
deleted file mode 100644
index 1472dcc..0000000
--- a/modules/websocket/register_types.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef WEBSOCKET_REGISTER_TYPES_H
-#define WEBSOCKET_REGISTER_TYPES_H
-/*************************************************************************/
-/* register_types.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "modules/register_module_types.h"
-
-void register_websocket_types(ModuleRegistrationLevel p_level);
-void unregister_websocket_types(ModuleRegistrationLevel p_level);
-
-#endif // WEBSOCKET_REGISTER_TYPES_H
diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp
deleted file mode 100644
index 3efd8c1..0000000
--- a/modules/websocket/websocket_client.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*************************************************************************/
-/* websocket_client.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "websocket_client.h"
-
-GDCINULL(WebSocketClient);
-
-WebSocketClient::WebSocketClient() {
- verify_ssl = true;
-}
-
-WebSocketClient::~WebSocketClient() {
-}
-
-Error WebSocketClient::connect_to_url(String p_url, const Vector p_protocols, bool gd_mp_api, const Vector p_custom_headers) {
- _is_multiplayer = gd_mp_api;
-
- String host = p_url;
- String path;
- String scheme;
- int port = 0;
- Error err = p_url.parse_url(scheme, host, port, path);
- ERR_FAIL_COND_V_MSG(err != OK, err, "Invalid URL: " + p_url);
-
- bool ssl = false;
- if (scheme == "wss://") {
- ssl = true;
- }
- if (port == 0) {
- port = ssl ? 443 : 80;
- }
- if (path.empty()) {
- path = "/";
- }
- return connect_to_host(host, path, port, ssl, p_protocols, p_custom_headers);
-}
-
-void WebSocketClient::set_verify_ssl_enabled(bool p_verify_ssl) {
- verify_ssl = p_verify_ssl;
-}
-
-bool WebSocketClient::is_verify_ssl_enabled() const {
- return verify_ssl;
-}
-
-Ref WebSocketClient::get_trusted_ssl_certificate() const {
- return ssl_cert;
-}
-
-void WebSocketClient::set_trusted_ssl_certificate(Ref p_cert) {
- ERR_FAIL_COND(get_connection_status() != CONNECTION_DISCONNECTED);
- ssl_cert = p_cert;
-}
-
-bool WebSocketClient::is_server() const {
- return false;
-}
-
-void WebSocketClient::_on_peer_packet() {
- if (_is_multiplayer) {
- _process_multiplayer(get_peer(1), 1);
- } else {
- emit_signal("data_received");
- }
-}
-
-void WebSocketClient::_on_connect(String p_protocol) {
- if (_is_multiplayer) {
- // need to wait for ID confirmation...
- } else {
- emit_signal("connection_established", p_protocol);
- }
-}
-
-void WebSocketClient::_on_close_request(int p_code, String p_reason) {
- emit_signal("server_close_request", p_code, p_reason);
-}
-
-void WebSocketClient::_on_disconnect(bool p_was_clean) {
- if (_is_multiplayer) {
- emit_signal("connection_failed");
- } else {
- emit_signal("connection_closed", p_was_clean);
- }
-}
-
-void WebSocketClient::_on_error() {
- if (_is_multiplayer) {
- emit_signal("connection_failed");
- } else {
- emit_signal("connection_error");
- }
-}
-
-void WebSocketClient::_bind_methods() {
- ClassDB::bind_method(D_METHOD("connect_to_url", "url", "protocols", "gd_mp_api", "custom_headers"), &WebSocketClient::connect_to_url, DEFVAL(Vector()), DEFVAL(false), DEFVAL(Vector()));
- ClassDB::bind_method(D_METHOD("disconnect_from_host", "code", "reason"), &WebSocketClient::disconnect_from_host, DEFVAL(1000), DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_connected_host"), &WebSocketClient::get_connected_host);
- ClassDB::bind_method(D_METHOD("get_connected_port"), &WebSocketClient::get_connected_port);
- ClassDB::bind_method(D_METHOD("set_verify_ssl_enabled", "enabled"), &WebSocketClient::set_verify_ssl_enabled);
- ClassDB::bind_method(D_METHOD("is_verify_ssl_enabled"), &WebSocketClient::is_verify_ssl_enabled);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "verify_ssl", PROPERTY_HINT_NONE, "", 0), "set_verify_ssl_enabled", "is_verify_ssl_enabled");
-
- ClassDB::bind_method(D_METHOD("get_trusted_ssl_certificate"), &WebSocketClient::get_trusted_ssl_certificate);
- ClassDB::bind_method(D_METHOD("set_trusted_ssl_certificate", "certificate"), &WebSocketClient::set_trusted_ssl_certificate);
-
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trusted_ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_trusted_ssl_certificate", "get_trusted_ssl_certificate");
-
- ADD_SIGNAL(MethodInfo("data_received"));
- ADD_SIGNAL(MethodInfo("connection_established", PropertyInfo(Variant::STRING, "protocol")));
- ADD_SIGNAL(MethodInfo("server_close_request", PropertyInfo(Variant::INT, "code"), PropertyInfo(Variant::STRING, "reason")));
- ADD_SIGNAL(MethodInfo("connection_closed", PropertyInfo(Variant::BOOL, "was_clean_close")));
- ADD_SIGNAL(MethodInfo("connection_error"));
-}
diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h
deleted file mode 100644
index 1a92ee9..0000000
--- a/modules/websocket/websocket_client.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef WEBSOCKET_CLIENT_H
-#define WEBSOCKET_CLIENT_H
-/*************************************************************************/
-/* websocket_client.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "core/crypto/crypto.h"
-#include "core/error/error_list.h"
-#include "websocket_multiplayer_peer.h"
-#include "websocket_peer.h"
-
-class WebSocketClient : public WebSocketMultiplayerPeer {
- GDCLASS(WebSocketClient, WebSocketMultiplayerPeer);
- GDCICLASS(WebSocketClient);
-
-protected:
- Ref _peer;
- bool verify_ssl;
- Ref ssl_cert;
-
- static void _bind_methods();
-
-public:
- Error connect_to_url(String p_url, const Vector p_protocols = Vector(), bool gd_mp_api = false, const Vector p_custom_headers = Vector());
-
- void set_verify_ssl_enabled(bool p_verify_ssl);
- bool is_verify_ssl_enabled() const;
- Ref get_trusted_ssl_certificate() const;
- void set_trusted_ssl_certificate(Ref p_cert);
-
- virtual void poll() = 0;
- virtual Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector p_protocol = Vector(), const Vector p_custom_headers = Vector()) = 0;
- virtual void disconnect_from_host(int p_code = 1000, String p_reason = "") = 0;
- virtual IP_Address get_connected_host() const = 0;
- virtual uint16_t get_connected_port() const = 0;
-
- virtual bool is_server() const;
- virtual ConnectionStatus get_connection_status() const = 0;
-
- void _on_peer_packet();
- void _on_connect(String p_protocol);
- void _on_close_request(int p_code, String p_reason);
- void _on_disconnect(bool p_was_clean);
- void _on_error();
-
- virtual Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) = 0;
-
- WebSocketClient();
- ~WebSocketClient();
-};
-
-#endif // WEBSOCKET_CLIENT_H
diff --git a/modules/websocket/websocket_macros.h b/modules/websocket/websocket_macros.h
deleted file mode 100644
index 8528d78..0000000
--- a/modules/websocket/websocket_macros.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef WEBSOCKETMACTOS_H
-#define WEBSOCKETMACTOS_H
-/*************************************************************************/
-/* websocket_macros.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#define WSC_IN_BUF "network/limits/websocket_client/max_in_buffer_kb"
-#define WSC_IN_PKT "network/limits/websocket_client/max_in_packets"
-#define WSC_OUT_BUF "network/limits/websocket_client/max_out_buffer_kb"
-#define WSC_OUT_PKT "network/limits/websocket_client/max_out_packets"
-
-#define WSS_IN_BUF "network/limits/websocket_server/max_in_buffer_kb"
-#define WSS_IN_PKT "network/limits/websocket_server/max_in_packets"
-#define WSS_OUT_BUF "network/limits/websocket_server/max_out_buffer_kb"
-#define WSS_OUT_PKT "network/limits/websocket_server/max_out_packets"
-
-#define GDCICLASS(CNAME) \
-public: \
- static CNAME *(*_create)(); \
- \
- static Ref create_ref() { \
- if (!_create) \
- return Ref(); \
- return Ref(_create()); \
- } \
- \
- static CNAME *create() { \
- if (!_create) \
- return NULL; \
- return _create(); \
- } \
- \
-protected:
-
-#define GDCINULL(CNAME) \
- CNAME *(*CNAME::_create)() = NULL;
-
-#define GDCIIMPL(IMPNAME, CNAME) \
-public: \
- static CNAME *_create() { return memnew(IMPNAME); } \
- static void make_default() { CNAME::_create = IMPNAME::_create; } \
- \
-protected:
-
-#endif // WEBSOCKETMACTOS_H
diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp
deleted file mode 100644
index 6ce4c1c..0000000
--- a/modules/websocket/websocket_multiplayer_peer.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*************************************************************************/
-/* websocket_multiplayer_peer.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "websocket_multiplayer_peer.h"
-
-#include "core/os/os.h"
-
-WebSocketMultiplayerPeer::WebSocketMultiplayerPeer() {
- _is_multiplayer = false;
- _peer_id = 0;
- _target_peer = 0;
- _refusing = false;
-
- _current_packet.source = 0;
- _current_packet.destination = 0;
- _current_packet.size = 0;
- _current_packet.data = nullptr;
-}
-
-WebSocketMultiplayerPeer::~WebSocketMultiplayerPeer() {
- _clear();
-}
-
-int WebSocketMultiplayerPeer::_gen_unique_id() const {
- uint32_t hash = 0;
-
- while (hash == 0 || hash == 1) {
- hash = hash_djb2_one_32(
- (uint32_t)OS::get_singleton()->get_ticks_usec());
- hash = hash_djb2_one_32(
- (uint32_t)OS::get_singleton()->get_unix_time(), hash);
- hash = hash_djb2_one_32(
- (uint32_t)OS::get_singleton()->get_data_path().hash64(), hash);
- hash = hash_djb2_one_32(
- (uint32_t)((uint64_t)this), hash); //rely on aslr heap
- hash = hash_djb2_one_32(
- (uint32_t)((uint64_t)&hash), hash); //rely on aslr stack
- hash = hash & 0x7FFFFFFF; // make it compatible with unsigned, since negatie id is used for exclusion
- }
-
- return hash;
-}
-void WebSocketMultiplayerPeer::_clear() {
- _peer_map.clear();
- if (_current_packet.data != nullptr) {
- memfree(_current_packet.data);
- }
-
- for (List::Element *E = _incoming_packets.front(); E; E = E->next()) {
- memfree(E->get().data);
- E->get().data = nullptr;
- }
-
- _incoming_packets.clear();
-}
-
-void WebSocketMultiplayerPeer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_buffers", "input_buffer_size_kb", "input_max_packets", "output_buffer_size_kb", "output_max_packets"), &WebSocketMultiplayerPeer::set_buffers);
- ClassDB::bind_method(D_METHOD("get_peer", "peer_id"), &WebSocketMultiplayerPeer::get_peer);
-
- ADD_SIGNAL(MethodInfo("peer_packet", PropertyInfo(Variant::INT, "peer_source")));
-}
-
-//
-// PacketPeer
-//
-int WebSocketMultiplayerPeer::get_available_packet_count() const {
- ERR_FAIL_COND_V_MSG(!_is_multiplayer, 0, "Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI.");
-
- return _incoming_packets.size();
-}
-
-Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).get_packet/var to communicate with peers when not using the MultiplayerAPI.");
-
- r_buffer_size = 0;
-
- if (_current_packet.data != nullptr) {
- memfree(_current_packet.data);
- _current_packet.data = nullptr;
- }
-
- ERR_FAIL_COND_V(_incoming_packets.size() == 0, ERR_UNAVAILABLE);
-
- _current_packet = _incoming_packets.front()->get();
- _incoming_packets.pop_front();
-
- *r_buffer = _current_packet.data;
- r_buffer_size = _current_packet.size;
-
- return OK;
-}
-
-Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).put_packet/var to communicate with peers when not using the MultiplayerAPI.");
-
- PoolVector buffer = _make_pkt(SYS_NONE, get_unique_id(), _target_peer, p_buffer, p_buffer_size);
-
- if (is_server()) {
- return _server_relay(1, _target_peer, &(buffer.read()[0]), buffer.size());
- } else {
- return get_peer(1)->put_packet(&(buffer.read()[0]), buffer.size());
- }
-}
-
-//
-// NetworkedMultiplayerPeer
-//
-void WebSocketMultiplayerPeer::set_transfer_mode(TransferMode p_mode) {
- // Websocket uses TCP, reliable
-}
-
-NetworkedMultiplayerPeer::TransferMode WebSocketMultiplayerPeer::get_transfer_mode() const {
- // Websocket uses TCP, reliable
- return TRANSFER_MODE_RELIABLE;
-}
-
-void WebSocketMultiplayerPeer::set_target_peer(int p_target_peer) {
- _target_peer = p_target_peer;
-}
-
-int WebSocketMultiplayerPeer::get_packet_peer() const {
- ERR_FAIL_COND_V_MSG(!_is_multiplayer, 1, "This function is not available when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(_incoming_packets.size() == 0, 1);
-
- return _incoming_packets.front()->get().source;
-}
-
-int WebSocketMultiplayerPeer::get_unique_id() const {
- return _peer_id;
-}
-
-void WebSocketMultiplayerPeer::set_refuse_new_connections(bool p_enable) {
- _refusing = p_enable;
-}
-
-bool WebSocketMultiplayerPeer::is_refusing_new_connections() const {
- return _refusing;
-}
-
-void WebSocketMultiplayerPeer::_send_sys(Ref p_peer, uint8_t p_type, int32_t p_peer_id) {
- ERR_FAIL_COND(!p_peer.is_valid());
- ERR_FAIL_COND(!p_peer->is_connected_to_host());
-
- PoolVector message = _make_pkt(p_type, 1, 0, (uint8_t *)&p_peer_id, 4);
- p_peer->put_packet(&(message.read()[0]), message.size());
-}
-
-PoolVector WebSocketMultiplayerPeer::_make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size) {
- PoolVector out;
- out.resize(PROTO_SIZE + p_data_size);
-
- PoolVector::Write w = out.write();
- memcpy(&w[0], &p_type, 1);
- memcpy(&w[1], &p_from, 4);
- memcpy(&w[5], &p_to, 4);
- memcpy(&w[PROTO_SIZE], p_data, p_data_size);
-
- return out;
-}
-
-void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) {
- // First of all, confirm the ID!
- _send_sys(get_peer(p_peer_id), SYS_ID, p_peer_id);
-
- // Then send the server peer (which will trigger connection_succeded in client)
- _send_sys(get_peer(p_peer_id), SYS_ADD, 1);
-
- for (RBMap>::Element *E = _peer_map.front(); E; E = E->next()) {
- int32_t id = E->key();
- if (p_peer_id == id) {
- continue; // Skip the newwly added peer (already confirmed)
- }
-
- // Send new peer to others
- _send_sys(get_peer(id), SYS_ADD, p_peer_id);
- // Send others to new peer
- _send_sys(get_peer(p_peer_id), SYS_ADD, id);
- }
-}
-
-void WebSocketMultiplayerPeer::_send_del(int32_t p_peer_id) {
- for (RBMap>::Element *E = _peer_map.front(); E; E = E->next()) {
- int32_t id = E->key();
- if (p_peer_id != id) {
- _send_sys(get_peer(id), SYS_DEL, p_peer_id);
- }
- }
-}
-
-void WebSocketMultiplayerPeer::_store_pkt(int32_t p_source, int32_t p_dest, const uint8_t *p_data, uint32_t p_data_size) {
- Packet packet;
- packet.data = (uint8_t *)memalloc(p_data_size);
- packet.size = p_data_size;
- packet.source = p_source;
- packet.destination = p_dest;
- memcpy(packet.data, &p_data[PROTO_SIZE], p_data_size);
- _incoming_packets.push_back(packet);
- emit_signal("peer_packet", p_source);
-}
-
-Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, const uint8_t *p_buffer, uint32_t p_buffer_size) {
- if (p_to == 1) {
- return OK; // Will not send to self
-
- } else if (p_to == 0) {
- for (RBMap>::Element *E = _peer_map.front(); E; E = E->next()) {
- if (E->key() != p_from) {
- E->get()->put_packet(p_buffer, p_buffer_size);
- }
- }
- return OK; // Sent to all but sender
-
- } else if (p_to < 0) {
- for (RBMap>::Element *E = _peer_map.front(); E; E = E->next()) {
- if (E->key() != p_from && E->key() != -p_to) {
- E->get()->put_packet(p_buffer, p_buffer_size);
- }
- }
- return OK; // Sent to all but sender and excluded
-
- } else {
- ERR_FAIL_COND_V(p_to == p_from, FAILED);
-
- Ref peer_to = get_peer(p_to);
- ERR_FAIL_COND_V(peer_to.is_null(), FAILED);
-
- return peer_to->put_packet(p_buffer, p_buffer_size); // Sending to specific peer
- }
-}
-
-void WebSocketMultiplayerPeer::_process_multiplayer(Ref p_peer, uint32_t p_peer_id) {
- ERR_FAIL_COND(!p_peer.is_valid());
-
- const uint8_t *in_buffer;
- int size = 0;
- int data_size = 0;
-
- Error err = p_peer->get_packet(&in_buffer, size);
-
- ERR_FAIL_COND(err != OK);
- ERR_FAIL_COND(size < PROTO_SIZE);
-
- data_size = size - PROTO_SIZE;
-
- uint8_t type = 0;
- uint32_t from = 0;
- int32_t to = 0;
- memcpy(&type, in_buffer, 1);
- memcpy(&from, &in_buffer[1], 4);
- memcpy(&to, &in_buffer[5], 4);
-
- if (is_server()) { // Server can resend
-
- ERR_FAIL_COND(type != SYS_NONE); // Only server sends sys messages
- ERR_FAIL_COND(from != p_peer_id); // Someone is cheating
-
- if (to == 1) { // This is for the server
-
- _store_pkt(from, to, in_buffer, data_size);
-
- } else if (to == 0) {
- // Broadcast, for us too
- _store_pkt(from, to, in_buffer, data_size);
-
- } else if (to < 0) {
- // All but one, for us if not excluded
- if (_peer_id != -(int32_t)p_peer_id) {
- _store_pkt(from, to, in_buffer, data_size);
- }
- }
- // Relay if needed (i.e. "to" includes a peer that is not the server)
- _server_relay(from, to, in_buffer, size);
-
- } else {
- if (type == SYS_NONE) { // Payload message
-
- _store_pkt(from, to, in_buffer, data_size);
- return;
- }
-
- // System message
- ERR_FAIL_COND(data_size < 4);
- int id = 0;
- memcpy(&id, &in_buffer[PROTO_SIZE], 4);
-
- switch (type) {
- case SYS_ADD: // Add peer
- _peer_map[id] = Ref();
- emit_signal("peer_connected", id);
- if (id == 1) { // We just connected to the server
- emit_signal("connection_succeeded");
- }
- break;
-
- case SYS_DEL: // Remove peer
- _peer_map.erase(id);
- emit_signal("peer_disconnected", id);
- break;
- case SYS_ID: // Helo, server assigned ID
- _peer_id = id;
- break;
- default:
- ERR_FAIL_MSG("Invalid multiplayer message.");
- break;
- }
- }
-}
diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h
deleted file mode 100644
index 36a1206..0000000
--- a/modules/websocket/websocket_multiplayer_peer.h
+++ /dev/null
@@ -1,108 +0,0 @@
-#ifndef WEBSOCKET_MULTIPLAYER_PEER_H
-#define WEBSOCKET_MULTIPLAYER_PEER_H
-/*************************************************************************/
-/* websocket_multiplayer_peer.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "core/error/error_list.h"
-#include "core/io/networked_multiplayer_peer.h"
-#include "core/containers/list.h"
-#include "websocket_peer.h"
-
-class WebSocketMultiplayerPeer : public NetworkedMultiplayerPeer {
- GDCLASS(WebSocketMultiplayerPeer, NetworkedMultiplayerPeer);
-
-private:
- PoolVector _make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size);
- void _store_pkt(int32_t p_source, int32_t p_dest, const uint8_t *p_data, uint32_t p_data_size);
- Error _server_relay(int32_t p_from, int32_t p_to, const uint8_t *p_buffer, uint32_t p_buffer_size);
-
-protected:
- enum {
- SYS_NONE = 0,
- SYS_ADD = 1,
- SYS_DEL = 2,
- SYS_ID = 3,
-
- PROTO_SIZE = 9
- };
-
- struct Packet {
- int source;
- int destination;
- uint8_t *data;
- uint32_t size;
- };
-
- List _incoming_packets;
- RBMap> _peer_map;
- Packet _current_packet;
-
- bool _is_multiplayer;
- int _target_peer;
- int _peer_id;
- int _refusing;
-
- static void _bind_methods();
-
- void _send_add(int32_t p_peer_id);
- void _send_sys(Ref p_peer, uint8_t p_type, int32_t p_peer_id);
- void _send_del(int32_t p_peer_id);
- int _gen_unique_id() const;
-
-public:
- /* NetworkedMultiplayerPeer */
- void set_transfer_mode(TransferMode p_mode);
- TransferMode get_transfer_mode() const;
- void set_target_peer(int p_target_peer);
- int get_packet_peer() const;
- int get_unique_id() const;
- virtual bool is_server() const = 0;
- void set_refuse_new_connections(bool p_enable);
- bool is_refusing_new_connections() const;
- virtual ConnectionStatus get_connection_status() const = 0;
-
- /* PacketPeer */
- virtual int get_available_packet_count() const;
- virtual int get_max_packet_size() const = 0;
- virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size);
- virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
-
- /* WebSocketPeer */
- virtual Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) = 0;
- virtual Ref get_peer(int p_peer_id) const = 0;
-
- void _process_multiplayer(Ref p_peer, uint32_t p_peer_id);
- void _clear();
-
- WebSocketMultiplayerPeer();
- ~WebSocketMultiplayerPeer();
-};
-
-#endif // WEBSOCKET_MULTIPLAYER_PEER_H
diff --git a/modules/websocket/websocket_peer.cpp b/modules/websocket/websocket_peer.cpp
deleted file mode 100644
index a0af930..0000000
--- a/modules/websocket/websocket_peer.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*************************************************************************/
-/* websocket_peer.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "websocket_peer.h"
-
-GDCINULL(WebSocketPeer);
-
-WebSocketPeer::WebSocketPeer() {
-}
-
-WebSocketPeer::~WebSocketPeer() {
-}
-
-void WebSocketPeer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_write_mode"), &WebSocketPeer::get_write_mode);
- ClassDB::bind_method(D_METHOD("set_write_mode", "mode"), &WebSocketPeer::set_write_mode);
- ClassDB::bind_method(D_METHOD("is_connected_to_host"), &WebSocketPeer::is_connected_to_host);
- ClassDB::bind_method(D_METHOD("was_string_packet"), &WebSocketPeer::was_string_packet);
- ClassDB::bind_method(D_METHOD("close", "code", "reason"), &WebSocketPeer::close, DEFVAL(1000), DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_connected_host"), &WebSocketPeer::get_connected_host);
- ClassDB::bind_method(D_METHOD("get_connected_port"), &WebSocketPeer::get_connected_port);
- ClassDB::bind_method(D_METHOD("set_no_delay", "enabled"), &WebSocketPeer::set_no_delay);
- ClassDB::bind_method(D_METHOD("get_current_outbound_buffered_amount"), &WebSocketPeer::get_current_outbound_buffered_amount);
-
- BIND_ENUM_CONSTANT(WRITE_MODE_TEXT);
- BIND_ENUM_CONSTANT(WRITE_MODE_BINARY);
-}
diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h
deleted file mode 100644
index 6552b68..0000000
--- a/modules/websocket/websocket_peer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef WEBSOCKETPEER_H
-#define WEBSOCKETPEER_H
-/*************************************************************************/
-/* websocket_peer.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "core/error/error_list.h"
-#include "core/io/packet_peer.h"
-#include "websocket_macros.h"
-
-class WebSocketPeer : public PacketPeer {
- GDCLASS(WebSocketPeer, PacketPeer);
- GDCICLASS(WebSocketPeer);
-
-public:
- enum WriteMode {
- WRITE_MODE_TEXT,
- WRITE_MODE_BINARY,
- };
-
-protected:
- static void _bind_methods();
-
-public:
- virtual int get_available_packet_count() const = 0;
- virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) = 0;
- virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) = 0;
- virtual int get_max_packet_size() const = 0;
- virtual int get_current_outbound_buffered_amount() const = 0;
-
- virtual WriteMode get_write_mode() const = 0;
- virtual void set_write_mode(WriteMode p_mode) = 0;
-
- virtual void close(int p_code = 1000, String p_reason = "") = 0;
-
- virtual bool is_connected_to_host() const = 0;
- virtual IP_Address get_connected_host() const = 0;
- virtual uint16_t get_connected_port() const = 0;
- virtual bool was_string_packet() const = 0;
- virtual void set_no_delay(bool p_enabled) = 0;
-
- WebSocketPeer();
- ~WebSocketPeer();
-};
-
-VARIANT_ENUM_CAST(WebSocketPeer::WriteMode);
-#endif // WEBSOCKETPEER_H
diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp
deleted file mode 100644
index b041848..0000000
--- a/modules/websocket/websocket_server.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*************************************************************************/
-/* websocket_server.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "websocket_server.h"
-
-GDCINULL(WebSocketServer);
-
-WebSocketServer::WebSocketServer() {
- _peer_id = 1;
- bind_ip = IP_Address("*");
-}
-
-WebSocketServer::~WebSocketServer() {
-}
-
-void WebSocketServer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("is_listening"), &WebSocketServer::is_listening);
- ClassDB::bind_method(D_METHOD("set_extra_headers", "headers"), &WebSocketServer::set_extra_headers, DEFVAL(Vector()));
- ClassDB::bind_method(D_METHOD("listen", "port", "protocols", "gd_mp_api"), &WebSocketServer::listen, DEFVAL(Vector()), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("stop"), &WebSocketServer::stop);
- ClassDB::bind_method(D_METHOD("has_peer", "id"), &WebSocketServer::has_peer);
- ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &WebSocketServer::get_peer_address);
- ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &WebSocketServer::get_peer_port);
- ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "code", "reason"), &WebSocketServer::disconnect_peer, DEFVAL(1000), DEFVAL(""));
-
- ClassDB::bind_method(D_METHOD("get_bind_ip"), &WebSocketServer::get_bind_ip);
- ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &WebSocketServer::set_bind_ip);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "bind_ip"), "set_bind_ip", "get_bind_ip");
-
- ClassDB::bind_method(D_METHOD("get_private_key"), &WebSocketServer::get_private_key);
- ClassDB::bind_method(D_METHOD("set_private_key", "key"), &WebSocketServer::set_private_key);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "private_key", PROPERTY_HINT_RESOURCE_TYPE, "CryptoKey", 0), "set_private_key", "get_private_key");
-
- ClassDB::bind_method(D_METHOD("get_ssl_certificate"), &WebSocketServer::get_ssl_certificate);
- ClassDB::bind_method(D_METHOD("set_ssl_certificate", "certificate"), &WebSocketServer::set_ssl_certificate);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_ssl_certificate", "get_ssl_certificate");
-
- ClassDB::bind_method(D_METHOD("get_ca_chain"), &WebSocketServer::get_ca_chain);
- ClassDB::bind_method(D_METHOD("set_ca_chain", "ca_chain"), &WebSocketServer::set_ca_chain);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ca_chain", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_ca_chain", "get_ca_chain");
-
- ClassDB::bind_method(D_METHOD("get_handshake_timeout"), &WebSocketServer::get_handshake_timeout);
- ClassDB::bind_method(D_METHOD("set_handshake_timeout", "timeout"), &WebSocketServer::set_handshake_timeout);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "handshake_timeout"), "set_handshake_timeout", "get_handshake_timeout");
-
- ADD_SIGNAL(MethodInfo("client_close_request", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::INT, "code"), PropertyInfo(Variant::STRING, "reason")));
- ADD_SIGNAL(MethodInfo("client_disconnected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::BOOL, "was_clean_close")));
- ADD_SIGNAL(MethodInfo("client_connected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::STRING, "protocol")));
- ADD_SIGNAL(MethodInfo("data_received", PropertyInfo(Variant::INT, "id")));
-}
-
-IP_Address WebSocketServer::get_bind_ip() const {
- return bind_ip;
-}
-
-void WebSocketServer::set_bind_ip(const IP_Address &p_bind_ip) {
- ERR_FAIL_COND(is_listening());
- ERR_FAIL_COND(!p_bind_ip.is_valid() && !p_bind_ip.is_wildcard());
- bind_ip = p_bind_ip;
-}
-
-Ref WebSocketServer::get_private_key() const {
- return private_key;
-}
-
-void WebSocketServer::set_private_key(Ref p_key) {
- ERR_FAIL_COND(is_listening());
- private_key = p_key;
-}
-
-Ref WebSocketServer::get_ssl_certificate() const {
- return ssl_cert;
-}
-
-void WebSocketServer::set_ssl_certificate(Ref p_cert) {
- ERR_FAIL_COND(is_listening());
- ssl_cert = p_cert;
-}
-
-Ref WebSocketServer::get_ca_chain() const {
- return ca_chain;
-}
-
-void WebSocketServer::set_ca_chain(Ref p_ca_chain) {
- ERR_FAIL_COND(is_listening());
- ca_chain = p_ca_chain;
-}
-
-float WebSocketServer::get_handshake_timeout() const {
- return handshake_timeout / 1000.0;
-}
-
-void WebSocketServer::set_handshake_timeout(float p_timeout) {
- ERR_FAIL_COND(p_timeout <= 0.0);
- handshake_timeout = p_timeout * 1000;
-}
-
-NetworkedMultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const {
- if (is_listening()) {
- return CONNECTION_CONNECTED;
- }
-
- return CONNECTION_DISCONNECTED;
-}
-
-bool WebSocketServer::is_server() const {
- return true;
-}
-
-void WebSocketServer::_on_peer_packet(int32_t p_peer_id) {
- if (_is_multiplayer) {
- _process_multiplayer(get_peer(p_peer_id), p_peer_id);
- } else {
- emit_signal("data_received", p_peer_id);
- }
-}
-
-void WebSocketServer::_on_connect(int32_t p_peer_id, String p_protocol) {
- if (_is_multiplayer) {
- // Send add to clients
- _send_add(p_peer_id);
- emit_signal("peer_connected", p_peer_id);
- } else {
- emit_signal("client_connected", p_peer_id, p_protocol);
- }
-}
-
-void WebSocketServer::_on_disconnect(int32_t p_peer_id, bool p_was_clean) {
- if (_is_multiplayer) {
- // Send delete to clients
- _send_del(p_peer_id);
- emit_signal("peer_disconnected", p_peer_id);
- } else {
- emit_signal("client_disconnected", p_peer_id, p_was_clean);
- }
-}
-
-void WebSocketServer::_on_close_request(int32_t p_peer_id, int p_code, String p_reason) {
- emit_signal("client_close_request", p_peer_id, p_code, p_reason);
-}
diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h
deleted file mode 100644
index 9437723..0000000
--- a/modules/websocket/websocket_server.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef WEBSOCKET_H
-#define WEBSOCKET_H
-/*************************************************************************/
-/* websocket_server.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "core/crypto/crypto.h"
-#include "core/object/reference.h"
-#include "websocket_multiplayer_peer.h"
-#include "websocket_peer.h"
-
-class WebSocketServer : public WebSocketMultiplayerPeer {
- GDCLASS(WebSocketServer, WebSocketMultiplayerPeer);
- GDCICLASS(WebSocketServer);
-
- IP_Address bind_ip;
-
-protected:
- static void _bind_methods();
-
- Ref private_key;
- Ref ssl_cert;
- Ref ca_chain;
- uint32_t handshake_timeout = 3000;
-
-public:
- virtual void poll() = 0;
- virtual void set_extra_headers(const Vector &p_headers) = 0;
- virtual Error listen(int p_port, const Vector p_protocols = Vector(), bool gd_mp_api = false) = 0;
- virtual void stop() = 0;
- virtual bool is_listening() const = 0;
- virtual bool has_peer(int p_id) const = 0;
- virtual Ref get_peer(int p_id) const = 0;
- virtual bool is_server() const;
- ConnectionStatus get_connection_status() const;
-
- virtual IP_Address get_peer_address(int p_peer_id) const = 0;
- virtual int get_peer_port(int p_peer_id) const = 0;
- virtual void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = "") = 0;
-
- void _on_peer_packet(int32_t p_peer_id);
- void _on_connect(int32_t p_peer_id, String p_protocol);
- void _on_disconnect(int32_t p_peer_id, bool p_was_clean);
- void _on_close_request(int32_t p_peer_id, int p_code, String p_reason);
-
- IP_Address get_bind_ip() const;
- void set_bind_ip(const IP_Address &p_bind_ip);
-
- Ref get_private_key() const;
- void set_private_key(Ref p_key);
-
- Ref get_ssl_certificate() const;
- void set_ssl_certificate(Ref p_cert);
-
- Ref get_ca_chain() const;
- void set_ca_chain(Ref p_ca_chain);
-
- float get_handshake_timeout() const;
- void set_handshake_timeout(float p_timeout);
-
- virtual Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) = 0;
-
- WebSocketServer();
- ~WebSocketServer();
-};
-
-#endif // WEBSOCKET_H
diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp
deleted file mode 100644
index b8ffc7f..0000000
--- a/modules/websocket/wsl_client.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-/*************************************************************************/
-/* wsl_client.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifndef JAVASCRIPT_ENABLED
-
-#include "wsl_client.h"
-#include "core/io/ip.h"
-#include "core/config/project_settings.h"
-
-void WSLClient::_do_handshake() {
- if (_requested < _request.size() - 1) {
- int sent = 0;
- Error err = _connection->put_partial_data(((const uint8_t *)_request.get_data() + _requested), _request.size() - _requested - 1, sent);
- // Sending handshake failed
- if (err != OK) {
- disconnect_from_host();
- _on_error();
- return;
- }
- _requested += sent;
-
- } else {
- int read = 0;
- while (true) {
- if (_resp_pos >= WSL_MAX_HEADER_SIZE) {
- // Header is too big
- disconnect_from_host();
- _on_error();
- ERR_FAIL_MSG("Response headers too big.");
- }
- Error err = _connection->get_partial_data(&_resp_buf[_resp_pos], 1, read);
- if (err == ERR_FILE_EOF) {
- // We got a disconnect.
- disconnect_from_host();
- _on_error();
- return;
- } else if (err != OK) {
- // Got some error.
- disconnect_from_host();
- _on_error();
- return;
- } else if (read != 1) {
- // Busy, wait next poll.
- break;
- }
- // Check "\r\n\r\n" header terminator
- char *r = (char *)_resp_buf;
- int l = _resp_pos;
- if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') {
- r[l - 3] = '\0';
- String protocol;
- // Response is over, verify headers and create peer.
- if (!_verify_headers(protocol)) {
- disconnect_from_host();
- _on_error();
- ERR_FAIL_MSG("Invalid response headers.");
- }
- // Create peer.
- WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData);
- data->obj = this;
- data->conn = _connection;
- data->tcp = _tcp;
- data->is_server = false;
- data->id = 1;
- _peer->make_context(data, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size);
- _peer->set_no_delay(true);
- _on_connect(protocol);
- break;
- }
- _resp_pos += 1;
- }
- }
-}
-
-bool WSLClient::_verify_headers(String &r_protocol) {
- String s = (char *)_resp_buf;
- Vector psa = s.split("\r\n");
- int len = psa.size();
- ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4.");
-
- Vector req = psa[0].split(" ", false);
- ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code.");
-
- // Wrong protocol
- ERR_FAIL_COND_V_MSG(req[0] != "HTTP/1.1" || req[1] != "101", false, "Invalid protocol or status code.");
-
- RBMap headers;
- for (int i = 1; i < len; i++) {
- Vector header = psa[i].split(":", false, 1);
- ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i] + ".");
- String name = header[0].to_lower();
- String value = header[1].strip_edges();
- if (headers.has(name)) {
- headers[name] += "," + value;
- } else {
- headers[name] = value;
- }
- }
-
-#define _WSL_CHECK(NAME, VALUE) \
- ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME].to_lower() != VALUE, false, \
- "Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'.");
-#define _WSL_CHECK_NC(NAME, VALUE) \
- ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME] != VALUE, false, \
- "Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'.");
- _WSL_CHECK("connection", "upgrade");
- _WSL_CHECK("upgrade", "websocket");
- _WSL_CHECK_NC("sec-websocket-accept", WSLPeer::compute_key_response(_key));
-#undef _WSL_CHECK_NC
-#undef _WSL_CHECK
- if (_protocols.size() == 0) {
- // We didn't request a custom protocol
- ERR_FAIL_COND_V(headers.has("sec-websocket-protocol"), false);
- } else {
- ERR_FAIL_COND_V(!headers.has("sec-websocket-protocol"), false);
- r_protocol = headers["sec-websocket-protocol"];
- bool valid = false;
- for (int i = 0; i < _protocols.size(); i++) {
- if (_protocols[i] != r_protocol) {
- continue;
- }
- valid = true;
- break;
- }
- if (!valid) {
- return false;
- }
- }
- return true;
-}
-
-Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector p_protocols, const Vector p_custom_headers) {
- ERR_FAIL_COND_V(_connection.is_valid(), ERR_ALREADY_IN_USE);
- ERR_FAIL_COND_V(p_path.empty(), ERR_INVALID_PARAMETER);
-
- _peer = Ref(memnew(WSLPeer));
-
- if (p_host.is_valid_ip_address()) {
- _ip_candidates.push_back(IP_Address(p_host));
- } else {
- // Queue hostname for resolution.
- _resolver_id = IP::get_singleton()->resolve_hostname_queue_item(p_host);
- ERR_FAIL_COND_V(_resolver_id == IP::RESOLVER_INVALID_ID, ERR_INVALID_PARAMETER);
- // Check if it was found in cache.
- IP::ResolverStatus ip_status = IP::get_singleton()->get_resolve_item_status(_resolver_id);
- if (ip_status == IP::RESOLVER_STATUS_DONE) {
- _ip_candidates = IP::get_singleton()->get_resolve_item_addresses(_resolver_id);
- IP::get_singleton()->erase_resolve_item(_resolver_id);
- _resolver_id = IP::RESOLVER_INVALID_ID;
- }
- }
-
- // We assume OK while hostname resolution is pending.
- Error err = _resolver_id != IP::RESOLVER_INVALID_ID ? OK : FAILED;
- while (_ip_candidates.size()) {
- err = _tcp->connect_to_host(_ip_candidates.pop_front(), p_port);
- if (err == OK) {
- break;
- }
- }
- if (err != OK) {
- _tcp->disconnect_from_host();
- _on_error();
- return err;
- }
- _connection = _tcp;
- _use_ssl = p_ssl;
- _host = p_host;
- _port = p_port;
- // Strip edges from protocols.
- _protocols.resize(p_protocols.size());
- String *pw = _protocols.ptrw();
- for (int i = 0; i < p_protocols.size(); i++) {
- pw[i] = p_protocols[i].strip_edges();
- }
-
- _key = WSLPeer::generate_key();
- String request = "GET " + p_path + " HTTP/1.1\r\n";
- String port = "";
- if ((p_port != 80 && !p_ssl) || (p_port != 443 && p_ssl)) {
- port = ":" + itos(p_port);
- }
- request += "Host: " + p_host + port + "\r\n";
- request += "Upgrade: websocket\r\n";
- request += "Connection: Upgrade\r\n";
- request += "Sec-WebSocket-Key: " + _key + "\r\n";
- request += "Sec-WebSocket-Version: 13\r\n";
- if (p_protocols.size() > 0) {
- request += "Sec-WebSocket-Protocol: ";
- for (int i = 0; i < p_protocols.size(); i++) {
- if (i != 0) {
- request += ",";
- }
- request += p_protocols[i];
- }
- request += "\r\n";
- }
- for (int i = 0; i < p_custom_headers.size(); i++) {
- request += p_custom_headers[i] + "\r\n";
- }
- request += "\r\n";
- _request = request.utf8();
-
- return OK;
-}
-
-int WSLClient::get_max_packet_size() const {
- return (1 << _out_buf_size) - PROTO_SIZE;
-}
-
-void WSLClient::poll() {
- if (_resolver_id != IP::RESOLVER_INVALID_ID) {
- IP::ResolverStatus ip_status = IP::get_singleton()->get_resolve_item_status(_resolver_id);
- if (ip_status == IP::RESOLVER_STATUS_WAITING) {
- return;
- }
- // Anything else is either a candidate or a failure.
- Error err = FAILED;
- if (ip_status == IP::RESOLVER_STATUS_DONE) {
- _ip_candidates = IP::get_singleton()->get_resolve_item_addresses(_resolver_id);
- while (_ip_candidates.size()) {
- err = _tcp->connect_to_host(_ip_candidates.pop_front(), _port);
- if (err == OK) {
- break;
- }
- }
- }
- IP::get_singleton()->erase_resolve_item(_resolver_id);
- _resolver_id = IP::RESOLVER_INVALID_ID;
- if (err != OK) {
- disconnect_from_host();
- _on_error();
- return;
- }
- }
- if (_peer->is_connected_to_host()) {
- _peer->poll();
- if (!_peer->is_connected_to_host()) {
- disconnect_from_host();
- _on_disconnect(_peer->close_code != -1);
- }
- return;
- }
-
- if (_connection.is_null()) {
- return; // Not connected.
- }
-
- switch (_tcp->get_status()) {
- case StreamPeerTCP::STATUS_NONE:
- // Clean close
- disconnect_from_host();
- _on_error();
- break;
- case StreamPeerTCP::STATUS_CONNECTED: {
- _ip_candidates.clear();
- Ref ssl;
- if (_use_ssl) {
- if (_connection == _tcp) {
- // Start SSL handshake
- ssl = Ref(StreamPeerSSL::create());
- ERR_FAIL_COND_MSG(ssl.is_null(), "SSL is not available in this build.");
- ssl->set_blocking_handshake_enabled(false);
- if (ssl->connect_to_stream(_tcp, verify_ssl, _host, ssl_cert) != OK) {
- disconnect_from_host();
- _on_error();
- return;
- }
- _connection = ssl;
- } else {
- ssl = static_cast][>(_connection);
- ERR_FAIL_COND(ssl.is_null()); // Bug?
- ssl->poll();
- }
- if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) {
- return; // Need more polling.
- } else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
- disconnect_from_host();
- _on_error();
- return; // Error.
- }
- }
- // Do websocket handshake.
- _do_handshake();
- } break;
- case StreamPeerTCP::STATUS_ERROR:
- while (_ip_candidates.size() > 0) {
- _tcp->disconnect_from_host();
- if (_tcp->connect_to_host(_ip_candidates.pop_front(), _port) == OK) {
- return;
- }
- }
- disconnect_from_host();
- _on_error();
- break;
- case StreamPeerTCP::STATUS_CONNECTING:
- break; // Wait for connection
- }
-}
-
-Ref WSLClient::get_peer(int p_peer_id) const {
- ERR_FAIL_COND_V(p_peer_id != 1, nullptr);
-
- return _peer;
-}
-
-NetworkedMultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() const {
- if (_peer->is_connected_to_host()) {
- return CONNECTION_CONNECTED;
- }
-
- if (_tcp->is_connected_to_host() || _resolver_id != IP::RESOLVER_INVALID_ID) {
- return CONNECTION_CONNECTING;
- }
-
- return CONNECTION_DISCONNECTED;
-}
-
-void WSLClient::disconnect_from_host(int p_code, String p_reason) {
- _peer->close(p_code, p_reason);
- _connection = Ref(nullptr);
- _tcp = Ref(memnew(StreamPeerTCP));
-
- _key = "";
- _host = "";
- _protocols.clear();
- _use_ssl = false;
-
- _request = "";
- _requested = 0;
-
- memset(_resp_buf, 0, sizeof(_resp_buf));
- _resp_pos = 0;
-
- if (_resolver_id != IP::RESOLVER_INVALID_ID) {
- IP::get_singleton()->erase_resolve_item(_resolver_id);
- _resolver_id = IP::RESOLVER_INVALID_ID;
- }
-
- _ip_candidates.clear();
-}
-
-IP_Address WSLClient::get_connected_host() const {
- ERR_FAIL_COND_V(!_peer->is_connected_to_host(), IP_Address());
- return _peer->get_connected_host();
-}
-
-uint16_t WSLClient::get_connected_port() const {
- ERR_FAIL_COND_V(!_peer->is_connected_to_host(), 0);
- return _peer->get_connected_port();
-}
-
-Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) {
- ERR_FAIL_COND_V_MSG(_connection.is_valid(), FAILED, "Buffers sizes can only be set before listening or connecting.");
-
- _in_buf_size = nearest_shift(p_in_buffer - 1) + 10;
- _in_pkt_size = nearest_shift(p_in_packets - 1);
- _out_buf_size = nearest_shift(p_out_buffer - 1) + 10;
- _out_pkt_size = nearest_shift(p_out_packets - 1);
- return OK;
-}
-
-WSLClient::WSLClient() {
- _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);
- _out_buf_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_BUF) - 1) + 10;
- _out_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_PKT) - 1);
-
- _peer.instance();
- _tcp.instance();
- disconnect_from_host();
-}
-
-WSLClient::~WSLClient() {
- _peer->close_now();
- _peer->invalidate();
- disconnect_from_host();
-}
-
-#endif // JAVASCRIPT_ENABLED
diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h
deleted file mode 100644
index 7244912..0000000
--- a/modules/websocket/wsl_client.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef WSLCLIENT_H
-#define WSLCLIENT_H
-/*************************************************************************/
-/* wsl_client.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifndef JAVASCRIPT_ENABLED
-
-#include "core/error/error_list.h"
-#include "core/io/stream_peer_ssl.h"
-#include "core/io/stream_peer_tcp.h"
-#include "websocket_client.h"
-#include "wsl_peer.h"
-#include "wslay/wslay.h"
-
-class WSLClient : public WebSocketClient {
- GDCIIMPL(WSLClient, WebSocketClient);
-
-private:
- int _in_buf_size;
- int _in_pkt_size;
- int _out_buf_size;
- int _out_pkt_size;
-
- Ref _peer;
- Ref _tcp;
- Ref _connection;
-
- CharString _request;
- int _requested;
-
- uint8_t _resp_buf[WSL_MAX_HEADER_SIZE];
- int _resp_pos;
-
- String _response;
-
- String _key;
- String _host;
- uint16_t _port;
- Array _ip_candidates;
- Vector _protocols;
- bool _use_ssl = false;
- IP::ResolverID _resolver_id = IP::RESOLVER_INVALID_ID;
-
- void _do_handshake();
- bool _verify_headers(String &r_protocol);
-
-public:
- Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets);
- Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector p_protocol = Vector(), const Vector p_custom_headers = Vector());
- int get_max_packet_size() const;
- Ref get_peer(int p_peer_id) const;
- void disconnect_from_host(int p_code = 1000, String p_reason = "");
- IP_Address get_connected_host() const;
- uint16_t get_connected_port() const;
- virtual ConnectionStatus get_connection_status() const;
- virtual void poll();
-
- WSLClient();
- ~WSLClient();
-};
-
-#endif // JAVASCRIPT_ENABLED
-
-#endif // WSLCLIENT_H
diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp
deleted file mode 100644
index 73ea7d3..0000000
--- a/modules/websocket/wsl_peer.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/*************************************************************************/
-/* wsl_peer.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifndef JAVASCRIPT_ENABLED
-
-#include "wsl_peer.h"
-
-#include "wsl_client.h"
-#include "wsl_server.h"
-
-#include "core/crypto/crypto_core.h"
-#include "core/math/random_number_generator.h"
-#include "core/os/os.h"
-
-String WSLPeer::generate_key() {
- // Random key
- RandomNumberGenerator rng;
- rng.set_seed(OS::get_singleton()->get_unix_time());
- PoolVector bkey;
- int len = 16; // 16 bytes, as per RFC
- bkey.resize(len);
- PoolVector::Write w = bkey.write();
- for (int i = 0; i < len; i++) {
- w[i] = (uint8_t)rng.randi_range(0, 255);
- }
- return CryptoCore::b64_encode_str(&w[0], len);
-}
-
-String WSLPeer::compute_key_response(String p_key) {
- String key = p_key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // Magic UUID as per RFC
- Vector sha = key.sha1_buffer();
- return CryptoCore::b64_encode_str(sha.ptr(), sha.size());
-}
-
-void WSLPeer::_wsl_destroy(struct PeerData **p_data) {
- if (!p_data || !(*p_data)) {
- return;
- }
- struct PeerData *data = *p_data;
- if (data->polling) {
- data->destroy = true;
- return;
- }
- wslay_event_context_free(data->ctx);
- memdelete(data);
- *p_data = nullptr;
-}
-
-bool WSLPeer::_wsl_poll(struct PeerData *p_data) {
- p_data->polling = true;
- int err = 0;
- if ((err = wslay_event_recv(p_data->ctx)) != 0 || (err = wslay_event_send(p_data->ctx)) != 0) {
- print_verbose("Websocket (wslay) poll error: " + itos(err));
- p_data->destroy = true;
- }
- p_data->polling = false;
-
- if (p_data->destroy || (wslay_event_get_close_sent(p_data->ctx) && wslay_event_get_close_received(p_data->ctx))) {
- bool valid = p_data->valid;
- _wsl_destroy(&p_data);
- return valid;
- }
- return false;
-}
-
-ssize_t wsl_recv_callback(wslay_event_context_ptr ctx, uint8_t *data, size_t len, int flags, void *user_data) {
- struct WSLPeer::PeerData *peer_data = (struct WSLPeer::PeerData *)user_data;
- if (!peer_data->valid) {
- wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
- return -1;
- }
- Ref conn = peer_data->conn;
- int read = 0;
- Error err = conn->get_partial_data(data, len, read);
- if (err != OK) {
- print_verbose("Websocket get data error: " + itos(err) + ", read (should be 0!): " + itos(read));
- wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
- return -1;
- }
- if (read == 0) {
- wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
- return -1;
- }
- return read;
-}
-
-ssize_t wsl_send_callback(wslay_event_context_ptr ctx, const uint8_t *data, size_t len, int flags, void *user_data) {
- struct WSLPeer::PeerData *peer_data = (struct WSLPeer::PeerData *)user_data;
- if (!peer_data->valid) {
- wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
- return -1;
- }
- Ref conn = peer_data->conn;
- int sent = 0;
- Error err = conn->put_partial_data(data, len, sent);
- if (err != OK) {
- wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
- return -1;
- }
- if (sent == 0) {
- wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
- return -1;
- }
- return sent;
-}
-
-int wsl_genmask_callback(wslay_event_context_ptr ctx, uint8_t *buf, size_t len, void *user_data) {
- RandomNumberGenerator rng;
- // TODO maybe use crypto in the future?
- rng.set_seed(OS::get_singleton()->get_unix_time());
- for (unsigned int i = 0; i < len; i++) {
- buf[i] = (uint8_t)rng.randi_range(0, 255);
- }
- return 0;
-}
-
-void wsl_msg_recv_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_msg_recv_arg *arg, void *user_data) {
- struct WSLPeer::PeerData *peer_data = (struct WSLPeer::PeerData *)user_data;
- if (!peer_data->valid || peer_data->closing) {
- return;
- }
- WSLPeer *peer = (WSLPeer *)peer_data->peer;
-
- if (peer->parse_message(arg) != OK) {
- return;
- }
-
- if (peer_data->is_server) {
- WSLServer *helper = (WSLServer *)peer_data->obj;
- helper->_on_peer_packet(peer_data->id);
- } else {
- WSLClient *helper = (WSLClient *)peer_data->obj;
- helper->_on_peer_packet();
- }
-}
-
-wslay_event_callbacks wsl_callbacks = {
- wsl_recv_callback,
- wsl_send_callback,
- wsl_genmask_callback,
- nullptr, /* on_frame_recv_start_callback */
- nullptr, /* on_frame_recv_callback */
- nullptr, /* on_frame_recv_end_callback */
- wsl_msg_recv_callback
-};
-
-Error WSLPeer::parse_message(const wslay_event_on_msg_recv_arg *arg) {
- uint8_t is_string = 0;
- if (arg->opcode == WSLAY_TEXT_FRAME) {
- is_string = 1;
- } else if (arg->opcode == WSLAY_CONNECTION_CLOSE) {
- close_code = arg->status_code;
- size_t len = arg->msg_length;
- close_reason = "";
- if (len > 2 /* first 2 bytes = close code */) {
- close_reason.parse_utf8((char *)arg->msg + 2, len - 2);
- }
- if (!wslay_event_get_close_sent(_data->ctx)) {
- if (_data->is_server) {
- WSLServer *helper = (WSLServer *)_data->obj;
- helper->_on_close_request(_data->id, close_code, close_reason);
- } else {
- WSLClient *helper = (WSLClient *)_data->obj;
- helper->_on_close_request(close_code, close_reason);
- }
- }
- return ERR_FILE_EOF;
- } else if (arg->opcode != WSLAY_BINARY_FRAME) {
- // Ping or pong
- return ERR_SKIP;
- }
- _in_buffer.write_packet(arg->msg, arg->msg_length, &is_string);
- return OK;
-}
-
-void WSLPeer::make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size, unsigned int p_out_pkt_size) {
- ERR_FAIL_COND(_data != nullptr);
- ERR_FAIL_COND(p_data == nullptr);
-
- _in_buffer.resize(p_in_pkt_size, p_in_buf_size);
- _packet_buffer.resize(1 << p_in_buf_size);
- _out_buf_size = p_out_buf_size;
- _out_pkt_size = p_out_pkt_size;
-
- _data = p_data;
- _data->peer = this;
- _data->valid = true;
-
- if (_data->is_server) {
- wslay_event_context_server_init(&(_data->ctx), &wsl_callbacks, _data);
- } else {
- wslay_event_context_client_init(&(_data->ctx), &wsl_callbacks, _data);
- }
- wslay_event_config_set_max_recv_msg_length(_data->ctx, (1ULL << p_in_buf_size));
-}
-
-void WSLPeer::set_write_mode(WriteMode p_mode) {
- write_mode = p_mode;
-}
-
-WSLPeer::WriteMode WSLPeer::get_write_mode() const {
- return write_mode;
-}
-
-void WSLPeer::poll() {
- if (!_data) {
- return;
- }
-
- if (_wsl_poll(_data)) {
- _data = nullptr;
- }
-}
-
-Error WSLPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_FAIL_COND_V(!is_connected_to_host(), FAILED);
- ERR_FAIL_COND_V(_out_pkt_size && (wslay_event_get_queued_msg_count(_data->ctx) >= (1ULL << _out_pkt_size)), ERR_OUT_OF_MEMORY);
- ERR_FAIL_COND_V(_out_buf_size && (wslay_event_get_queued_msg_length(_data->ctx) + p_buffer_size >= (1ULL << _out_buf_size)), ERR_OUT_OF_MEMORY);
-
- struct wslay_event_msg msg;
- msg.opcode = write_mode == WRITE_MODE_TEXT ? WSLAY_TEXT_FRAME : WSLAY_BINARY_FRAME;
- msg.msg = p_buffer;
- msg.msg_length = p_buffer_size;
-
- if (wslay_event_queue_msg(_data->ctx, &msg) != 0 || wslay_event_send(_data->ctx) != 0) {
- close_now();
- return FAILED;
- }
- return OK;
-}
-
-Error WSLPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- r_buffer_size = 0;
-
- ERR_FAIL_COND_V(!is_connected_to_host(), FAILED);
-
- if (_in_buffer.packets_left() == 0) {
- return ERR_UNAVAILABLE;
- }
-
- int read = 0;
- PoolVector::Write rw = _packet_buffer.write();
- _in_buffer.read_packet(rw.ptr(), _packet_buffer.size(), &_is_string, read);
-
- *r_buffer = rw.ptr();
- r_buffer_size = read;
-
- return OK;
-}
-
-int WSLPeer::get_available_packet_count() const {
- if (!is_connected_to_host()) {
- return 0;
- }
-
- return _in_buffer.packets_left();
-}
-
-int WSLPeer::get_current_outbound_buffered_amount() const {
- ERR_FAIL_COND_V(!_data, 0);
-
- return wslay_event_get_queued_msg_length(_data->ctx);
-}
-
-bool WSLPeer::was_string_packet() const {
- return _is_string;
-}
-
-bool WSLPeer::is_connected_to_host() const {
- return _data != nullptr;
-}
-
-void WSLPeer::close_now() {
- close(1000, "");
- _wsl_destroy(&_data);
-}
-
-void WSLPeer::close(int p_code, String p_reason) {
- if (_data && !wslay_event_get_close_sent(_data->ctx)) {
- CharString cs = p_reason.utf8();
- wslay_event_queue_close(_data->ctx, p_code, (uint8_t *)cs.ptr(), cs.size());
- wslay_event_send(_data->ctx);
- _data->closing = true;
- }
-
- _in_buffer.clear();
- _packet_buffer.resize(0);
-}
-
-IP_Address WSLPeer::get_connected_host() const {
- ERR_FAIL_COND_V(!is_connected_to_host() || _data->tcp.is_null(), IP_Address());
-
- return _data->tcp->get_connected_host();
-}
-
-uint16_t WSLPeer::get_connected_port() const {
- ERR_FAIL_COND_V(!is_connected_to_host() || _data->tcp.is_null(), 0);
-
- return _data->tcp->get_connected_port();
-}
-
-void WSLPeer::set_no_delay(bool p_enabled) {
- ERR_FAIL_COND(!is_connected_to_host() || _data->tcp.is_null());
- _data->tcp->set_no_delay(p_enabled);
-}
-
-void WSLPeer::invalidate() {
- if (_data) {
- _data->valid = false;
- }
-}
-
-WSLPeer::WSLPeer() {
- _data = nullptr;
- _is_string = 0;
- close_code = -1;
- write_mode = WRITE_MODE_BINARY;
- _out_buf_size = 0;
- _out_pkt_size = 0;
-}
-
-WSLPeer::~WSLPeer() {
- close();
- invalidate();
- _wsl_destroy(&_data);
- _data = nullptr;
-}
-
-#endif // JAVASCRIPT_ENABLED
diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h
deleted file mode 100644
index b14617c..0000000
--- a/modules/websocket/wsl_peer.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef WSLPEER_H
-#define WSLPEER_H
-/*************************************************************************/
-/* wsl_peer.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifndef JAVASCRIPT_ENABLED
-
-#include "core/error/error_list.h"
-#include "core/io/packet_peer.h"
-#include "core/io/stream_peer_tcp.h"
-#include "core/containers/ring_buffer.h"
-#include "packet_buffer.h"
-#include "websocket_peer.h"
-#include "wslay/wslay.h"
-
-#define WSL_MAX_HEADER_SIZE 4096
-
-class WSLPeer : public WebSocketPeer {
- GDCIIMPL(WSLPeer, WebSocketPeer);
-
-public:
- struct PeerData {
- bool polling;
- bool destroy;
- bool valid;
- bool is_server;
- bool closing;
- void *obj;
- void *peer;
- Ref conn;
- Ref tcp;
- int id;
- wslay_event_context_ptr ctx;
-
- PeerData() {
- polling = false;
- destroy = false;
- valid = false;
- is_server = false;
- id = 1;
- ctx = nullptr;
- obj = nullptr;
- closing = false;
- peer = nullptr;
- }
- };
-
- static String compute_key_response(String p_key);
- static String generate_key();
-
-private:
- static bool _wsl_poll(struct PeerData *p_data);
- static void _wsl_destroy(struct PeerData **p_data);
-
- struct PeerData *_data;
- uint8_t _is_string;
- // Our packet info is just a boolean (is_string), using uint8_t for it.
- PacketBuffer _in_buffer;
-
- PoolVector _packet_buffer;
-
- WriteMode write_mode;
-
- int _out_buf_size;
- int _out_pkt_size;
-
-public:
- int close_code;
- String close_reason;
- void poll(); // Used by client and server.
-
- virtual int get_available_packet_count() const;
- virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size);
- virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
- virtual int get_max_packet_size() const { return _packet_buffer.size(); };
- virtual int get_current_outbound_buffered_amount() const;
-
- virtual void close_now();
- virtual void close(int p_code = 1000, String p_reason = "");
- virtual bool is_connected_to_host() const;
- virtual IP_Address get_connected_host() const;
- virtual uint16_t get_connected_port() const;
-
- virtual WriteMode get_write_mode() const;
- virtual void set_write_mode(WriteMode p_mode);
- virtual bool was_string_packet() const;
- virtual void set_no_delay(bool p_enabled);
-
- void make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size, unsigned int p_out_pkt_size);
- Error parse_message(const wslay_event_on_msg_recv_arg *arg);
- void invalidate();
-
- WSLPeer();
- ~WSLPeer();
-};
-
-#endif // JAVASCRIPT_ENABLED
-
-#endif // LSWPEER_H
diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp
deleted file mode 100644
index c9d77cc..0000000
--- a/modules/websocket/wsl_server.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-/*************************************************************************/
-/* wsl_server.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifndef JAVASCRIPT_ENABLED
-
-#include "wsl_server.h"
-#include "core/os/os.h"
-#include "core/config/project_settings.h"
-
-WSLServer::PendingPeer::PendingPeer() {
- use_ssl = false;
- time = 0;
- has_request = false;
- response_sent = 0;
- req_pos = 0;
- memset(req_buf, 0, sizeof(req_buf));
-}
-
-bool WSLServer::PendingPeer::_parse_request(const Vector p_protocols) {
- Vector psa = String((char *)req_buf).split("\r\n");
- int len = psa.size();
- ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4.");
-
- Vector req = psa[0].split(" ", false);
- ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code.");
-
- // Wrong protocol
- ERR_FAIL_COND_V_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", false, "Invalid method or HTTP version.");
-
- RBMap headers;
- for (int i = 1; i < len; i++) {
- Vector header = psa[i].split(":", false, 1);
- ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i]);
- String name = header[0].to_lower();
- String value = header[1].strip_edges();
- if (headers.has(name)) {
- headers[name] += "," + value;
- } else {
- headers[name] = value;
- }
- }
-#define _WSL_CHECK(NAME, VALUE) \
- ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME].to_lower() != VALUE, false, \
- "Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'.");
-#define _WSL_CHECK_EX(NAME) \
- ERR_FAIL_COND_V_MSG(!headers.has(NAME), false, "Missing header '" + String(NAME) + "'.");
- _WSL_CHECK("upgrade", "websocket");
- _WSL_CHECK("sec-websocket-version", "13");
- _WSL_CHECK_EX("sec-websocket-key");
- _WSL_CHECK_EX("connection");
-#undef _WSL_CHECK_EX
-#undef _WSL_CHECK
- key = headers["sec-websocket-key"];
- if (headers.has("sec-websocket-protocol")) {
- Vector protos = headers["sec-websocket-protocol"].split(",");
- for (int i = 0; i < protos.size(); i++) {
- String proto = protos[i].strip_edges();
- // Check if we have the given protocol
- for (int j = 0; j < p_protocols.size(); j++) {
- if (proto != p_protocols[j]) {
- continue;
- }
- protocol = proto;
- break;
- }
- // Found a protocol
- if (protocol != "") {
- break;
- }
- }
- if (protocol == "") { // Invalid protocol(s) requested
- return false;
- }
- } else if (p_protocols.size() > 0) { // No protocol requested, but we need one
- return false;
- }
- return true;
-}
-
-Error WSLServer::PendingPeer::do_handshake(const Vector p_protocols, uint64_t p_timeout, const Vector &p_extra_headers) {
- if (OS::get_singleton()->get_ticks_msec() - time > p_timeout) {
- print_verbose(vformat("WebSocket handshake timed out after %.3f seconds.", p_timeout * 0.001));
- return ERR_TIMEOUT;
- }
-
- if (use_ssl) {
- Ref ssl = static_cast][>(connection);
- if (ssl.is_null()) {
- ERR_FAIL_V_MSG(ERR_BUG, "Couldn't get StreamPeerSSL for WebSocket handshake.");
- }
- ssl->poll();
- if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) {
- return ERR_BUSY;
- } else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
- print_verbose(vformat("WebSocket SSL connection error during handshake (StreamPeerSSL status code %d).", ssl->get_status()));
- return FAILED;
- }
- }
-
- if (!has_request) {
- int read = 0;
- while (true) {
- ERR_FAIL_COND_V_MSG(req_pos >= WSL_MAX_HEADER_SIZE, ERR_OUT_OF_MEMORY, "WebSocket response headers are too big.");
- Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
- if (err != OK) { // Got an error
- print_verbose(vformat("WebSocket error while getting partial data (StreamPeer error code %d).", err));
- return FAILED;
- } else if (read != 1) { // Busy, wait next poll
- return ERR_BUSY;
- }
- char *r = (char *)req_buf;
- int l = req_pos;
- if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') {
- r[l - 3] = '\0';
- if (!_parse_request(p_protocols)) {
- return FAILED;
- }
- String s = "HTTP/1.1 101 Switching Protocols\r\n";
- s += "Upgrade: websocket\r\n";
- s += "Connection: Upgrade\r\n";
- s += "Sec-WebSocket-Accept: " + WSLPeer::compute_key_response(key) + "\r\n";
- if (protocol != "") {
- s += "Sec-WebSocket-Protocol: " + protocol + "\r\n";
- }
- for (int i = 0; i < p_extra_headers.size(); i++) {
- s += p_extra_headers[i] + "\r\n";
- }
- s += "\r\n";
- response = s.utf8();
- has_request = true;
- break;
- }
- req_pos += 1;
- }
- }
-
- if (has_request && response_sent < response.size() - 1) {
- int sent = 0;
- Error err = connection->put_partial_data((const uint8_t *)response.get_data() + response_sent, response.size() - response_sent - 1, sent);
- if (err != OK) {
- print_verbose(vformat("WebSocket error while putting partial data (StreamPeer error code %d).", err));
- return err;
- }
- response_sent += sent;
- }
-
- if (response_sent < response.size() - 1) {
- return ERR_BUSY;
- }
-
- return OK;
-}
-
-void WSLServer::set_extra_headers(const Vector &p_headers) {
- _extra_headers = p_headers;
-}
-
-Error WSLServer::listen(int p_port, const Vector p_protocols, bool gd_mp_api) {
- ERR_FAIL_COND_V(is_listening(), ERR_ALREADY_IN_USE);
-
- _is_multiplayer = gd_mp_api;
- // Strip edges from protocols.
- _protocols.resize(p_protocols.size());
- String *pw = _protocols.ptrw();
- for (int i = 0; i < p_protocols.size(); i++) {
- pw[i] = p_protocols[i].strip_edges();
- }
- return _server->listen(p_port, bind_ip);
-}
-
-void WSLServer::poll() {
- List remove_ids;
- for (RBMap>::Element *E = _peer_map.front(); E; E = E->next()) {
- Ref peer = (WSLPeer *)E->get().ptr();
- peer->poll();
- if (!peer->is_connected_to_host()) {
- _on_disconnect(E->key(), peer->close_code != -1);
- remove_ids.push_back(E->key());
- }
- }
- for (List::Element *E = remove_ids.front(); E; E = E->next()) {
- _peer_map.erase(E->get());
- }
- remove_ids.clear();
-
- List][> remove_peers;
- for (List][>::Element *E = _pending.front(); E; E = E->next()) {
- Ref ppeer = E->get();
- Error err = ppeer->do_handshake(_protocols, handshake_timeout, _extra_headers);
- if (err == ERR_BUSY) {
- continue;
- } else if (err != OK) {
- remove_peers.push_back(ppeer);
- continue;
- }
- // Creating new peer
- int32_t id = _gen_unique_id();
-
- WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData);
- data->obj = this;
- data->conn = ppeer->connection;
- data->tcp = ppeer->tcp;
- data->is_server = true;
- data->id = id;
-
- Ref ws_peer = memnew(WSLPeer);
- ws_peer->make_context(data, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size);
- ws_peer->set_no_delay(true);
-
- _peer_map[id] = ws_peer;
- remove_peers.push_back(ppeer);
- _on_connect(id, ppeer->protocol);
- }
- for (List][>::Element *E = remove_peers.front(); E; E = E->next()) {
- _pending.erase(E->get());
- }
- remove_peers.clear();
-
- if (!_server->is_listening()) {
- return;
- }
-
- while (_server->is_connection_available()) {
- Ref conn = _server->take_connection();
- if (is_refusing_new_connections()) {
- continue; // Conn will go out-of-scope and be closed.
- }
-
- Ref peer = memnew(PendingPeer);
- if (private_key.is_valid() && ssl_cert.is_valid()) {
- Ref ssl = Ref(StreamPeerSSL::create());
- ssl->set_blocking_handshake_enabled(false);
- ssl->accept_stream(conn, private_key, ssl_cert, ca_chain);
- peer->connection = ssl;
- peer->use_ssl = true;
- } else {
- peer->connection = conn;
- }
- peer->tcp = conn;
- peer->time = OS::get_singleton()->get_ticks_msec();
- _pending.push_back(peer);
- }
-}
-
-bool WSLServer::is_listening() const {
- return _server->is_listening();
-}
-
-int WSLServer::get_max_packet_size() const {
- return (1 << _out_buf_size) - PROTO_SIZE;
-}
-
-void WSLServer::stop() {
- _server->stop();
- for (RBMap>::Element *E = _peer_map.front(); E; E = E->next()) {
- Ref peer = (WSLPeer *)E->get().ptr();
- peer->close_now();
- }
- _pending.clear();
- _peer_map.clear();
- _protocols.clear();
-}
-
-bool WSLServer::has_peer(int p_id) const {
- return _peer_map.has(p_id);
-}
-
-Ref WSLServer::get_peer(int p_id) const {
- ERR_FAIL_COND_V(!has_peer(p_id), nullptr);
- return _peer_map[p_id];
-}
-
-IP_Address WSLServer::get_peer_address(int p_peer_id) const {
- ERR_FAIL_COND_V(!has_peer(p_peer_id), IP_Address());
-
- return _peer_map[p_peer_id]->get_connected_host();
-}
-
-int WSLServer::get_peer_port(int p_peer_id) const {
- ERR_FAIL_COND_V(!has_peer(p_peer_id), 0);
-
- return _peer_map[p_peer_id]->get_connected_port();
-}
-
-void WSLServer::disconnect_peer(int p_peer_id, int p_code, String p_reason) {
- ERR_FAIL_COND(!has_peer(p_peer_id));
-
- get_peer(p_peer_id)->close(p_code, p_reason);
-}
-
-Error WSLServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) {
- ERR_FAIL_COND_V_MSG(_server->is_listening(), FAILED, "Buffers sizes can only be set before listening or connecting.");
-
- _in_buf_size = nearest_shift(p_in_buffer - 1) + 10;
- _in_pkt_size = nearest_shift(p_in_packets - 1);
- _out_buf_size = nearest_shift(p_out_buffer - 1) + 10;
- _out_pkt_size = nearest_shift(p_out_packets - 1);
- return OK;
-}
-
-WSLServer::WSLServer() {
- _in_buf_size = nearest_shift((int)GLOBAL_GET(WSS_IN_BUF) - 1) + 10;
- _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSS_IN_PKT) - 1);
- _out_buf_size = nearest_shift((int)GLOBAL_GET(WSS_OUT_BUF) - 1) + 10;
- _out_pkt_size = nearest_shift((int)GLOBAL_GET(WSS_OUT_PKT) - 1);
- _server.instance();
-}
-
-WSLServer::~WSLServer() {
- stop();
-}
-
-#endif // JAVASCRIPT_ENABLED
diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h
deleted file mode 100644
index 2a64dc6..0000000
--- a/modules/websocket/wsl_server.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef WSLSERVER_H
-#define WSLSERVER_H
-/*************************************************************************/
-/* wsl_server.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#ifndef JAVASCRIPT_ENABLED
-
-#include "websocket_server.h"
-#include "wsl_peer.h"
-
-#include "core/io/stream_peer_ssl.h"
-#include "core/io/stream_peer_tcp.h"
-#include "core/io/tcp_server.h"
-
-class WSLServer : public WebSocketServer {
- GDCIIMPL(WSLServer, WebSocketServer);
-
-private:
- class PendingPeer : public Reference {
- private:
- bool _parse_request(const Vector p_protocols);
-
- public:
- Ref tcp;
- Ref connection;
- bool use_ssl;
-
- uint64_t time;
- uint8_t req_buf[WSL_MAX_HEADER_SIZE];
- int req_pos;
- String key;
- String protocol;
- bool has_request;
- CharString response;
- int response_sent;
-
- PendingPeer();
-
- Error do_handshake(const Vector p_protocols, uint64_t p_timeout, const Vector &p_extra_headers);
- };
-
- int _in_buf_size;
- int _in_pkt_size;
- int _out_buf_size;
- int _out_pkt_size;
-
- List][> _pending;
- Ref _server;
- Vector _protocols;
- Vector _extra_headers;
-
-public:
- Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets);
- void set_extra_headers(const Vector &p_headers);
- Error listen(int p_port, const Vector p_protocols = Vector(), bool gd_mp_api = false);
- void stop();
- bool is_listening() const;
- int get_max_packet_size() const;
- bool has_peer(int p_id) const;
- Ref get_peer(int p_id) const;
- IP_Address get_peer_address(int p_peer_id) const;
- int get_peer_port(int p_peer_id) const;
- void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = "");
- virtual void poll();
-
- WSLServer();
- ~WSLServer();
-};
-
-#endif // JAVASCRIPT_ENABLED
-
-#endif // WSLSERVER_H
]