Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiplayer networking renames/simplification #52480

Merged
merged 1 commit into from
Sep 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/multiplayer/multiplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ enum TransferMode {

enum RPCMode {
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
RPC_MODE_ANY, // Any peer can call this rpc()
RPC_MODE_AUTHORITY, // / Only the node's network authority (server by default) can call this rpc()
RPC_MODE_ANY, // Any peer can call this RPC
RPC_MODE_AUTHORITY, // / Only the node's multiplayer authority (server by default) can call this RPC
};

struct RPCConfig {
Expand Down
140 changes: 70 additions & 70 deletions core/multiplayer/multiplayer_api.cpp

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions core/multiplayer/multiplayer_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class MultiplayerAPI : public RefCounted {
Map<int, NodeInfo> nodes;
};

Ref<MultiplayerPeer> network_peer;
Ref<MultiplayerPeer> multiplayer_peer;
Set<int> connected_peers;
int remote_sender_id = 0;
int remote_sender_override = 0;
Expand Down Expand Up @@ -112,8 +112,8 @@ class MultiplayerAPI : public RefCounted {
void clear();
void set_root_node(Node *p_node);
Node *get_root_node();
void set_network_peer(const Ref<MultiplayerPeer> &p_peer);
Ref<MultiplayerPeer> get_network_peer() const;
void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer);
Ref<MultiplayerPeer> get_multiplayer_peer() const;

Error send_bytes(Vector<uint8_t> p_data, int p_to = MultiplayerPeer::TARGET_PEER_BROADCAST, Multiplayer::TransferMode p_mode = Multiplayer::TRANSFER_MODE_RELIABLE, int p_channel = 0);

Expand All @@ -135,15 +135,15 @@ class MultiplayerAPI : public RefCounted {
void _connection_failed();
void _server_disconnected();

bool has_network_peer() const { return network_peer.is_valid(); }
Vector<int> get_network_connected_peers() const;
bool has_multiplayer_peer() const { return multiplayer_peer.is_valid(); }
Vector<int> get_peer_ids() const;
const Set<int> get_connected_peers() const { return connected_peers; }
int get_remote_sender_id() const { return remote_sender_override ? remote_sender_override : remote_sender_id; }
void set_remote_sender_override(int p_id) { remote_sender_override = p_id; }
int get_network_unique_id() const;
bool is_network_server() const;
void set_refuse_new_network_connections(bool p_refuse);
bool is_refusing_new_network_connections() const;
int get_unique_id() const;
bool is_server() const;
void set_refuse_new_connections(bool p_refuse);
bool is_refusing_new_connections() const;

void set_allow_object_decoding(bool p_enable);
bool is_object_decoding_allowed() const;
Expand Down
60 changes: 30 additions & 30 deletions core/multiplayer/multiplayer_replicator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,18 @@ Error MultiplayerReplicator::_sync_all_default(const ResourceUID::ID &p_scene_id
ERR_CONTINUE(err);
ofs += size;
}
Ref<MultiplayerPeer> network_peer = multiplayer->get_network_peer();
network_peer->set_target_peer(p_peer);
network_peer->set_transfer_channel(0);
network_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_UNRELIABLE);
return network_peer->put_packet(ptr, ofs);
Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer();
peer->set_target_peer(p_peer);
peer->set_transfer_channel(0);
peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_UNRELIABLE);
return peer->put_packet(ptr, ofs);
}

