diff options
author | Fabio Alessandrelli <fabio.alessandrelli@gmail.com> | 2023-09-27 01:12:58 +0200 |
---|---|---|
committer | Fabio Alessandrelli <fabio.alessandrelli@gmail.com> | 2023-10-10 14:42:54 +0200 |
commit | 9ce423914ec4a392e42dbf894dc7929befcc7e1d (patch) | |
tree | 6efcc40b5d6b9f8a922c8b2f0db554b387bc9103 /modules | |
parent | 61cf7d180cc6ac1be1f9cb1c7369b2cae5d99b25 (diff) | |
download | redot-engine-9ce423914ec4a392e42dbf894dc7929befcc7e1d.tar.gz |
[MP] Optimize internal authority checks
We already know which MultiplayerAPI a certain Node uses, so we don't
need to retrieve it via SceneTree every time.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/multiplayer/scene_replication_interface.cpp | 22 | ||||
-rw-r--r-- | modules/multiplayer/scene_replication_interface.h | 1 | ||||
-rw-r--r-- | modules/multiplayer/scene_rpc_interface.cpp | 30 |
3 files changed, 28 insertions, 25 deletions
diff --git a/modules/multiplayer/scene_replication_interface.cpp b/modules/multiplayer/scene_replication_interface.cpp index e350f2f68b..0404bc982d 100644 --- a/modules/multiplayer/scene_replication_interface.cpp +++ b/modules/multiplayer/scene_replication_interface.cpp @@ -89,6 +89,10 @@ void SceneReplicationInterface::_free_remotes(const PeerInfo &p_info) { } } +bool SceneReplicationInterface::_has_authority(const Node *p_node) { + return multiplayer->has_multiplayer_peer() && p_node->get_multiplayer_authority() == multiplayer->get_unique_id(); +} + void SceneReplicationInterface::on_peer_change(int p_id, bool p_connected) { if (p_connected) { peers_info[p_id] = PeerInfo(); @@ -184,7 +188,7 @@ void SceneReplicationInterface::_node_ready(const ObjectID &p_oid) { ERR_CONTINUE(!spawner); spawned_nodes.insert(oid); - if (multiplayer->has_multiplayer_peer() && spawner->is_multiplayer_authority()) { + if (_has_authority(spawner)) { if (tobj.net_id == 0) { tobj.net_id = ++last_net_id; } @@ -342,7 +346,7 @@ bool SceneReplicationInterface::is_rpc_visible(const ObjectID &p_oid, int p_peer Error SceneReplicationInterface::_update_sync_visibility(int p_peer, MultiplayerSynchronizer *p_sync) { ERR_FAIL_NULL_V(p_sync, ERR_BUG); - if (!multiplayer->has_multiplayer_peer() || !p_sync->is_multiplayer_authority() || p_peer == multiplayer->get_unique_id()) { + if (!_has_authority(p_sync) || p_peer == multiplayer->get_unique_id()) { return OK; } @@ -383,14 +387,16 @@ Error SceneReplicationInterface::_update_spawn_visibility(int p_peer, const Obje ERR_FAIL_NULL_V(tnode, ERR_BUG); MultiplayerSpawner *spawner = get_id_as<MultiplayerSpawner>(tnode->spawner); Node *node = get_id_as<Node>(p_oid); - ERR_FAIL_COND_V(!node || !spawner || !spawner->is_multiplayer_authority(), ERR_BUG); + ERR_FAIL_NULL_V(node, ERR_BUG); + ERR_FAIL_NULL_V(spawner, ERR_BUG); + ERR_FAIL_COND_V(!_has_authority(spawner), ERR_BUG); ERR_FAIL_COND_V(!tracked_nodes.has(p_oid), ERR_BUG); const HashSet<ObjectID> synchronizers = tracked_nodes[p_oid].synchronizers; bool is_visible = true; for (const ObjectID &sid : synchronizers) { MultiplayerSynchronizer *sync = get_id_as<MultiplayerSynchronizer>(sid); ERR_CONTINUE(!sync); - if (!sync->is_multiplayer_authority()) { + if (!_has_authority(sync)) { continue; } // Spawn visibility is composed using OR when multiple synchronizers are present. @@ -454,9 +460,9 @@ Error SceneReplicationInterface::_update_spawn_visibility(int p_peer, const Obje Error SceneReplicationInterface::_send_raw(const uint8_t *p_buffer, int p_size, int p_peer, bool p_reliable) { ERR_FAIL_COND_V(!p_buffer || p_size < 1, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(!multiplayer->has_multiplayer_peer(), ERR_UNCONFIGURED); Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer(); + ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED); peer->set_transfer_channel(0); peer->set_transfer_mode(p_reliable ? MultiplayerPeer::TRANSFER_MODE_RELIABLE : MultiplayerPeer::TRANSFER_MODE_UNRELIABLE); return multiplayer->send_command(p_peer, p_buffer, p_size); @@ -488,7 +494,7 @@ Error SceneReplicationInterface::_make_spawn_packet(Node *p_node, MultiplayerSpa const HashSet<ObjectID> synchronizers = tnode->synchronizers; for (const ObjectID &sid : synchronizers) { MultiplayerSynchronizer *sync = get_id_as<MultiplayerSynchronizer>(sid); - if (!sync->is_multiplayer_authority()) { + if (!_has_authority(sync)) { continue; } ERR_CONTINUE(!sync); @@ -708,7 +714,7 @@ void SceneReplicationInterface::_send_delta(int p_peer, const HashSet<ObjectID> int ofs = 1; for (const ObjectID &oid : p_synchronizers) { MultiplayerSynchronizer *sync = get_id_as<MultiplayerSynchronizer>(oid); - ERR_CONTINUE(!sync || !sync->get_replication_config().is_valid() || !sync->is_multiplayer_authority()); + ERR_CONTINUE(!sync || !sync->get_replication_config().is_valid() || !_has_authority(sync)); uint32_t net_id; if (!_verify_synchronizer(p_peer, sync, net_id)) { continue; @@ -803,7 +809,7 @@ void SceneReplicationInterface::_send_sync(int p_peer, const HashSet<ObjectID> p // This is a lazy implementation, we could optimize much more here with by grouping by replication config. for (const ObjectID &oid : p_synchronizers) { MultiplayerSynchronizer *sync = get_id_as<MultiplayerSynchronizer>(oid); - ERR_CONTINUE(!sync || !sync->get_replication_config().is_valid() || !sync->is_multiplayer_authority()); + ERR_CONTINUE(!sync || !sync->get_replication_config().is_valid() || !_has_authority(sync)); if (!sync->update_outbound_sync_time(p_usec)) { continue; // nothing to sync. } diff --git a/modules/multiplayer/scene_replication_interface.h b/modules/multiplayer/scene_replication_interface.h index 267d329ca7..4cc2f20ffa 100644 --- a/modules/multiplayer/scene_replication_interface.h +++ b/modules/multiplayer/scene_replication_interface.h @@ -95,6 +95,7 @@ private: void _untrack(const ObjectID &p_id); void _node_ready(const ObjectID &p_oid); + bool _has_authority(const Node *p_node); bool _verify_synchronizer(int p_peer, MultiplayerSynchronizer *p_sync, uint32_t &r_net_id); MultiplayerSynchronizer *_find_synchronizer(int p_peer, uint32_t p_net_ida); diff --git a/modules/multiplayer/scene_rpc_interface.cpp b/modules/multiplayer/scene_rpc_interface.cpp index bf0a261bd8..5301815c1e 100644 --- a/modules/multiplayer/scene_rpc_interface.cpp +++ b/modules/multiplayer/scene_rpc_interface.cpp @@ -116,22 +116,6 @@ const SceneRPCInterface::RPCConfigCache &SceneRPCInterface::_get_node_config(con return rpc_cache[oid]; } -_FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) { - switch (mode) { - case MultiplayerAPI::RPC_MODE_DISABLED: { - return false; - } break; - case MultiplayerAPI::RPC_MODE_ANY_PEER: { - return true; - } break; - case MultiplayerAPI::RPC_MODE_AUTHORITY: { - return !p_node->is_multiplayer_authority() && p_remote_id == p_node->get_multiplayer_authority(); - } break; - } - - return false; -} - String SceneRPCInterface::get_rpc_md5(const Object *p_obj) { const Node *node = Object::cast_to<Node>(p_obj); ERR_FAIL_NULL_V(node, ""); @@ -252,7 +236,19 @@ void SceneRPCInterface::_process_rpc(Node *p_node, const uint16_t p_rpc_method_i ERR_FAIL_COND(!cache_config.configs.has(p_rpc_method_id)); const RPCConfig &config = cache_config.configs[p_rpc_method_id]; - bool can_call = _can_call_mode(p_node, config.rpc_mode, p_from); + bool can_call = false; + switch (config.rpc_mode) { + case MultiplayerAPI::RPC_MODE_DISABLED: { + can_call = false; + } break; + case MultiplayerAPI::RPC_MODE_ANY_PEER: { + can_call = true; + } break; + case MultiplayerAPI::RPC_MODE_AUTHORITY: { + can_call = p_from == p_node->get_multiplayer_authority(); + } break; + } + 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; |