summaryrefslogtreecommitdiffstats
path: root/modules/multiplayer/scene_cache_interface.cpp
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-07-31 22:33:07 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-07-31 22:33:07 +0200
commit019cf2b40c834a07eb4a35be26d839fc1b13d80b (patch)
treed9e1f37ab45d3afa6078dbb7a1dcc37b988adec0 /modules/multiplayer/scene_cache_interface.cpp
parent8460a72f94f9fae37b9111775104654781a8de06 (diff)
parent90d5d260265a8092624ad3af91c12171bc1e9b7e (diff)
downloadredot-engine-019cf2b40c834a07eb4a35be26d839fc1b13d80b.tar.gz
Merge pull request #94984 from Faless/mp/fix_safer_cache_cleanup
[MP] Partially revert cache cleanup, track paths as fallback
Diffstat (limited to 'modules/multiplayer/scene_cache_interface.cpp')
-rw-r--r--modules/multiplayer/scene_cache_interface.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/modules/multiplayer/scene_cache_interface.cpp b/modules/multiplayer/scene_cache_interface.cpp
index af43123b29..99c8930e92 100644
--- a/modules/multiplayer/scene_cache_interface.cpp
+++ b/modules/multiplayer/scene_cache_interface.cpp
@@ -54,11 +54,14 @@ void SceneCacheInterface::_remove_node_cache(ObjectID p_oid) {
if (nc->cache_id) {
assigned_ids.erase(nc->cache_id);
}
+#if 0
+ // TODO: Find a way to cleanup recv_nodes without breaking visibility and RPCs interactions.
for (KeyValue<int, int> &E : nc->recv_ids) {
PeerInfo *pinfo = peers_info.getptr(E.key);
ERR_CONTINUE(!pinfo);
pinfo->recv_nodes.erase(E.value);
}
+#endif
for (KeyValue<int, bool> &E : nc->confirmed_peers) {
PeerInfo *pinfo = peers_info.getptr(E.key);
ERR_CONTINUE(!pinfo);
@@ -73,9 +76,12 @@ void SceneCacheInterface::on_peer_change(int p_id, bool p_connected) {
} else {
PeerInfo *pinfo = peers_info.getptr(p_id);
ERR_FAIL_NULL(pinfo); // Bug.
- for (KeyValue<int, ObjectID> E : pinfo->recv_nodes) {
- NodeCache *nc = nodes_cache.getptr(E.value);
- ERR_CONTINUE(!nc);
+ for (KeyValue<int, RecvNode> E : pinfo->recv_nodes) {
+ NodeCache *nc = nodes_cache.getptr(E.value.oid);
+ if (!nc) {
+ // Node might have already been deleted locally.
+ continue;
+ }
nc->recv_ids.erase(p_id);
}
for (const ObjectID &oid : pinfo->sent_nodes) {
@@ -115,7 +121,7 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac
ERR_PRINT("The rpc node checksum failed. Make sure to have the same methods on both nodes. Node path: " + path);
}
- peers_info[p_from].recv_nodes.insert(id, node->get_instance_id());
+ peers_info[p_from].recv_nodes.insert(id, RecvNode(node->get_instance_id(), path));
NodeCache &cache = _track(node);
cache.recv_ids.insert(p_from, id);
@@ -269,14 +275,21 @@ bool SceneCacheInterface::send_object_cache(Object *p_obj, int p_peer_id, int &r
}
Object *SceneCacheInterface::get_cached_object(int p_from, uint32_t p_cache_id) {
- Node *root_node = SceneTree::get_singleton()->get_root()->get_node(multiplayer->get_root_path());
- ERR_FAIL_NULL_V(root_node, nullptr);
PeerInfo *pinfo = peers_info.getptr(p_from);
ERR_FAIL_NULL_V(pinfo, nullptr);
- const ObjectID *oid = pinfo->recv_nodes.getptr(p_cache_id);
- ERR_FAIL_NULL_V_MSG(oid, nullptr, vformat("ID %d not found in cache of peer %d.", p_cache_id, p_from));
- Node *node = Object::cast_to<Node>(ObjectDB::get_instance(*oid));
+ RecvNode *recv_node = pinfo->recv_nodes.getptr(p_cache_id);
+ ERR_FAIL_NULL_V_MSG(recv_node, nullptr, vformat("ID %d not found in cache of peer %d.", p_cache_id, p_from));
+ Node *node = Object::cast_to<Node>(ObjectDB::get_instance(recv_node->oid));
+ if (!node) {
+ // Fallback to path lookup.
+ Node *root_node = SceneTree::get_singleton()->get_root()->get_node(multiplayer->get_root_path());
+ ERR_FAIL_NULL_V(root_node, nullptr);
+ node = root_node->get_node(recv_node->path);
+ if (node) {
+ recv_node->oid = node->get_instance_id();
+ }
+ }
ERR_FAIL_NULL_V_MSG(node, nullptr, vformat("Failed to get cached node from peer %d with cache ID %d.", p_from, p_cache_id));
return node;
}