void MultiplayerReplicator::_process_default_sync(const ResourceUID::ID &p_id, const uint8_t *p_packet, int p_packet_len) {
ERR_FAIL_COND_MSG(p_packet_len < SYNC_CMD_OFFSET + 5, "Invalid spawn packet received");
ERR_FAIL_COND_MSG(!replications.has(p_id), "Invalid spawn ID received " + itos(p_id));
SceneConfig &cfg = replications[p_id];
ERR_FAIL_COND_MSG(cfg.mode != REPLICATION_MODE_SERVER || multiplayer->is_network_server(), "The defualt implementation only allows sync packets from the server");
ERR_FAIL_COND_MSG(cfg.mode != REPLICATION_MODE_SERVER || multiplayer->is_server(), "The defualt implementation only allows sync packets from the server");
const bool same_size = p_packet[0] & BYTE_OR_ZERO_FLAG;
int ofs = SYNC_CMD_OFFSET;
int time = p_packet[ofs];
Expand Down Expand Up @@ -233,11 +233,11 @@ Error MultiplayerReplicator::_send_default_spawn_despawn(int p_peer_id, const Re
memcpy(&ptr[ofs], pba.ptr(), state_len);
}

Ref<MultiplayerPeer> network_peer = multiplayer->get_network_peer();
network_peer->set_target_peer(p_peer_id);
network_peer->set_transfer_channel(0);
network_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE);
return network_peer->put_packet(ptr, ofs + state_len);
Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer();
peer->set_target_peer(p_peer_id);
peer->set_transfer_channel(0);
peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE);
return peer->put_packet(ptr, ofs + state_len);
}

void MultiplayerReplicator::_process_default_spawn_despawn(int p_from, const ResourceUID::ID &p_scene_id, const uint8_t *p_packet, int p_packet_len, bool p_spawn) {
Expand Down Expand Up @@ -513,21 +513,21 @@ Error MultiplayerReplicator::_send_spawn_despawn(int p_peer_id, const ResourceUI
} else if (data_size) {
encode_variant(p_data, &ptr[SPAWN_CMD_OFFSET], data_size);
}
Ref<MultiplayerPeer> network_peer = multiplayer->get_network_peer();
network_peer->set_target_peer(p_peer_id);
network_peer->set_transfer_channel(0);
network_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE);
return network_peer->put_packet(ptr, SPAWN_CMD_OFFSET + data_size);
Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer();
peer->set_target_peer(p_peer_id);
peer->set_transfer_channel(0);
peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE);
return peer->put_packet(ptr, SPAWN_CMD_OFFSET + data_size);
}

