scene_replication_interface.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /*************************************************************************/
  2. /* scene_replication_interface.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "scene_replication_interface.h"
  31. #include "core/io/marshalls.h"
  32. #include "scene/main/node.h"
  33. #include "multiplayer_spawner.h"
  34. #include "multiplayer_synchronizer.h"
  35. #include "scene_multiplayer.h"
  36. #define MAKE_ROOM(m_amount) \
  37. if (packet_cache.size() < m_amount) \
  38. packet_cache.resize(m_amount);
  39. void SceneReplicationInterface::_free_remotes(int p_id) {
  40. const HashMap<uint32_t, ObjectID> remotes = rep_state->peer_get_remotes(p_id);
  41. for (const KeyValue<uint32_t, ObjectID> &E : remotes) {
  42. Node *node = rep_state->get_node(E.value);
  43. ERR_CONTINUE(!node);
  44. node->queue_delete();
  45. }
  46. }
  47. void SceneReplicationInterface::on_peer_change(int p_id, bool p_connected) {
  48. if (p_connected) {
  49. rep_state->on_peer_change(p_id, p_connected);
  50. for (const ObjectID &oid : rep_state->get_spawned_nodes()) {
  51. _update_spawn_visibility(p_id, oid);
  52. }
  53. for (const ObjectID &oid : rep_state->get_synced_nodes()) {
  54. MultiplayerSynchronizer *sync = rep_state->get_synchronizer(oid);
  55. ERR_CONTINUE(!sync); // ERR_BUG
  56. if (sync->is_multiplayer_authority()) {
  57. _update_sync_visibility(p_id, oid);
  58. }
  59. }
  60. } else {
  61. _free_remotes(p_id);
  62. rep_state->on_peer_change(p_id, p_connected);
  63. }
  64. }
  65. void SceneReplicationInterface::on_reset() {
  66. for (int pid : rep_state->get_peers()) {
  67. _free_remotes(pid);
  68. }
  69. rep_state->reset();
  70. }
  71. void SceneReplicationInterface::on_network_process() {
  72. uint64_t msec = OS::get_singleton()->get_ticks_msec();
  73. for (int peer : rep_state->get_peers()) {
  74. _send_sync(peer, msec);
  75. }
  76. }
  77. Error SceneReplicationInterface::on_spawn(Object *p_obj, Variant p_config) {
  78. Node *node = Object::cast_to<Node>(p_obj);
  79. ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER);
  80. MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(p_config.get_validated_object());
  81. ERR_FAIL_COND_V(!spawner, ERR_INVALID_PARAMETER);
  82. Error err = rep_state->config_add_spawn(node, spawner);
  83. ERR_FAIL_COND_V(err != OK, err);
  84. const ObjectID oid = node->get_instance_id();
  85. if (multiplayer->has_multiplayer_peer() && spawner->is_multiplayer_authority()) {
  86. rep_state->ensure_net_id(oid);
  87. _update_spawn_visibility(0, oid);
  88. }
  89. ERR_FAIL_COND_V(err != OK, err);
  90. return OK;
  91. }
  92. Error SceneReplicationInterface::on_despawn(Object *p_obj, Variant p_config) {
  93. Node *node = Object::cast_to<Node>(p_obj);
  94. ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER);
  95. MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(p_config.get_validated_object());
  96. ERR_FAIL_COND_V(!p_obj || !spawner, ERR_INVALID_PARAMETER);
  97. // Forcibly despawn to all peers that knowns me.
  98. int len = 0;
  99. Error err = _make_despawn_packet(node, len);
  100. ERR_FAIL_COND_V(err != OK, ERR_BUG);
  101. const ObjectID oid = p_obj->get_instance_id();
  102. for (int pid : rep_state->get_peers()) {
  103. if (!rep_state->is_peer_spawn(pid, oid)) {
  104. continue;
  105. }
  106. _send_raw(packet_cache.ptr(), len, pid, true);
  107. }
  108. // Also remove spawner tracking from the replication state.
  109. return rep_state->config_del_spawn(node, spawner);
  110. }
  111. Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_config) {
  112. Node *node = Object::cast_to<Node>(p_obj);
  113. ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER);
  114. MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object());
  115. ERR_FAIL_COND_V(!sync, ERR_INVALID_PARAMETER);
  116. // Add to synchronizer list and setup visibility.
  117. rep_state->config_add_sync(node, sync);
  118. const ObjectID oid = node->get_instance_id();
  119. sync->connect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed).bind(oid));
  120. if (multiplayer->has_multiplayer_peer() && sync->is_multiplayer_authority()) {
  121. _update_sync_visibility(0, oid);
  122. }
  123. // Try to apply initial state if spawning (hack to apply if before ready).
  124. if (pending_spawn == p_obj->get_instance_id()) {
  125. pending_spawn = ObjectID(); // Make sure this only happens once.
  126. const List<NodePath> props = sync->get_replication_config()->get_spawn_properties();
  127. Vector<Variant> vars;
  128. vars.resize(props.size());
  129. int consumed;
  130. Error err = MultiplayerAPI::decode_and_decompress_variants(vars, pending_buffer, pending_buffer_size, consumed);
  131. ERR_FAIL_COND_V(err, err);
  132. err = MultiplayerSynchronizer::set_state(props, node, vars);
  133. ERR_FAIL_COND_V(err, err);
  134. }
  135. return OK;
  136. }
  137. Error SceneReplicationInterface::on_replication_stop(Object *p_obj, Variant p_config) {
  138. Node *node = Object::cast_to<Node>(p_obj);
  139. ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER);
  140. MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object());
  141. ERR_FAIL_COND_V(!sync, ERR_INVALID_PARAMETER);
  142. sync->disconnect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed));
  143. return rep_state->config_del_sync(node, sync);
  144. }
  145. void SceneReplicationInterface::_visibility_changed(int p_peer, ObjectID p_oid) {
  146. if (rep_state->is_spawned_node(p_oid)) {
  147. _update_spawn_visibility(p_peer, p_oid);
  148. }
  149. if (rep_state->is_synced_node(p_oid)) {
  150. _update_sync_visibility(p_peer, p_oid);
  151. }
  152. }
  153. Error SceneReplicationInterface::_update_sync_visibility(int p_peer, const ObjectID &p_oid) {
  154. MultiplayerSynchronizer *sync = rep_state->get_synchronizer(p_oid);
  155. ERR_FAIL_COND_V(!sync || !sync->is_multiplayer_authority(), ERR_BUG);
  156. bool is_visible = sync->is_visible_to(p_peer);
  157. if (p_peer == 0) {
  158. for (int pid : rep_state->get_peers()) {
  159. // Might be visible to this specific peer.
  160. is_visible = is_visible || sync->is_visible_to(pid);
  161. if (rep_state->is_peer_sync(pid, p_oid) == is_visible) {
  162. continue;
  163. }
  164. if (is_visible) {
  165. rep_state->peer_add_sync(pid, p_oid);
  166. } else {
  167. rep_state->peer_del_sync(pid, p_oid);
  168. }
  169. }
  170. return OK;
  171. } else {
  172. if (is_visible == rep_state->is_peer_sync(p_peer, p_oid)) {
  173. return OK;
  174. }
  175. if (is_visible) {
  176. return rep_state->peer_add_sync(p_peer, p_oid);
  177. } else {
  178. return rep_state->peer_del_sync(p_peer, p_oid);
  179. }
  180. }
  181. }
  182. Error SceneReplicationInterface::_update_spawn_visibility(int p_peer, const ObjectID &p_oid) {
  183. MultiplayerSpawner *spawner = rep_state->get_spawner(p_oid);
  184. MultiplayerSynchronizer *sync = rep_state->get_synchronizer(p_oid);
  185. Node *node = Object::cast_to<Node>(ObjectDB::get_instance(p_oid));
  186. ERR_FAIL_COND_V(!node || !spawner || !spawner->is_multiplayer_authority(), ERR_BUG);
  187. bool is_visible = !sync || sync->is_visible_to(p_peer);
  188. // Spawn (and despawn) when needed.
  189. HashSet<int> to_spawn;
  190. HashSet<int> to_despawn;
  191. if (p_peer) {
  192. if (is_visible == rep_state->is_peer_spawn(p_peer, p_oid)) {
  193. return OK;
  194. }
  195. if (is_visible) {
  196. to_spawn.insert(p_peer);
  197. } else {
  198. to_despawn.insert(p_peer);
  199. }
  200. } else {
  201. // Check visibility for each peers.
  202. for (int pid : rep_state->get_peers()) {
  203. bool peer_visible = is_visible || sync->is_visible_to(pid);
  204. if (peer_visible == rep_state->is_peer_spawn(pid, p_oid)) {
  205. continue;
  206. }
  207. if (peer_visible) {
  208. to_spawn.insert(pid);
  209. } else {
  210. to_despawn.insert(pid);
  211. }
  212. }
  213. }
  214. if (to_spawn.size()) {
  215. int len = 0;
  216. _make_spawn_packet(node, len);
  217. for (int pid : to_spawn) {
  218. int path_id;
  219. multiplayer->get_path_cache()->send_object_cache(spawner, pid, path_id);
  220. _send_raw(packet_cache.ptr(), len, pid, true);
  221. rep_state->peer_add_spawn(pid, p_oid);
  222. }
  223. }
  224. if (to_despawn.size()) {
  225. int len = 0;
  226. _make_despawn_packet(node, len);
  227. for (int pid : to_despawn) {
  228. rep_state->peer_del_spawn(pid, p_oid);
  229. _send_raw(packet_cache.ptr(), len, pid, true);
  230. }
  231. }
  232. return OK;
  233. }
  234. Error SceneReplicationInterface::_send_raw(const uint8_t *p_buffer, int p_size, int p_peer, bool p_reliable) {
  235. ERR_FAIL_COND_V(!p_buffer || p_size < 1, ERR_INVALID_PARAMETER);
  236. ERR_FAIL_COND_V(!multiplayer, ERR_UNCONFIGURED);
  237. ERR_FAIL_COND_V(!multiplayer->has_multiplayer_peer(), ERR_UNCONFIGURED);
  238. #ifdef DEBUG_ENABLED
  239. multiplayer->profile_bandwidth("out", p_size);
  240. #endif
  241. Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer();
  242. peer->set_target_peer(p_peer);
  243. peer->set_transfer_channel(0);
  244. peer->set_transfer_mode(p_reliable ? MultiplayerPeer::TRANSFER_MODE_RELIABLE : MultiplayerPeer::TRANSFER_MODE_UNRELIABLE);
  245. return peer->put_packet(p_buffer, p_size);
  246. }
  247. Error SceneReplicationInterface::_make_spawn_packet(Node *p_node, int &r_len) {
  248. ERR_FAIL_COND_V(!multiplayer, ERR_BUG);
  249. const ObjectID oid = p_node->get_instance_id();
  250. MultiplayerSpawner *spawner = rep_state->get_spawner(oid);
  251. ERR_FAIL_COND_V(!spawner || !p_node, ERR_BUG);
  252. uint32_t nid = rep_state->get_net_id(oid);
  253. ERR_FAIL_COND_V(!nid, ERR_UNCONFIGURED);
  254. // Prepare custom arg and scene_id
  255. uint8_t scene_id = spawner->find_spawnable_scene_index_from_object(oid);
  256. bool is_custom = scene_id == MultiplayerSpawner::INVALID_ID;
  257. Variant spawn_arg = spawner->get_spawn_argument(oid);
  258. int spawn_arg_size = 0;
  259. if (is_custom) {
  260. Error err = MultiplayerAPI::encode_and_compress_variant(spawn_arg, nullptr, spawn_arg_size, false);
  261. ERR_FAIL_COND_V(err, err);
  262. }
  263. // Prepare spawn state.
  264. int state_size = 0;
  265. Vector<Variant> state_vars;
  266. Vector<const Variant *> state_varp;
  267. MultiplayerSynchronizer *synchronizer = rep_state->get_synchronizer(oid);
  268. if (synchronizer) {
  269. ERR_FAIL_COND_V(synchronizer->get_replication_config().is_null(), ERR_BUG);
  270. const List<NodePath> props = synchronizer->get_replication_config()->get_spawn_properties();
  271. Error err = MultiplayerSynchronizer::get_state(props, p_node, state_vars, state_varp);
  272. ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to retrieve spawn state.");
  273. err = MultiplayerAPI::encode_and_compress_variants(state_varp.ptrw(), state_varp.size(), nullptr, state_size);
  274. ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to encode spawn state.");
  275. }
  276. // Encode scene ID, path ID, net ID, node name.
  277. int path_id = multiplayer->get_path_cache()->make_object_cache(spawner);
  278. CharString cname = p_node->get_name().operator String().utf8();
  279. int nlen = encode_cstring(cname.get_data(), nullptr);
  280. MAKE_ROOM(1 + 1 + 4 + 4 + 4 + nlen + (is_custom ? 4 + spawn_arg_size : 0) + state_size);
  281. uint8_t *ptr = packet_cache.ptrw();
  282. ptr[0] = (uint8_t)SceneMultiplayer::NETWORK_COMMAND_SPAWN;
  283. ptr[1] = scene_id;
  284. int ofs = 2;
  285. ofs += encode_uint32(path_id, &ptr[ofs]);
  286. ofs += encode_uint32(nid, &ptr[ofs]);
  287. ofs += encode_uint32(nlen, &ptr[ofs]);
  288. ofs += encode_cstring(cname.get_data(), &ptr[ofs]);
  289. // Write args
  290. if (is_custom) {
  291. ofs += encode_uint32(spawn_arg_size, &ptr[ofs]);
  292. Error err = MultiplayerAPI::encode_and_compress_variant(spawn_arg, &ptr[ofs], spawn_arg_size, false);
  293. ERR_FAIL_COND_V(err, err);
  294. ofs += spawn_arg_size;
  295. }
  296. // Write state.
  297. if (state_size) {
  298. Error err = MultiplayerAPI::encode_and_compress_variants(state_varp.ptrw(), state_varp.size(), &ptr[ofs], state_size);
  299. ERR_FAIL_COND_V(err, err);
  300. ofs += state_size;
  301. }
  302. r_len = ofs;
  303. return OK;
  304. }
  305. Error SceneReplicationInterface::_make_despawn_packet(Node *p_node, int &r_len) {
  306. const ObjectID oid = p_node->get_instance_id();
  307. MAKE_ROOM(5);
  308. uint8_t *ptr = packet_cache.ptrw();
  309. ptr[0] = (uint8_t)SceneMultiplayer::NETWORK_COMMAND_DESPAWN;
  310. int ofs = 1;
  311. uint32_t nid = rep_state->get_net_id(oid);
  312. ofs += encode_uint32(nid, &ptr[ofs]);
  313. r_len = ofs;
  314. return OK;
  315. }
  316. Error SceneReplicationInterface::on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) {
  317. ERR_FAIL_COND_V_MSG(p_buffer_len < 14, ERR_INVALID_DATA, "Invalid spawn packet received");
  318. int ofs = 1; // The spawn/despawn command.
  319. uint8_t scene_id = p_buffer[ofs];
  320. ofs += 1;
  321. uint32_t node_target = decode_uint32(&p_buffer[ofs]);
  322. ofs += 4;
  323. MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(multiplayer->get_path_cache()->get_cached_object(p_from, node_target));
  324. ERR_FAIL_COND_V(!spawner, ERR_DOES_NOT_EXIST);
  325. ERR_FAIL_COND_V(p_from != spawner->get_multiplayer_authority(), ERR_UNAUTHORIZED);
  326. uint32_t net_id = decode_uint32(&p_buffer[ofs]);
  327. ofs += 4;
  328. uint32_t name_len = decode_uint32(&p_buffer[ofs]);
  329. ofs += 4;
  330. ERR_FAIL_COND_V_MSG(name_len > uint32_t(p_buffer_len - ofs), ERR_INVALID_DATA, vformat("Invalid spawn packet size: %d, wants: %d", p_buffer_len, ofs + name_len));
  331. ERR_FAIL_COND_V_MSG(name_len < 1, ERR_INVALID_DATA, "Zero spawn name size.");
  332. // We need to make sure no trickery happens here, but we want to allow autogenerated ("@") node names.
  333. const String name = String::utf8((const char *)&p_buffer[ofs], name_len);
  334. ERR_FAIL_COND_V_MSG(name.validate_node_name() != name, ERR_INVALID_DATA, vformat("Invalid node name received: '%s'. Make sure to add nodes via 'add_child(node, true)' remotely.", name));
  335. ofs += name_len;
  336. // Check that we can spawn.
  337. Node *parent = spawner->get_node_or_null(spawner->get_spawn_path());
  338. ERR_FAIL_COND_V(!parent, ERR_UNCONFIGURED);
  339. ERR_FAIL_COND_V(parent->has_node(name), ERR_INVALID_DATA);
  340. Node *node = nullptr;
  341. if (scene_id == MultiplayerSpawner::INVALID_ID) {
  342. // Custom spawn.
  343. ERR_FAIL_COND_V(p_buffer_len - ofs < 4, ERR_INVALID_DATA);
  344. uint32_t arg_size = decode_uint32(&p_buffer[ofs]);
  345. ofs += 4;
  346. ERR_FAIL_COND_V(arg_size > uint32_t(p_buffer_len - ofs), ERR_INVALID_DATA);
  347. Variant v;
  348. Error err = MultiplayerAPI::decode_and_decompress_variant(v, &p_buffer[ofs], arg_size, nullptr, false);
  349. ERR_FAIL_COND_V(err != OK, err);
  350. ofs += arg_size;
  351. node = spawner->instantiate_custom(v);
  352. } else {
  353. // Scene based spawn.
  354. node = spawner->instantiate_scene(scene_id);
  355. }
  356. ERR_FAIL_COND_V(!node, ERR_UNAUTHORIZED);
  357. node->set_name(name);
  358. rep_state->peer_add_remote(p_from, net_id, node, spawner);
  359. // The initial state will be applied during the sync config (i.e. before _ready).
  360. int state_len = p_buffer_len - ofs;
  361. if (state_len) {
  362. pending_spawn = node->get_instance_id();
  363. pending_buffer = &p_buffer[ofs];
  364. pending_buffer_size = state_len;
  365. }
  366. parent->add_child(node);
  367. pending_spawn = ObjectID();
  368. pending_buffer = nullptr;
  369. pending_buffer_size = 0;
  370. return OK;
  371. }
  372. Error SceneReplicationInterface::on_despawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) {
  373. ERR_FAIL_COND_V_MSG(p_buffer_len < 5, ERR_INVALID_DATA, "Invalid spawn packet received");
  374. int ofs = 1; // The spawn/despawn command.
  375. uint32_t net_id = decode_uint32(&p_buffer[ofs]);
  376. ofs += 4;
  377. Node *node = nullptr;
  378. Error err = rep_state->peer_del_remote(p_from, net_id, &node);
  379. ERR_FAIL_COND_V(err != OK, err);
  380. ERR_FAIL_COND_V(!node, ERR_BUG);
  381. if (node->get_parent() != nullptr) {
  382. node->get_parent()->remove_child(node);
  383. }
  384. node->queue_delete();
  385. return OK;
  386. }
  387. void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) {
  388. const HashSet<ObjectID> &to_sync = rep_state->get_peer_sync_nodes(p_peer);
  389. if (to_sync.is_empty()) {
  390. return;
  391. }
  392. MAKE_ROOM(sync_mtu);
  393. uint8_t *ptr = packet_cache.ptrw();
  394. ptr[0] = SceneMultiplayer::NETWORK_COMMAND_SYNC;
  395. int ofs = 1;
  396. ofs += encode_uint16(rep_state->peer_sync_next(p_peer), &ptr[1]);
  397. // Can only send updates for already notified nodes.
  398. // This is a lazy implementation, we could optimize much more here with by grouping by replication config.
  399. for (const ObjectID &oid : to_sync) {
  400. if (!rep_state->update_sync_time(oid, p_msec)) {
  401. continue; // nothing to sync.
  402. }
  403. MultiplayerSynchronizer *sync = rep_state->get_synchronizer(oid);
  404. ERR_CONTINUE(!sync || !sync->get_replication_config().is_valid());
  405. Node *node = rep_state->get_node(oid);
  406. ERR_CONTINUE(!node);
  407. uint32_t net_id = rep_state->get_net_id(oid);
  408. if (net_id == 0 || (net_id & 0x80000000)) {
  409. int path_id = 0;
  410. bool verified = multiplayer->get_path_cache()->send_object_cache(sync, p_peer, path_id);
  411. ERR_CONTINUE_MSG(path_id < 0, "This should never happen!");
  412. if (net_id == 0) {
  413. // First time path based ID.
  414. net_id = path_id | 0x80000000;
  415. rep_state->set_net_id(oid, net_id | 0x80000000);
  416. }
  417. if (!verified) {
  418. // The path based sync is not yet confirmed, skipping.
  419. continue;
  420. }
  421. }
  422. int size;
  423. Vector<Variant> vars;
  424. Vector<const Variant *> varp;
  425. const List<NodePath> props = sync->get_replication_config()->get_sync_properties();
  426. Error err = MultiplayerSynchronizer::get_state(props, node, vars, varp);
  427. ERR_CONTINUE_MSG(err != OK, "Unable to retrieve sync state.");
  428. err = MultiplayerAPI::encode_and_compress_variants(varp.ptrw(), varp.size(), nullptr, size);
  429. ERR_CONTINUE_MSG(err != OK, "Unable to encode sync state.");
  430. // TODO Handle single state above MTU.
  431. ERR_CONTINUE_MSG(size > 3 + 4 + 4 + sync_mtu, vformat("Node states bigger then MTU will not be sent (%d > %d): %s", size, sync_mtu, node->get_path()));
  432. if (ofs + 4 + 4 + size > sync_mtu) {
  433. // Send what we got, and reset write.
  434. _send_raw(packet_cache.ptr(), ofs, p_peer, false);
  435. ofs = 3;
  436. }
  437. if (size) {
  438. ofs += encode_uint32(rep_state->get_net_id(oid), &ptr[ofs]);
  439. ofs += encode_uint32(size, &ptr[ofs]);
  440. MultiplayerAPI::encode_and_compress_variants(varp.ptrw(), varp.size(), &ptr[ofs], size);
  441. ofs += size;
  442. }
  443. }
  444. if (ofs > 3) {
  445. // Got some left over to send.
  446. _send_raw(packet_cache.ptr(), ofs, p_peer, false);
  447. }
  448. }
  449. Error SceneReplicationInterface::on_sync_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) {
  450. ERR_FAIL_COND_V_MSG(p_buffer_len < 11, ERR_INVALID_DATA, "Invalid sync packet received");
  451. uint16_t time = decode_uint16(&p_buffer[1]);
  452. int ofs = 3;
  453. rep_state->peer_sync_recv(p_from, time);
  454. while (ofs + 8 < p_buffer_len) {
  455. uint32_t net_id = decode_uint32(&p_buffer[ofs]);
  456. ofs += 4;
  457. uint32_t size = decode_uint32(&p_buffer[ofs]);
  458. ofs += 4;
  459. Node *node = nullptr;
  460. if (net_id & 0x80000000) {
  461. MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(multiplayer->get_path_cache()->get_cached_object(p_from, net_id & 0x7FFFFFFF));
  462. ERR_FAIL_COND_V(!sync || sync->get_multiplayer_authority() != p_from, ERR_UNAUTHORIZED);
  463. node = sync->get_node(sync->get_root_path());
  464. } else {
  465. node = rep_state->peer_get_remote(p_from, net_id);
  466. }
  467. if (!node) {
  468. // Not received yet.
  469. ofs += size;
  470. continue;
  471. }
  472. const ObjectID oid = node->get_instance_id();
  473. if (!rep_state->update_last_node_sync(oid, time)) {
  474. // State is too old.
  475. ofs += size;
  476. continue;
  477. }
  478. MultiplayerSynchronizer *sync = rep_state->get_synchronizer(oid);
  479. ERR_FAIL_COND_V(!sync, ERR_BUG);
  480. ERR_FAIL_COND_V(size > uint32_t(p_buffer_len - ofs), ERR_BUG);
  481. const List<NodePath> props = sync->get_replication_config()->get_sync_properties();
  482. Vector<Variant> vars;
  483. vars.resize(props.size());
  484. int consumed;
  485. Error err = MultiplayerAPI::decode_and_decompress_variants(vars, &p_buffer[ofs], size, consumed);
  486. ERR_FAIL_COND_V(err, err);
  487. err = MultiplayerSynchronizer::set_state(props, node, vars);
  488. ERR_FAIL_COND_V(err, err);
  489. ofs += size;
  490. }
  491. return OK;
  492. }