diff --git a/modules/blazium_sdk/config.py b/modules/blazium_sdk/config.py
index a973e6216753..ce39d90e6dfc 100644
--- a/modules/blazium_sdk/config.py
+++ b/modules/blazium_sdk/config.py
@@ -18,6 +18,9 @@ def get_doc_classes():
"ListLobbyResult",
"ViewLobbyResponse",
"ViewLobbyResult",
+ "AuthoritativeClient",
+ "LobbyCallResponse",
+ "LobbyCallResult",
]
diff --git a/modules/blazium_sdk/doc_classes/AuthoritativeClient.xml b/modules/blazium_sdk/doc_classes/AuthoritativeClient.xml
new file mode 100644
index 000000000000..8a289c3cbeee
--- /dev/null
+++ b/modules/blazium_sdk/doc_classes/AuthoritativeClient.xml
@@ -0,0 +1,24 @@
+
+
+
+ A lobby client that is authoritative.
+
+
+ A lobby client that is authoritative.
+
+
+
+
+
+
+
+
+
+ Call a method on the server.
+
+
+
+
+
+
+
diff --git a/modules/blazium_sdk/doc_classes/LobbyCallResponse.xml b/modules/blazium_sdk/doc_classes/LobbyCallResponse.xml
new file mode 100644
index 000000000000..7d2a3e4d16e0
--- /dev/null
+++ b/modules/blazium_sdk/doc_classes/LobbyCallResponse.xml
@@ -0,0 +1,19 @@
+
+
+
+ Response from a lobby call function.
+
+
+ Response from a lobby call function. Await on finished to get the [LobbyCallResult].
+
+
+
+
+
+
+
+ Signal emitted when the request is finished.
+
+
+
+
diff --git a/modules/blazium_sdk/doc_classes/LobbyCallResult.xml b/modules/blazium_sdk/doc_classes/LobbyCallResult.xml
new file mode 100644
index 000000000000..ce51a41d80ae
--- /dev/null
+++ b/modules/blazium_sdk/doc_classes/LobbyCallResult.xml
@@ -0,0 +1,30 @@
+
+
+
+ A result from a [LobbyCallResponse].
+
+
+ A result from a [LobbyCallResponse].
+
+
+
+
+
+
+
+ Result of the function call.
+
+
+
+
+
+ Returns true if there is an error.
+
+
+
+
+
+ Gets the error message.
+
+
+
diff --git a/modules/blazium_sdk/doc_classes/LobbyClient.xml b/modules/blazium_sdk/doc_classes/LobbyClient.xml
index 3c7bd788f9dc..89fa73adfb7e 100644
--- a/modules/blazium_sdk/doc_classes/LobbyClient.xml
+++ b/modules/blazium_sdk/doc_classes/LobbyClient.xml
@@ -1,10 +1,10 @@
- A node used to connect to a blazium lobby websocket server.
+ A node used to connect to a lobby server.
- A node used to connect to a lobby server. It can be used to do matchmaking. You care do operations such as create lobbys, join lobbys, etc.
+ A node used to connect to a lobby server. It can be used to do matchmaking. You can do operations such as create lobby, join lobby, etc. The server is configurable and can either be self deployed or you can use the blazium free matchmaking server.
@@ -12,24 +12,31 @@
- Connect to a Blazium Lobby Server using the game_id and [member server_url].
+ Connect to a Blazium Lobby Server using the [member game_id] and [member server_url].
-
+
Create a lobby and become host. If you are already in a lobby, you cannot create one. You need to leave first.
+ The new lobby can have a title, tags, max players and password. 0 max players means unlimited.
Generates [signal lobby_created] signal.
+
+
+
+ Disconnect from the lobby server.
+
+
- Returns true if you are the host.
+ Returns true if you are the host of the current lobby.
@@ -37,7 +44,8 @@
- Joint a lobby. If you are already in a lobby, you cannot join another one. You need to leave first.
+ Join a lobby. If you are already in a lobby, you cannot join another one. You need to leave first.
+ If the lobby you want to join is password protected, you need to provide the password.
Generates [signal lobby_joined].
@@ -58,38 +66,45 @@
-
-
-
-
-
+
+
+
- Lists all lobbies.
+ Lists all lobbies. Lobbies that are sealed won't show in the list, except if you disconnected and trying to reconnect to a lobby.
-
+
-
+
- Send a chat message.
- Generates [signal peer_messaged].
+ Send a notification either to the host, or if you are host send data to all peers.
+ Generates [signal lobby_notified] signal.
-
+
+
- Send data either to the host, or if you are host send data to all peers.
- Generates [signal received_data] signal.
+ Send a notification to a peer, works only if you are host.
+ Generates [signal lobby_notified] signal.
-
+
-
-
+
+
+ Send a chat message. Only works if you are in a lobby.
+ Generates [signal peer_messaged].
+
+
+
+
+
+
- Send data either to a peer, works only if you are host.
- Generates [signal received_data_to] signal.
+ Set data on the lobby. Only works if you are host.
+ Generates [signal received_lobby_data].
@@ -108,6 +123,24 @@
Generates [signal lobby_sealed].
+
+
+
+
+ Set tags on the lobby. Only works if you are host.
+ Generates [signal lobby_tagged].
+
+
+
+
+
+
+
+
+ Set data on the peer. Only works if you are host.
+ Generates [signal received_peer_data] signal if you are in lobby.
+
+
@@ -116,6 +149,15 @@
Generates [signal peer_named] signal if you are in lobby.
+
+
+
+
+
+ Set data on the peers. Only works if you are host.
+ Generates [signal received_peer_data] signal if you are in lobby.
+
+
@@ -130,6 +172,10 @@
True if the client is connected, else false.
+ The game id.
+
+
+ The current lobby private data. Only works if you are host.
The current lobby. Reflects changes to the lobby.
@@ -137,6 +183,9 @@
The current peer. Reflects changes to the self peer.
+
+ The current peer private data.
+
The lobby peers. Reflects changes to all peers.
@@ -181,12 +230,25 @@
Signal generated after you leave a lobby.
+
+
+
+
+ Signal generated after a notification is received.
+
+
Signal generated after the host seals the lobby.
+
+
+
+ Signal generated after the host updated the tags of the lobby
+
+
@@ -228,7 +290,7 @@
-
+
Signal generated after a peer is ready.
@@ -239,18 +301,19 @@
Signal generated after a peer reconnects.
-
+
-
+
- Signal generated after a lobby_data call.
+ Signal generated after data is sent to the lobby.
-
+
-
+
+
- Signal generated after a data_to call.
+ Signal generated after data is sent to peer.
diff --git a/modules/blazium_sdk/doc_classes/LobbyInfo.xml b/modules/blazium_sdk/doc_classes/LobbyInfo.xml
index b3258e190c07..a21571197e12 100644
--- a/modules/blazium_sdk/doc_classes/LobbyInfo.xml
+++ b/modules/blazium_sdk/doc_classes/LobbyInfo.xml
@@ -9,6 +9,9 @@
+
+ The lobby public data.
+
The host id of the lobby.
@@ -22,7 +25,7 @@
The name of the lobby.
- The maximum number of players allowed in the lobby.
+ The maximum number of players allowed in the lobby. 0 = unlimited
@@ -32,7 +35,7 @@
Whether the lobby is sealed.
-
+
The tags of the lobby. Used for listing lobbies to filter based on them.
diff --git a/modules/blazium_sdk/doc_classes/LobbyPeer.xml b/modules/blazium_sdk/doc_classes/LobbyPeer.xml
index 858ecccc7dee..36cf1f1e7ad1 100644
--- a/modules/blazium_sdk/doc_classes/LobbyPeer.xml
+++ b/modules/blazium_sdk/doc_classes/LobbyPeer.xml
@@ -9,6 +9,8 @@
+
+
Identifier of the peer.
diff --git a/modules/blazium_sdk/icons/AuthoritativeClient.svg b/modules/blazium_sdk/icons/AuthoritativeClient.svg
new file mode 100644
index 000000000000..e000cd5827ab
--- /dev/null
+++ b/modules/blazium_sdk/icons/AuthoritativeClient.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/modules/blazium_sdk/lobby/authoritative_client.cpp b/modules/blazium_sdk/lobby/authoritative_client.cpp
new file mode 100644
index 000000000000..474bd91093a4
--- /dev/null
+++ b/modules/blazium_sdk/lobby/authoritative_client.cpp
@@ -0,0 +1,26 @@
+#include "authoritative_client.h"
+
+Ref AuthoritativeClient::lobby_call(const String &p_method, const Array &p_args) {
+ String id = _increment_counter();
+ Dictionary command;
+ command["command"] = "lobby_call";
+ Dictionary data_dict;
+ data_dict["function"] = p_method;
+ data_dict["inputs"] = p_args;
+ command["data"] = data_dict;
+ Array command_array;
+ Ref response;
+ response.instantiate();
+ command_array.push_back(LobbyClient::LOBBY_CALL);
+ command_array.push_back(response);
+ _commands[id] = command_array;
+ _send_data(command);
+ return response;
+}
+
+void AuthoritativeClient::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("lobby_call", "method", "args"), &AuthoritativeClient::lobby_call);
+ ADD_PROPERTY_DEFAULT("peers", TypedArray());
+ ADD_PROPERTY_DEFAULT("peer", Ref());
+ ADD_PROPERTY_DEFAULT("lobby", Ref());
+}
diff --git a/modules/blazium_sdk/lobby/authoritative_client.h b/modules/blazium_sdk/lobby/authoritative_client.h
new file mode 100644
index 000000000000..c165218c8961
--- /dev/null
+++ b/modules/blazium_sdk/lobby/authoritative_client.h
@@ -0,0 +1,83 @@
+/**************************************************************************/
+/* lobby_client.h */
+/**************************************************************************/
+/* This file is part of: */
+/* BLAZIUM ENGINE */
+/* https://blazium.app */
+/**************************************************************************/
+/* Copyright (c) 2024-present Blazium Engine contributors. */
+/* Copyright (c) 2024 Dragos Daian, Randolph William Aarseth II. */
+/* */
+/* 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 AUTHORITATIVE_CLIENT_H
+#define AUTHORITATIVE_CLIENT_H
+
+#include "lobby_client.h"
+
+class AuthoritativeClient : public LobbyClient {
+ GDCLASS(AuthoritativeClient, LobbyClient);
+
+public:
+ class LobbyCallResponse : public RefCounted {
+ GDCLASS(LobbyCallResponse, RefCounted);
+
+ protected:
+ static void _bind_methods() {
+ ADD_SIGNAL(MethodInfo("finished", PropertyInfo(Variant::OBJECT, "result", PROPERTY_HINT_RESOURCE_TYPE, "LobbyCallResult")));
+ }
+
+ public:
+ class LobbyCallResult : public RefCounted {
+ GDCLASS(LobbyCallResult, RefCounted);
+ Variant result;
+ String error;
+
+ protected:
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("has_error"), &LobbyCallResult::has_error);
+ ClassDB::bind_method(D_METHOD("get_error"), &LobbyCallResult::get_error);
+ ClassDB::bind_method(D_METHOD("get_result"), &LobbyCallResult::get_result);
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "error"), "", "get_error");
+ }
+
+ public:
+ void set_error(String p_error) { this->error = p_error; }
+ void set_result(Variant p_result) { this->result = p_result; }
+
+ bool has_error() const { return !error.is_empty(); }
+ String get_error() const { return error; }
+ Variant get_result() const { return result; }
+ };
+ };
+
+protected:
+ static void _bind_methods();
+
+public:
+ Ref lobby_call(const String &p_method, const Array &p_args);
+
+ AuthoritativeClient() {
+ server_url = "wss://authlobby.blazium.app/connect";
+ }
+};
+
+#endif // AUTHORITATIVE_CLIENT_H
diff --git a/modules/blazium_sdk/lobby/lobby_client.cpp b/modules/blazium_sdk/lobby/lobby_client.cpp
index b50379195bd3..66ed20008a4b 100644
--- a/modules/blazium_sdk/lobby/lobby_client.cpp
+++ b/modules/blazium_sdk/lobby/lobby_client.cpp
@@ -29,8 +29,10 @@
/**************************************************************************/
#include "./lobby_client.h"
+#include "./authoritative_client.h"
#include "scene/main/node.h"
LobbyClient::LobbyClient() {
+ server_url = "wss://lobby.blazium.app/connect";
lobby.instantiate();
peer.instantiate();
_socket = Ref(WebSocketPeer::create());
@@ -55,6 +57,8 @@ void LobbyClient::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_lobby"), &LobbyClient::get_lobby);
ClassDB::bind_method(D_METHOD("get_peer"), &LobbyClient::get_peer);
ClassDB::bind_method(D_METHOD("get_peers"), &LobbyClient::get_peers);
+ ClassDB::bind_method(D_METHOD("get_host_data"), &LobbyClient::get_host_data);
+ ClassDB::bind_method(D_METHOD("get_peer_data"), &LobbyClient::get_peer_data);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "server_url", PROPERTY_HINT_NONE, ""), "set_server_url", "get_server_url");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "reconnection_token", PROPERTY_HINT_NONE, ""), "set_reconnection_token", "get_reconnection_token");
@@ -63,40 +67,49 @@ void LobbyClient::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "lobby", PROPERTY_HINT_RESOURCE_TYPE, "LobbyInfo"), "", "get_lobby");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer"), "", "get_peer");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "peers", PROPERTY_HINT_ARRAY_TYPE, "LobbyPeer"), "", "get_peers");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "host_data"), "", "get_host_data");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "peer_data"), "", "get_peer_data");
ADD_PROPERTY_DEFAULT("peers", TypedArray());
ADD_PROPERTY_DEFAULT("peer", Ref());
ADD_PROPERTY_DEFAULT("lobby", Ref());
// Register methods
ClassDB::bind_method(D_METHOD("connect_to_lobby"), &LobbyClient::connect_to_lobby);
+ ClassDB::bind_method(D_METHOD("disconnect_from_lobby"), &LobbyClient::disconnect_from_lobby);
ClassDB::bind_method(D_METHOD("set_peer_name", "peer_name"), &LobbyClient::set_peer_name);
- ClassDB::bind_method(D_METHOD("create_lobby", "title", "tags", "max_players", "password"), &LobbyClient::create_lobby, DEFVAL(Array()), DEFVAL(4), DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("create_lobby", "title", "tags", "max_players", "password"), &LobbyClient::create_lobby, DEFVAL(Dictionary()), DEFVAL(4), DEFVAL(""));
ClassDB::bind_method(D_METHOD("join_lobby", "lobby_id", "password"), &LobbyClient::join_lobby, DEFVAL(""));
ClassDB::bind_method(D_METHOD("leave_lobby"), &LobbyClient::leave_lobby);
- ClassDB::bind_method(D_METHOD("list_lobbies", "title", "max_players", "tags", "start", "count"), &LobbyClient::list_lobby, DEFVAL(""), DEFVAL(-1), DEFVAL(Array()), DEFVAL(0), DEFVAL(10));
+ ClassDB::bind_method(D_METHOD("list_lobbies", "tags", "start", "count"), &LobbyClient::list_lobby, DEFVAL(Dictionary()), DEFVAL(0), DEFVAL(10));
ClassDB::bind_method(D_METHOD("view_lobby", "lobby_id", "password"), &LobbyClient::view_lobby, DEFVAL(""), DEFVAL(""));
ClassDB::bind_method(D_METHOD("kick_peer", "peer_id"), &LobbyClient::kick_peer);
ClassDB::bind_method(D_METHOD("send_chat_message", "chat_message"), &LobbyClient::lobby_chat);
ClassDB::bind_method(D_METHOD("set_lobby_ready", "ready"), &LobbyClient::lobby_ready);
+ ClassDB::bind_method(D_METHOD("set_lobby_tags", "tags"), &LobbyClient::set_lobby_tags);
ClassDB::bind_method(D_METHOD("set_lobby_sealed", "seal"), &LobbyClient::seal_lobby);
- ClassDB::bind_method(D_METHOD("send_lobby_data", "data"), &LobbyClient::lobby_data);
- ClassDB::bind_method(D_METHOD("send_lobby_data_to", "data", "target_peer"), &LobbyClient::lobby_data_to);
+ ClassDB::bind_method(D_METHOD("notify_lobby", "data"), &LobbyClient::lobby_notify);
+ ClassDB::bind_method(D_METHOD("notify_peer", "data", "target_peer"), &LobbyClient::peer_notify);
+ ClassDB::bind_method(D_METHOD("set_lobby_data", "data", "is_private"), &LobbyClient::lobby_data, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("set_peer_data", "data", "target_peer", "is_private"), &LobbyClient::set_peer_data);
+ ClassDB::bind_method(D_METHOD("set_peers_data", "data", "is_private"), &LobbyClient::set_peers_data);
// Register signals
ADD_SIGNAL(MethodInfo("connected_to_lobby", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer"), PropertyInfo(Variant::STRING, "reconnection_token")));
ADD_SIGNAL(MethodInfo("disconnected_from_lobby", PropertyInfo(Variant::STRING, "reason")));
ADD_SIGNAL(MethodInfo("peer_named", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer")));
- ADD_SIGNAL(MethodInfo("received_data", PropertyInfo(Variant::OBJECT, "data"), PropertyInfo(Variant::OBJECT, "from_peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer")));
- ADD_SIGNAL(MethodInfo("received_data_to", PropertyInfo(Variant::OBJECT, "data"), PropertyInfo(Variant::OBJECT, "from_peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer")));
+ ADD_SIGNAL(MethodInfo("lobby_notified", PropertyInfo(Variant::OBJECT, "data"), PropertyInfo(Variant::OBJECT, "from_peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer")));
+ ADD_SIGNAL(MethodInfo("received_peer_data", PropertyInfo(Variant::OBJECT, "data"), PropertyInfo(Variant::OBJECT, "to_peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer"), PropertyInfo(Variant::BOOL, "is_private")));
+ ADD_SIGNAL(MethodInfo("received_lobby_data", PropertyInfo(Variant::OBJECT, "data"), PropertyInfo(Variant::BOOL, "is_private")));
ADD_SIGNAL(MethodInfo("lobby_created", PropertyInfo(Variant::OBJECT, "lobby", PROPERTY_HINT_RESOURCE_TYPE, "LobbyInfo"), PropertyInfo(Variant::ARRAY, "peers", PROPERTY_HINT_ARRAY_TYPE, "LobbyPeer")));
ADD_SIGNAL(MethodInfo("lobby_joined", PropertyInfo(Variant::OBJECT, "lobby", PROPERTY_HINT_RESOURCE_TYPE, "LobbyInfo"), PropertyInfo(Variant::ARRAY, "peers", PROPERTY_HINT_ARRAY_TYPE, "LobbyPeer")));
ADD_SIGNAL(MethodInfo("lobby_left", PropertyInfo(Variant::BOOL, "kicked")));
ADD_SIGNAL(MethodInfo("lobby_sealed", PropertyInfo(Variant::BOOL, "sealed")));
+ ADD_SIGNAL(MethodInfo("lobby_tagged", PropertyInfo(Variant::DICTIONARY, "tags")));
ADD_SIGNAL(MethodInfo("peer_joined", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer")));
ADD_SIGNAL(MethodInfo("peer_reconnected", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer")));
ADD_SIGNAL(MethodInfo("peer_left", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer"), PropertyInfo(Variant::BOOL, "kicked")));
ADD_SIGNAL(MethodInfo("peer_disconnected", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer")));
ADD_SIGNAL(MethodInfo("peer_messaged", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer"), PropertyInfo(Variant::STRING, "chat_message")));
- ADD_SIGNAL(MethodInfo("peer_ready", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer"), PropertyInfo(Variant::BOOL, "ready")));
+ ADD_SIGNAL(MethodInfo("peer_ready", PropertyInfo(Variant::OBJECT, "peer", PROPERTY_HINT_RESOURCE_TYPE, "LobbyPeer"), PropertyInfo(Variant::BOOL, "is_ready")));
ADD_SIGNAL(MethodInfo("log_updated", PropertyInfo(Variant::STRING, "command"), PropertyInfo(Variant::STRING, "logs")));
}
@@ -127,8 +140,13 @@ bool LobbyClient::connect_to_lobby() {
void LobbyClient::disconnect_from_lobby() {
if (connected) {
- _socket->close();
+ _socket->close(1000, "Normal Closure");
connected = false;
+ host_data = Dictionary();
+ peer_data = Dictionary();
+ peer->set_data(Dictionary());
+ peers.clear();
+ lobby->set_data(Dictionary());
set_process_internal(false);
emit_signal("disconnected_from_lobby", _socket->get_close_reason());
emit_signal("log_updated", "disconnect_from_lobby", "Disconnected from: " + get_server_url());
@@ -139,7 +157,7 @@ String LobbyClient::_increment_counter() {
return String::num(_counter++);
}
-Ref LobbyClient::create_lobby(const String &p_lobby_name, const TypedArray &p_tags, int p_max_players, const String &p_password) {
+Ref LobbyClient::create_lobby(const String &p_lobby_name, const Dictionary &p_tags, int p_max_players, const String &p_password) {
String id = _increment_counter();
Dictionary command;
command["command"] = "create_lobby";
@@ -196,7 +214,7 @@ Ref LobbyClient::leave_lobby() {
return response;
}
-Ref LobbyClient::list_lobby(const String &p_title, const int p_max_players, const TypedArray &p_tags, int p_start, int p_count) {
+Ref LobbyClient::list_lobby(const Dictionary &p_tags, int p_start, int p_count) {
String id = _increment_counter();
Dictionary command;
command["command"] = "list_lobby";
@@ -209,12 +227,6 @@ Ref LobbyClient::list_lobby(const String &p_titl
if (p_tags.size() != 0) {
filter_dict["tags"] = p_tags;
}
- if (!p_title.is_empty()) {
- filter_dict["name"] = p_title;
- }
- if (p_max_players != -1) {
- filter_dict["max_players"] = int(p_max_players);
- }
command["data"] = data_dict;
Array command_array;
Ref response;
@@ -267,6 +279,24 @@ Ref LobbyClient::kick_peer(const String &p_peer_id)
return response;
}
+Ref LobbyClient::set_lobby_tags(const Dictionary &p_tags) {
+ String id = _increment_counter();
+ Dictionary command;
+ command["command"] = "lobby_tags";
+ Dictionary data_dict;
+ command["data"] = data_dict;
+ data_dict["tags"] = p_tags;
+ data_dict["id"] = id;
+ Array command_array;
+ Ref response;
+ response.instantiate();
+ command_array.push_back(LOBBY_REQUEST);
+ command_array.push_back(response);
+ _commands[id] = command_array;
+ _send_data(command);
+ return response;
+}
+
Ref LobbyClient::lobby_chat(const String &p_chat_message) {
String id = _increment_counter();
Dictionary command;
@@ -345,10 +375,10 @@ Ref LobbyClient::seal_lobby(bool seal) {
return response;
}
-Ref LobbyClient::lobby_data(const Variant &p_peer_data) {
+Ref LobbyClient::lobby_notify(const Variant &p_peer_data) {
String id = _increment_counter();
Dictionary command;
- command["command"] = "lobby_data";
+ command["command"] = "lobby_notify";
Dictionary data_dict;
data_dict["peer_data"] = p_peer_data;
data_dict["id"] = id;
@@ -363,13 +393,71 @@ Ref LobbyClient::lobby_data(const Variant &p_peer_da
return response;
}
-Ref LobbyClient::lobby_data_to(const Variant &p_peer_data, const String &p_target_peer) {
+Ref LobbyClient::peer_notify(const Variant &p_peer_data, const String &p_target_peer) {
+ String id = _increment_counter();
+ Dictionary command;
+ command["command"] = "notify_to";
+ Dictionary data_dict;
+ data_dict["peer_data"] = p_peer_data;
+ data_dict["target_peer"] = p_target_peer;
+ data_dict["id"] = id;
+ command["data"] = data_dict;
+ Array command_array;
+ Ref response;
+ response.instantiate();
+ command_array.push_back(LOBBY_REQUEST);
+ command_array.push_back(response);
+ _commands[id] = command_array;
+ _send_data(command);
+ return response;
+}
+
+Ref LobbyClient::lobby_data(const Dictionary &p_lobby_data, bool p_is_private) {
+ String id = _increment_counter();
+ Dictionary command;
+ command["command"] = "lobby_data";
+ Dictionary data_dict;
+ data_dict["lobby_data"] = p_lobby_data;
+ data_dict["is_private"] = p_is_private;
+ data_dict["id"] = id;
+ command["data"] = data_dict;
+ Array command_array;
+ Ref response;
+ response.instantiate();
+ command_array.push_back(LOBBY_REQUEST);
+ command_array.push_back(response);
+ _commands[id] = command_array;
+ _send_data(command);
+ return response;
+}
+
+Ref LobbyClient::set_peer_data(const Dictionary &p_peer_data, const String &p_target_peer, bool p_is_private) {
String id = _increment_counter();
Dictionary command;
command["command"] = "data_to";
Dictionary data_dict;
data_dict["peer_data"] = p_peer_data;
data_dict["target_peer"] = p_target_peer;
+ data_dict["is_private"] = p_is_private;
+ data_dict["id"] = id;
+ command["data"] = data_dict;
+ Array command_array;
+ Ref response;
+ response.instantiate();
+ command_array.push_back(LOBBY_REQUEST);
+ command_array.push_back(response);
+ _commands[id] = command_array;
+ _send_data(command);
+ return response;
+}
+
+Ref LobbyClient::set_peers_data(const Dictionary &p_peer_data, bool p_is_private) {
+ String id = _increment_counter();
+ Dictionary command;
+ command["command"] = "data_to_all";
+ Dictionary data_dict;
+ data_dict["peer_data"] = p_peer_data;
+ data_dict["is_private"] = p_is_private;
data_dict["id"] = id;
command["data"] = data_dict;
Array command_array;
@@ -449,21 +537,16 @@ void sort_peers_by_id(TypedArray &peers) {
void LobbyClient::_receive_data(const Dictionary &p_dict) {
String command = p_dict.get("command", "error");
- String message = p_dict.get("message", command);
+ String message = p_dict.get("message", "");
Dictionary data_dict = p_dict.get("data", Dictionary());
String message_id = data_dict.get("id", "");
Array command_array = _commands.get(message_id, Array());
_commands.erase(message_id);
- emit_signal("log_updated", command, message);
if (command_array.size() == 2 && command != "error") {
int command_type = command_array[0];
switch (command_type) {
case LOBBY_REQUEST: {
- Ref response = command_array[1];
- if (response.is_valid()) {
- Ref result = Ref(memnew(LobbyResponse::LobbyResult));
- response->emit_signal("finished", result);
- }
+ // nothing to update, will notify at the end
} break;
case LOBBY_VIEW: {
Dictionary lobby_dict = data_dict.get("lobby", Dictionary());
@@ -477,17 +560,10 @@ void LobbyClient::_receive_data(const Dictionary &p_dict) {
if (lobby_info->get_id() == lobby->get_id()) {
// Update lobby info because we viewed our own lobby
lobby->set_dict(lobby_info->get_dict());
- peers = peers_info;
- }
- if (command_array.size() == 2) {
- Ref response = command_array[1];
- if (response.is_valid()) {
- Ref result;
- result.instantiate();
- result->set_peers(peers_info);
- result->set_lobby(lobby_info);
- response->emit_signal("finished", result);
+ if (lobby_dict.has("private_data")) {
+ host_data = lobby_dict.get("private_data", Dictionary());
}
+ peers = peers_info;
}
} break;
}
@@ -496,6 +572,7 @@ void LobbyClient::_receive_data(const Dictionary &p_dict) {
Dictionary peer_dict = data_dict.get("peer", Dictionary());
peer->set_dict(peer_dict);
reconnection_token = peer_dict.get("reconnection_token", "");
+ peer_data = peer_dict.get("private_data", Dictionary());
emit_signal("connected_to_lobby", peer, reconnection_token);
} else if (command == "lobby_created") {
lobby->set_dict(data_dict.get("lobby", Dictionary()));
@@ -510,10 +587,14 @@ void LobbyClient::_receive_data(const Dictionary &p_dict) {
} else if (command == "lobby_left") {
lobby->set_dict(Dictionary());
peers.clear();
+ host_data = Dictionary();
+ peer_data = Dictionary();
emit_signal("lobby_left", false);
} else if (command == "lobby_kicked") {
lobby->set_dict(Dictionary());
peers.clear();
+ host_data = Dictionary();
+ peer_data = Dictionary();
emit_signal("lobby_left", true);
} else if (command == "lobby_sealed") {
Dictionary lobby_dict = data_dict.get("lobby", Dictionary());
@@ -522,6 +603,9 @@ void LobbyClient::_receive_data(const Dictionary &p_dict) {
} else if (command == "lobby_unsealed") {
lobby->set_sealed(false);
emit_signal("lobby_sealed", false);
+ } else if (command == "lobby_tags") {
+ lobby->set_tags(data_dict.get("tags", Dictionary()));
+ emit_signal("lobby_tagged", lobby->get_tags());
} else if (command == "lobby_list") {
Array arr = data_dict.get("lobbies", Array());
TypedArray lobbies_input = arr;
@@ -638,28 +722,67 @@ void LobbyClient::_receive_data(const Dictionary &p_dict) {
}
}
sort_peers_by_id(peers);
- } else if (command == "lobby_data") {
+ } else if (command == "peer_notify") {
String from_peer_id = data_dict.get("from_peer", "");
for (int i = 0; i < peers.size(); ++i) {
Ref from_peer = peers[i];
if (from_peer->get_id() == from_peer_id) {
- emit_signal("received_data", data_dict.get("peer_data", Variant()), from_peer);
+ emit_signal("lobby_notified", data_dict.get("peer_data", Variant()), from_peer);
break;
}
}
+ } else if (command == "lobby_data") {
+ Dictionary lobby_data = data_dict.get("lobby_data", Dictionary());
+ bool is_private = data_dict.get("is_private", false);
+ if (is_private) {
+ host_data = lobby_data;
+ } else {
+ lobby->set_data(lobby_data);
+ }
+ emit_signal("received_lobby_data", lobby_data, is_private);
+ // nothing for now
} else if (command == "data_to") {
+ String target_peer_id = data_dict.get("target_peer", "");
+ bool is_private = data_dict.get("is_private", false);
+ Dictionary peer_data_variant = data_dict.get("peer_data", Dictionary());
+ for (int i = 0; i < peers.size(); ++i) {
+ Ref updated_peer = peers[i];
+ if (updated_peer->get_id() == target_peer_id) {
+ // got peer data, update it
+ if (is_private && target_peer_id == peer->get_id()) {
+ // private data, update self
+ peer_data = peer_data_variant;
+ } else {
+ // public peer data
+ updated_peer->set_data(peer_data_variant);
+ }
+ emit_signal("received_peer_data", peer_data_variant, updated_peer, is_private);
+ break;
+ }
+ }
+ } else if (command == "lobby_call") {
+ // authoritative call
+ Ref response = command_array[1];
+ if (response.is_valid()) {
+ Ref result = Ref(memnew(AuthoritativeClient::LobbyCallResponse::LobbyCallResult));
+ result->set_result(data_dict.get("result", ""));
+ response->emit_signal("finished", result);
+ }
+ } else if (command == "notified_to") {
String from_peer_id = data_dict.get("from_peer", "");
for (int i = 0; i < peers.size(); ++i) {
Ref from_peer = peers[i];
if (from_peer->get_id() == from_peer_id) {
- emit_signal("received_data_to", data_dict.get("peer_data", Variant()), from_peer);
+ emit_signal("lobby_notified", data_dict.get("peer_data", Variant()), from_peer);
break;
}
}
- } else if (command == "lobby_data_sent") {
- // nothing for now
} else if (command == "data_to_sent") {
// nothing for now
+ } else if (command == "lobby_notify_sent") {
+ // nothing for now
+ } else if (command == "notify_to_sent") {
+ // nothing for now
} else if (command == "error") {
if (command_array.size() == 2) {
int command_type = command_array[0];
@@ -691,6 +814,16 @@ void LobbyClient::_receive_data(const Dictionary &p_dict) {
view_response->emit_signal("finished", result);
}
} break;
+ // From AuthoritativeClient
+ case LOBBY_CALL: {
+ Ref view_response = command_array[1];
+ if (view_response.is_valid()) {
+ Ref result;
+ result.instantiate();
+ result->set_error(message);
+ view_response->emit_signal("finished", result);
+ }
+ } break;
default: {
emit_signal("log_updated", "error", p_dict["message"]);
} break;
@@ -699,4 +832,36 @@ void LobbyClient::_receive_data(const Dictionary &p_dict) {
} else {
emit_signal("log_updated", "error", "Unknown command received.");
}
+ emit_signal("log_updated", command, message);
+ if (command_array.size() == 2 && command != "error") {
+ int command_type = command_array[0];
+ switch (command_type) {
+ case LOBBY_REQUEST: {
+ Ref response = command_array[1];
+ if (response.is_valid()) {
+ Ref result = Ref(memnew(LobbyResponse::LobbyResult));
+ response->emit_signal("finished", result);
+ }
+ } break;
+ case LOBBY_VIEW: {
+ Dictionary lobby_dict = data_dict.get("lobby", Dictionary());
+
+ // Iterate through peers and populate arrays
+ TypedArray peers_info;
+ update_peers(data_dict, peers_info);
+ sort_peers_by_id(peers_info);
+ Ref lobby_info = Ref(memnew(LobbyInfo));
+ lobby_info->set_dict(lobby_dict);
+ // notify
+ Ref response = command_array[1];
+ if (response.is_valid()) {
+ Ref result;
+ result.instantiate();
+ result->set_peers(peers_info);
+ result->set_lobby(lobby_info);
+ response->emit_signal("finished", result);
+ }
+ } break;
+ }
+ }
}
diff --git a/modules/blazium_sdk/lobby/lobby_client.h b/modules/blazium_sdk/lobby/lobby_client.h
index 95d65154f6b3..c3eae420b0d5 100644
--- a/modules/blazium_sdk/lobby/lobby_client.h
+++ b/modules/blazium_sdk/lobby/lobby_client.h
@@ -41,7 +41,8 @@ class LobbyInfo : public Resource {
String lobby_name;
String host;
String host_name;
- TypedArray tags;
+ Dictionary tags;
+ Dictionary data;
int max_players = 0;
int players = 0;
bool sealed = false;
@@ -58,9 +59,11 @@ class LobbyInfo : public Resource {
ClassDB::bind_method(D_METHOD("get_host_name"), &LobbyInfo::get_host_name);
ClassDB::bind_method(D_METHOD("get_players"), &LobbyInfo::get_players);
ClassDB::bind_method(D_METHOD("get_tags"), &LobbyInfo::get_tags);
+ ClassDB::bind_method(D_METHOD("get_data"), &LobbyInfo::get_data);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "id"), "", "get_id");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "tags"), "", "get_tags");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data"), "", "get_data");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "lobby_name"), "", "get_lobby_name");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "host_name"), "", "get_host_name");
ADD_PROPERTY(PropertyInfo(Variant::INT, "players"), "", "get_players");
@@ -79,7 +82,8 @@ class LobbyInfo : public Resource {
void set_players(int p_players) { this->players = p_players; }
void set_sealed(bool p_sealed) { this->sealed = p_sealed; }
void set_password_protected(bool p_password_protected) { this->password_protected = p_password_protected; }
- void set_tags(const TypedArray &p_tags) { this->tags = p_tags; }
+ void set_tags(const Dictionary &p_tags) { this->tags = p_tags; }
+ void set_data(const Dictionary &p_data) { this->data = p_data; }
void set_dict(const Dictionary &p_dict) {
this->set_host(p_dict.get("host", ""));
@@ -90,7 +94,8 @@ class LobbyInfo : public Resource {
this->set_lobby_name(p_dict.get("name", ""));
this->set_host_name(p_dict.get("host_name", ""));
this->set_password_protected(p_dict.get("has_password", false));
- this->set_tags(p_dict.get("tags", TypedArray()));
+ this->set_tags(p_dict.get("tags", Dictionary()));
+ this->set_data(p_dict.get("public_data", Dictionary()));
}
Dictionary get_dict() const {
Dictionary dict;
@@ -103,10 +108,12 @@ class LobbyInfo : public Resource {
dict["host_name"] = this->get_host_name();
dict["has_password"] = this->is_password_protected();
dict["tags"] = this->get_tags();
+ dict["public_data"] = this->get_data();
return dict;
}
- TypedArray get_tags() const { return tags; }
+ Dictionary get_data() const { return data; }
+ Dictionary get_tags() const { return tags; }
String get_id() const { return id; }
String get_lobby_name() const { return lobby_name; }
String get_host() const { return host; }
@@ -123,34 +130,41 @@ class LobbyPeer : public Resource {
String id;
String peer_name;
bool ready = false;
+ Dictionary data;
protected:
static void _bind_methods() {
ClassDB::bind_method(D_METHOD("get_id"), &LobbyPeer::get_id);
ClassDB::bind_method(D_METHOD("get_peer_name"), &LobbyPeer::get_peer_name);
ClassDB::bind_method(D_METHOD("is_ready"), &LobbyPeer::is_ready);
+ ClassDB::bind_method(D_METHOD("get_data"), &LobbyPeer::get_data);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "id"), "", "get_id");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "peer_name"), "", "get_peer_name");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ready"), "", "is_ready");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data"), "", "get_data");
}
public:
void set_id(const String &p_id) { this->id = p_id; }
void set_peer_name(const String &p_peer_name) { this->peer_name = p_peer_name; }
void set_ready(bool p_ready) { this->ready = p_ready; }
+ void set_data(const Dictionary &p_data) { this->data = p_data; }
void set_dict(const Dictionary &p_dict) {
this->set_id(p_dict.get("id", ""));
this->set_peer_name(p_dict.get("name", ""));
this->set_ready(p_dict.get("ready", ""));
+ this->set_data(p_dict.get("public_data", Dictionary()));
}
Dictionary get_dict() const {
Dictionary dict;
dict["id"] = this->get_id();
dict["name"] = this->get_peer_name();
dict["ready"] = this->is_ready();
+ dict["public_data"] = this->get_data();
return dict;
}
+ Dictionary get_data() const { return data; }
String get_id() const { return id; }
String get_peer_name() const { return peer_name; }
bool is_ready() const { return ready; }
@@ -159,14 +173,13 @@ class LobbyPeer : public Resource {
class LobbyClient : public BlaziumClient {
GDCLASS(LobbyClient, BlaziumClient);
- enum CommandType {
- LOBBY_REQUEST = 0,
- LOBBY_VIEW,
- LOBBY_LIST
- };
- String server_url = "wss://lobby.blazium.app/connect";
+
+protected:
+ String server_url;
String reconnection_token;
String game_id = "";
+ Dictionary host_data;
+ Dictionary peer_data;
Ref lobby;
Ref peer;
TypedArray peers;
@@ -198,9 +211,6 @@ class LobbyClient : public BlaziumClient {
bool has_error() const { return !error.is_empty(); }
String get_error() const { return error; }
- LobbyResult(const LobbyResult &p_other) :
- error(p_other.error) {}
- LobbyResult() {}
};
};
@@ -236,9 +246,6 @@ class LobbyClient : public BlaziumClient {
bool has_error() const { return !error.is_empty(); }
String get_error() const { return error; }
TypedArray get_lobbies() const { return lobbies; }
- ListLobbyResult(const ListLobbyResult &p_other) :
- error(p_other.error), lobbies(p_other.lobbies) {}
- ListLobbyResult() {}
};
};
@@ -287,7 +294,7 @@ class LobbyClient : public BlaziumClient {
};
};
-private:
+protected:
Ref _socket;
int _counter = 0;
bool connected = false;
@@ -297,7 +304,13 @@ class LobbyClient : public BlaziumClient {
void _send_data(const Dictionary &p_data);
String _increment_counter();
-protected:
+ enum CommandType {
+ LOBBY_REQUEST = 0,
+ LOBBY_VIEW,
+ LOBBY_LIST,
+ LOBBY_CALL
+ };
+
void _notification(int p_notification);
static void _bind_methods();
@@ -310,6 +323,8 @@ class LobbyClient : public BlaziumClient {
String get_game_id() { return game_id; }
bool is_host() { return lobby->get_host() == peer->get_id(); }
bool get_connected() { return connected; }
+ Dictionary get_host_data() { return host_data; }
+ Dictionary get_peer_data() { return peer_data; }
void set_lobby(const Ref &p_lobby) { this->lobby = p_lobby; }
Ref get_lobby() { return lobby; }
void set_peer(const Ref &p_peer) { this->peer = p_peer; }
@@ -318,18 +333,23 @@ class LobbyClient : public BlaziumClient {
bool connect_to_lobby();
void disconnect_from_lobby();
- Ref create_lobby(const String &p_lobby_name, const TypedArray &p_tags, int p_max_players, const String &p_password);
+ Ref create_lobby(const String &p_lobby_name, const Dictionary &p_tags, int p_max_players, const String &p_password);
Ref join_lobby(const String &p_lobby_id, const String &p_password);
Ref leave_lobby();
- Ref list_lobby(const String &p_title, const int p_max_players, const TypedArray &p_tags, int p_start, int p_count);
+ Ref list_lobby(const Dictionary &p_tags, int p_start, int p_count);
Ref view_lobby(const String &p_lobby_id, const String &p_password);
Ref kick_peer(const String &p_peer_id);
+ Ref set_lobby_tags(const Dictionary &p_tags);
Ref lobby_chat(const String &chat_message);
Ref lobby_ready(bool p_ready);
Ref set_peer_name(const String &p_peer_name);
Ref seal_lobby(bool seal);
- Ref lobby_data(const Variant &p_peer_data);
- Ref lobby_data_to(const Variant &p_peer_data, const String &p_target_peer);
+ Ref lobby_call(const String &p_method, const Array &p_args);
+ Ref lobby_notify(const Variant &p_peer_data);
+ Ref peer_notify(const Variant &p_peer_data, const String &p_target_peer);
+ Ref lobby_data(const Dictionary &p_lobby_data, bool p_is_private);
+ Ref set_peer_data(const Dictionary &p_peer_data, const String &p_target_peer, bool p_is_private);
+ Ref set_peers_data(const Dictionary &p_peer_data, bool p_is_private);
LobbyClient();
~LobbyClient();
diff --git a/modules/blazium_sdk/register_types.cpp b/modules/blazium_sdk/register_types.cpp
index 5a825fc946d3..d23cfb6d11c1 100644
--- a/modules/blazium_sdk/register_types.cpp
+++ b/modules/blazium_sdk/register_types.cpp
@@ -30,6 +30,7 @@
#include "register_types.h"
#include "blazium_client.h"
+#include "lobby/authoritative_client.h"
#include "lobby/lobby_client.h"
void initialize_blazium_sdk_module(ModuleInitializationLevel p_level) {
@@ -44,6 +45,9 @@ void initialize_blazium_sdk_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(LobbyClient::ListLobbyResponse);
GDREGISTER_CLASS(LobbyClient::ViewLobbyResponse::ViewLobbyResult);
GDREGISTER_CLASS(LobbyClient::ViewLobbyResponse);
+ GDREGISTER_CLASS(AuthoritativeClient);
+ GDREGISTER_CLASS(AuthoritativeClient::LobbyCallResponse);
+ GDREGISTER_CLASS(AuthoritativeClient::LobbyCallResponse::LobbyCallResult);
}
}