Error MultiplayerReplicator::send_despawn(int p_peer_id, const ResourceUID::ID &p_scene_id, const Variant &p_data, const NodePath &p_path) {
ERR_FAIL_COND_V(!multiplayer->has_network_peer(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!multiplayer->has_multiplayer_peer(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V_MSG(!replications.has(p_scene_id), ERR_INVALID_PARAMETER, vformat("Spawnable not found: %d", p_scene_id));
const SceneConfig &cfg = replications[p_scene_id];
if (cfg.on_spawn_despawn_send.is_valid()) {
return _send_spawn_despawn(p_peer_id, p_scene_id, p_data, true);
} else {
ERR_FAIL_COND_V_MSG(cfg.mode == REPLICATION_MODE_SERVER && multiplayer->is_network_server(), ERR_UNAVAILABLE, "Manual despawn is restricted in default server mode implementation. Use custom mode if you desire control over server spawn requests.");
ERR_FAIL_COND_V_MSG(cfg.mode == REPLICATION_MODE_SERVER && multiplayer->is_server(), ERR_UNAVAILABLE, "Manual despawn is restricted in default server mode implementation. Use custom mode if you desire control over server spawn requests.");
NodePath path = p_path;
Object *obj = p_data.get_type() == Variant::OBJECT ? p_data.get_validated_object() : nullptr;
if (path.is_empty() && obj) {
Expand All @@ -542,13 +542,13 @@ Error MultiplayerReplicator::send_despawn(int p_peer_id, const ResourceUID::ID &
}

Error MultiplayerReplicator::send_spawn(int p_peer_id, const ResourceUID::ID &p_scene_id, const Variant &p_data, const NodePath &p_path) {
ERR_FAIL_COND_V(!multiplayer->has_network_peer(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!multiplayer->has_multiplayer_peer(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V_MSG(!replications.has(p_scene_id), ERR_INVALID_PARAMETER, vformat("Spawnable not found: %d", p_scene_id));
const SceneConfig &cfg = replications[p_scene_id];
if (cfg.on_spawn_despawn_send.is_valid()) {
return _send_spawn_despawn(p_peer_id, p_scene_id, p_data, false);
} else {
ERR_FAIL_COND_V_MSG(cfg.mode == REPLICATION_MODE_SERVER && multiplayer->is_network_server(), ERR_UNAVAILABLE, "Manual spawn is restricted in default server mode implementation. Use custom mode if you desire control over server spawn requests.");
ERR_FAIL_COND_V_MSG(cfg.mode == REPLICATION_MODE_SERVER && multiplayer->is_server(), ERR_UNAVAILABLE, "Manual spawn is restricted in default server mode implementation. Use custom mode if you desire control over server spawn requests.");
NodePath path = p_path;
Object *obj = p_data.get_type() == Variant::OBJECT ? p_data.get_validated_object() : nullptr;
ERR_FAIL_COND_V_MSG(!obj, ERR_INVALID_PARAMETER, "Spawn default implementation requires the data to be an object.");
Expand Down Expand Up @@ -619,7 +619,7 @@ Error MultiplayerReplicator::decode_state(const ResourceUID::ID &p_scene_id, Obj
}

void MultiplayerReplicator::scene_enter_exit_notify(const String &p_scene, Node *p_node, bool p_enter) {
if (!multiplayer->has_network_peer()) {
if (!multiplayer->has_multiplayer_peer()) {
return;
}
Node *root_node = multiplayer->get_root_node();
Expand All @@ -634,14 +634,14 @@ void MultiplayerReplicator::scene_enter_exit_notify(const String &p_scene, Node
}
const SceneConfig &cfg = replications[id];
if (p_enter) {
if (cfg.mode == REPLICATION_MODE_SERVER && multiplayer->is_network_server()) {
if (cfg.mode == REPLICATION_MODE_SERVER && multiplayer->is_server()) {
replicated_nodes[p_node->get_instance_id()] = id;
_track(id, p_node);
spawn(id, p_node, 0);
}
emit_signal(SNAME("replicated_instance_added"), id, p_node);
} else {
if (cfg.mode == REPLICATION_MODE_SERVER && multiplayer->is_network_server() && replicated_nodes.has(p_node->get_instance_id())) {
if (cfg.mode == REPLICATION_MODE_SERVER && multiplayer->is_server() && replicated_nodes.has(p_node->get_instance_id())) {
replicated_nodes.erase(p_node->get_instance_id());
_untrack(id, p_node);
despawn(id, p_node, 0);
Expand All @@ -666,7 +666,7 @@ void MultiplayerReplicator::poll() {
if (!E.value.sync_interval) {
continue;
}
if (E.value.mode == REPLICATION_MODE_SERVER && !multiplayer->is_network_server()) {
if (E.value.mode == REPLICATION_MODE_SERVER && !multiplayer->is_server()) {
continue;
}
uint64_t time = OS::get_singleton()->get_ticks_usec();
Expand Down Expand Up @@ -741,19 +741,19 @@ Error MultiplayerReplicator::sync_all(const ResourceUID::ID &p_scene_id, int p_p
}

Error MultiplayerReplicator::send_sync(int p_peer_id, const ResourceUID::ID &p_scene_id, PackedByteArray p_data, Multiplayer::TransferMode p_transfer_mode, int p_channel) {
ERR_FAIL_COND_V(!multiplayer->has_network_peer(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!multiplayer->has_multiplayer_peer(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!replications.has(p_scene_id), ERR_INVALID_PARAMETER);
const SceneConfig &cfg = replications[p_scene_id];
ERR_FAIL_COND_V_MSG(!cfg.on_sync_send.is_valid(), ERR_UNCONFIGURED, "Sending raw sync messages is only available with custom functions");
MAKE_ROOM(SYNC_CMD_OFFSET + p_data.size());
uint8_t *ptr = packet_cache.ptrw();
ptr[0] = MultiplayerAPI::NETWORK_COMMAND_SYNC;
encode_uint64(p_scene_id, &ptr[1]);
Ref<MultiplayerPeer> network_peer = multiplayer->get_network_peer();
network_peer->set_target_peer(p_peer_id);
network_peer->set_transfer_channel(p_channel);
network_peer->set_transfer_mode(p_transfer_mode);
return network_peer->put_packet(ptr, SYNC_CMD_OFFSET + p_data.size());
Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer();
peer->set_target_peer(p_peer_id);
peer->set_transfer_channel(p_channel);
peer->set_transfer_mode(p_transfer_mode);
return peer->put_packet(ptr, SYNC_CMD_OFFSET + p_data.size());
}

void MultiplayerReplicator::clear() {
Expand Down
46 changes: 23 additions & 23 deletions core/multiplayer/rpc_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, Multiplayer::RPCMode mode, int
return true;
} break;
case Multiplayer::RPC_MODE_AUTHORITY: {
return !p_node->is_network_authority() && p_remote_id == p_node->get_network_authority();
return !p_node->is_multiplayer_authority() && p_remote_id == p_node->get_multiplayer_authority();
} break;
}

Expand Down Expand Up @@ -232,7 +232,7 @@ void RPCManager::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int
ERR_FAIL_COND(config.name == StringName());

bool can_call = _can_call_mode(p_node, config.rpc_mode, p_from);
ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(config.name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)config.rpc_mode) + ", authority is " + itos(p_node->get_network_authority()) + ".");
ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(config.name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)config.rpc_mode) + ", authority is " + itos(p_node->get_multiplayer_authority()) + ".");

int argc = 0;
bool byte_only = false;
Expand Down Expand Up @@ -294,19 +294,19 @@ void RPCManager::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int
}

void RPCManager::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const Multiplayer::RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount) {
Ref<MultiplayerPeer> network_peer = multiplayer->get_network_peer();
ERR_FAIL_COND_MSG(network_peer.is_null(), "Attempt to remote call/set when networking is not active in SceneTree.");
Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer();
ERR_FAIL_COND_MSG(peer.is_null(), "Attempt to call RPC without active multiplayer peer.");

ERR_FAIL_COND_MSG(network_peer->get_connection_status() == MultiplayerPeer::CONNECTION_CONNECTING, "Attempt to remote call/set when networking is not connected yet in SceneTree.");
ERR_FAIL_COND_MSG(peer->get_connection_status() == MultiplayerPeer::CONNECTION_CONNECTING, "Attempt to call RPC while multiplayer peer is not connected yet.");

ERR_FAIL_COND_MSG(network_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED, "Attempt to remote call/set when networking is disconnected.");
ERR_FAIL_COND_MSG(peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED, "Attempt to call RPC while multiplayer peer is disconnected.");

ERR_FAIL_COND_MSG(p_argcount > 255, "Too many arguments >255.");
ERR_FAIL_COND_MSG(p_argcount > 255, "Too many arguments (>255).");

if (p_to != 0 && !multiplayer->get_network_connected_peers().has(ABS(p_to))) {
ERR_FAIL_COND_MSG(p_to == network_peer->get_unique_id(), "Attempt to remote call/set yourself! unique ID: " + itos(network_peer->get_unique_id()) + ".");
if (p_to != 0 && !multiplayer->get_connected_peers().has(ABS(p_to))) {
ERR_FAIL_COND_MSG(p_to == peer->get_unique_id(), "Attempt to call RPC on yourself! Peer unique ID: " + itos(peer->get_unique_id()) + ".");

ERR_FAIL_MSG("Attempt to remote call unexisting ID: " + itos(p_to) + ".");
ERR_FAIL_MSG("Attempt to call RPC with unknown peer ID: " + itos(p_to) + ".");
}

NodePath from_path = (multiplayer->get_root_node()->get_path()).rel_path_to(p_from->get_path());
Expand Down Expand Up @@ -416,13 +416,13 @@ void RPCManager::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const Mult
#endif

// Take chance and set transfer mode, since all send methods will use it.
network_peer->set_transfer_channel(p_config.channel);
network_peer->set_transfer_mode(p_config.transfer_mode);
peer->set_transfer_channel(p_config.channel);
peer->set_transfer_mode(p_config.transfer_mode);

if (has_all_peers) {
// They all have verified paths, so send fast.
network_peer->set_target_peer(p_to); // To all of you.
network_peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
peer->set_target_peer(p_to); // To all of you.
peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
} else {
// Unreachable because the node ID is never compressed if the peers doesn't know it.
CRASH_COND(node_id_compression != NETWORK_NODE_ID_COMPRESSION_32);
Expand All @@ -446,28 +446,28 @@ void RPCManager::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const Mult

bool confirmed = multiplayer->is_cache_confirmed(from_path, P);

network_peer->set_target_peer(P); // To this one specifically.
peer->set_target_peer(P); // To this one specifically.

if (confirmed) {
// This one confirmed path, so use id.
encode_uint32(psc_id, &(packet_cache.write[1]));
network_peer->put_packet(packet_cache.ptr(), ofs);
peer->put_packet(packet_cache.ptr(), ofs);
} else {
// This one did not confirm path yet, so use entire path (sorry!).
encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); // Offset to path and flag.
network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
peer->put_packet(packet_cache.ptr(), ofs + path_len);
}
}
}
}

void RPCManager::rpcp(Node *p_node, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) {
Ref<MultiplayerPeer> network_peer = multiplayer->get_network_peer();
ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to call an RPC while no network peer is active.");
Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer();
ERR_FAIL_COND_MSG(!peer.is_valid(), "Trying to call an RPC while no multiplayer peer is active.");
ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to call an RPC on a node which is not inside SceneTree.");
ERR_FAIL_COND_MSG(network_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected.");
ERR_FAIL_COND_MSG(peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a multiplayer peer which is not connected.");

int node_id = network_peer->get_unique_id();
int node_id = peer->get_unique_id();
bool call_local_native = false;
bool call_local_script = false;
uint16_t rpc_id = UINT16_MAX;
Expand All @@ -493,7 +493,7 @@ void RPCManager::rpcp(Node *p_node, int p_peer_id, const StringName &p_method, c
if (call_local_native) {
Callable::CallError ce;

multiplayer->set_remote_sender_override(network_peer->get_unique_id());
multiplayer->set_remote_sender_override(peer->get_unique_id());
p_node->call(p_method, p_arg, p_argcount, ce);
multiplayer->set_remote_sender_override(0);

Expand All @@ -509,7 +509,7 @@ void RPCManager::rpcp(Node *p_node, int p_peer_id, const StringName &p_method, c
Callable::CallError ce;
ce.error = Callable::CallError::CALL_OK;

multiplayer->set_remote_sender_override(network_peer->get_unique_id());
multiplayer->set_remote_sender_override(peer->get_unique_id());
p_node->get_script_instance()->call(p_method, p_arg, p_argcount, ce);
multiplayer->set_remote_sender_override(0);

Expand Down
2 changes: 1 addition & 1 deletion doc/classes/@GlobalScope.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2472,7 +2472,7 @@
Used with [method Node.rpc_config] to set a method to be callable remotely by any peer. Analogous to the [code]@rpc(any)[/code] annotation. Calls are accepted from all remote peers, no matter if they are node's authority or not.
</constant>
<constant name="RPC_MODE_AUTH" value="2" enum="RPCMode">
Used with [method Node.rpc_config] to set a method to be callable remotely only by the current network authority (which is the server by default). Analogous to the [code]@rpc(auth)[/code] annotation. See [method Node.set_network_authority].
Used with [method Node.rpc_config] to set a method to be callable remotely only by the current multiplayer authority (which is the server by default). Analogous to the [code]@rpc(auth)[/code] annotation. See [method Node.set_multiplayer_authority].
</constant>
<constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode">
Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_ORDERED]. Use for non-critical data, and always consider whether the order matters.
Expand Down
Loading